지난번 드론의 정의(https://jwprogramming.tistory.com/282)를 다루었습니다.

 

오늘은 드론의 구성요소와 주요 용어 및 통신방식 등에 대해 간단히 정리해보았습니다.

 

1) 드론 구성요소

출처 : 드론의 구성, http://www.sigmapress.co.kr/shop/shop_image/g47841_1550542236.pdf

드론의 구조는 드론과 지상의 원격조정자가 각종 데이터를 주고받는 통신부, 드론의 비행을 조정하는 제어부, 드론을 날아가게 구동시키는 구동부, 그리고 카메라 등 각종 탑재 장비들로 구성된 페이로드의 네 부분으로 나뉜다고 볼 수 있습니다.

  ※ LTE, WIFI 등 드론 통신방식에 따라 통신부(송신기)에서 제어부(비행제어기)로 위치데이터 등이 이동되고, 제어부의 센서융합기를 통해 자이로센서, 지자기 센서 등 센서값에 대한 측정치를 갖고 있습니다. 이를 비행제어기를 통해 실제 구동부(모터, 프로펠러 등)으로 핀을 통해 데이터를 전달합니다.

[드론 HW 구성]

출처 : 드론의 구성, http://www.sigmapress.co.kr/shop/shop_image/g47841_1550542236.pdf

[드론 서비스 구성]

출처 : KISA, 드론 사이버보안 가이드 https://www.kisa.or.kr/2060205/form?postSeq=9&page=1#fnPostAttachDownload

2) 드론 관련 주요 용어

1. GCS(Ground Control System) : (지상관제 시스템)

  - 자율비행 및 실시간 비행경로 변경 관제 가능

  - 지도 데이터 처리, 비행경로 사전 분석 기능

  - 지오펜스 기능 (필요 시 비행금지 지역 생성)

 

2. FC(flight controller, FC) : 비행제어장치

: 수신기(Rx Module)에서 받은 조종신호를 변속기(ESC: 모터의 속도를 제어해주는 장치)로 보내주는 중간에 안정적인 비행을 위해 신호를 조종해주는 장치

 

3. FCC(Flight Control Computer) : 비행제어장치

: 각종 데이터를 취합하여 위치, 자세 제어

 

4. FCS(Flight Control System) : 비행제어시스템

- FCS는 위치, 자세 제어, 경로비행 제어 등에 필요한 드론 설계 핵심기술

- 핵심 모듈 (AHRS, FC) 자체 설계가능

- 제어기 커스터마이징, 비행 로그 추적 및 분석가능

 

5. AHRS : 관성측정장치 (Attitude and heading reference system)

: 기체의 상태 데이터 (자세,고도, 방향등)계산

 

6. RTH(Return to home) : 자동복귀

 

7. GNSS(Global Navigation Satellite System)

: 우주궤도를 돌고 있는 인공위성에 발신하는 전파를 이용해 지구 전역에서 움직이는 물체의 위치·고도치·속도를 계산하는 위성항법 시스템

 

8. ESC(electronic speed control) : (변속기)

: 전기적으로 속도를 제어하는 소자

- 브러쉬리스 모터를 구동하기 위해 필요한 전자회로

- FC의 명령을 받아서 모터 속도를 제어함

 

9. PWM(Pulse Width Modulation) : 신호 폭 조종

: 일정한 주기 내에서 Duty 비를 변화 시켜서 평균전압을 제어하는 방법

드론 로터의 회전수는 일반적으로 PWM(Pulse Width Modulation) 방식으로 제어되고 회전수의 차이에 따라 상하(Throttle), 전후진(Pitch), 좌우이동(Roll) 및 제자리 회전(Yaw) 동작이 이루어집니다.

 

2-1) 드론 탑재센서

1) 자동비행제어장치

: 자동비행제어장치(Automatic Flight Control System)란 항공기나 미사일의 내부와 외부 장치에 의해 진로나 비행 자세를 자동적으로 조정할 수 있는 모든 장비를 포괄한 장치

비행제어장치(flight controller, FC)

: 수신기(Rx Module)에서 받은 조종신호를 변속기(ESC: 모터의 속도를 제어해주는 장치)로 보내주는 중간에 안정적인 비행을 위해 신호를 조종해주는 장치

(FC의 세부역할)

- 수신기의 신호를 분석할 수 있도록 적당한 채널로 나눔

- 정착된 센서에서 감지된 신호를 분석하여 멀티콥터가 안정적인 자세를 유지하도록 변속기(ESC)에 신호를 보냄

- 수신기로 수신된 신호와 센서에서 수신된 정보, 두 신호를 분석하여 원하는 비행이 가능하도록 변속기(ESC)에 신호를 보냄

 

2) 모터

: 드론에서 사용하는 모터는 일반적으로 브러시(Brushed Direct Current, BDC)모터와 브러시리스 직류(Brushless Direct Current, BLDC) 모터로 나뉨

BDC 모터 BLDC 모터
BDC 모터는 주로 완구용 드론에 사용됨장점 : 가격이 싸고, 구동방식이 간단단점 : 브러시가 닳게 되면 수명이 다하고, 스파크, 열 등이 발생해 모터의 고속회전 및 장시간 회전에는 적합하지 않음 BLDC 모터는 영구 자석으로 된 중심부의 회전자(Rotor)와 권선(Wire)으로 되어 있는 극(Pole)과 고정자(Stator)들로 구성

 

3) 가속도계와 자이로스코프

: 가속도계와 자이로(Gyro) 센서는 드론의 관성 센서이다. 가속도계는 가속도를 측정하고, 자이로는 회전력을 측정

 

4) 자력계

: 자력계(magnetometer)는 나침반 기능을 하는 센서로 자기장을 측정하는 역할

(자력계가 자북을 측정하여 드론의 방향정보를 드론의 비행제어장치(FC)로 보내 이를 보강하는 역할)

자력계 센서는 전선, 모터, 변속기(ESC) 등에서 발생하는 주변 자기장에 매우 민감합니다. GPS 모듈은 일반적으로 이런 장비들과 떨어져 있기 때문에, 장비들에 의한 자기장 간섭을 피하기 위해 나침반 센서를 추가적으로 GPS 모듈에 장착하기도 합니다.

 

5) 관성측정장치

: 관성측정장치(Inertial Measurement Unit, IMU)GPS와 연동되어 기체의 이동방향, 이동경로, 이동속도를 유지하는 역할을 하고, 3축 자력계와 GPS 수신기가 결합된 형태로 얻은 정보를 드론의 비행제어장치(FC)로 전달합니다.

 

6) 기압계

: 기압계는 항공기의 고도를 측정하기 위한 압력 센서대기압은 해수면에서의 높이에 따라 결정되고, 기압계는 이 원리를 이용하여 대기압을 측정하여 고도를 측정

 

일반적으로는 GNSS 센서를 사용하여 고도를 매우 정밀하게 측정 할 수 있지만, GNSS사용할 수 없는 실내에서는 초음파나 이미지 센서 등을 사용하여 정밀하게 고도를 측정합니다.

 

7) 대기속도계

: 대기속도계는 비행 중 드론을 스쳐 지나가는 공기의 흐름속도를 측정하기 위한 것

 

8) 센서 융합

: 센서 융합(sensor fusion)이란 각종 외부 센서에서 오는 정보를 통합 또는 융합함으로써 새로운 정보를 얻는 것

 

9) 초음파 거리 센서

: 초음파 센서는 초음파를 발생하는 송신기 부분과 반사되어 돌아오는 초음파를 검출하는 수신기로 구성

송신기에서 초음파를 발사한 후, 수신기에 반사된 초음파가 들어올 때까지의 시간을 측정하여 센서와 물체까지의 거리를 측정

10) 라이다 센서

: 라이다 센서는 레이저(laser)를 목표물(대상체)에 투사하고 대상체에서 반사되어 되돌아오는 시간을 측정함으로써 대상체까지의 거리, 방향, 속도, 온도, 물질 분포 및 농도 특성 등을 감지, 측정할 수 있는 기술- 자율비행 및 실시간 비행경로 변경 관제 가능

- 지도 데이터 처리, 비행경로 사전 분석 기능

- 지오펜스 기능 (필요 시 비행금지 지역 생성)

 

3) 통신기술

1. 무선통신 송수신기(telemetry)

: 무선통신 송수신기는 데이터를 송수신하기 위한 무선장비로서 드론과 조정기에 각각 탑재·설치해야 합니다.

  ※ 중요한 것은 드론과 조정기의 무선통신 송수신기를 서로 페어링해야 한다는 것

드론과 조정기와의 통신을 위해 기본적으로 2.4GHz 5.0GHz의 와이파이(WiFi)를 사용합니다. 그러나 통신범위가 5~7km를 넘지 못하기 때문에 장거리 이동 시에는 LTE망을 활용합니다.

---------------------------------------------------

국립전파연구원은 20151231항공업무용 무선설비 기술기준을 개정해 드론 이용을 위한 전용 주파수를 할당했다. 이 기술기준에 따르면 드론 전용 주파수로 5,030~5,091MHz(5,030~5,091GHz) 대역(61MHz )이 새롭게 할당되었습니다.

 

-> 드론과 조정기와의 통신은 2.4GHz, 5.0GHz. 혹은 전용주파수로 5.0MHz 근방의 대역을 사용하지만, GPS신호는 1.2GHz(혹은 1.5GHz)에서 사용됩니다.

GPS신호를 수신할 때 다른 신호들과 중첩, 방해 등이 발생할 수 있으며 이때 GPS Spoofing 혹은 Jamming 등이 발생할 수 있지 않을까하는 의문을 가져봅니다.

---------------------------------------------------

2. 주파수 대역(RF)

드론은 지상에서 드론으로 원격조정(RC) 비행명령어 및 카메라 조작 등 페이로드 제어 신호를 전송하기 위한 상향링크(지상 드론)가 필요하고,

비디오, 사진 및 드론의 위치, 비행속도, 배터리 잔량 등의 비행정보를 지상으로 전송하기 위한 하향링크(드론 지상)가 필요합니다.

GPS 신호는 1.2GHz(혹은 1.5GHz) 주파수 대역으로 수신

[요약]

- 상향링크 : 지상에서 드론으로 페이로드 제어신호를 전송

- 하향링크 : 페이로드, 제어부 등에서 발생한 비행정보를 지상으로 전송

1) 900MHz 1.3GHz 주파수 대역

: 900MHz 주파수 대역은 비디오 및 텔레메트리 전송을 위한 하향링크로 사용

- 900MHz 대역은 최근 규격이 확정된 IoT(internet of things)WiFi 11ah 무선랜과도 주파수대역이 겹친다. 1.3GHz 주파수 대역 역시 비디오 전송을 위한 하향링크로 사용되는데, 2005년 이후에 쏘아 올린 GPS 위성의 1.2GHz L2 주파수 대역과 가까워서 드론에 탑재된 GPS 수신기에 간섭을 줄 수 있습니다.

2) 2.4GHz 5.8GHz 주파수 대역

: 2.4GHz 주파수 대역은 거의 모든 드론이 원격조정 및 페이로드 제어로 사용하는 상향링크입니다.

그러나 2.4GHzWiFi, 블루투스, 지그비 등과 주파수대역이 겹치므로 사람이 많이 모이는 공원 등의 지역에서는 드론 비행에 주의해야 합니다. 일부 드론들은 2.4GHz 대역을 비디오 전송 하향링크로 사용합니다. 이 경우, 원격조정 상향링크는 5.8GHz 주파수 대역을 이용합니다. 5.8GHz 주파수 대역은 최근 출시된 드론들이 비디오 및 텔레메트리 전송 하향링크로 사용하는 주파수 대역입니다.

3) WiFi 4G/3G

: 드론에 WiFi 수신기를 설치해 스마트폰 WiFi로 직접 드론을 원격조정할 수 있습니다. 드론에 LTE 혹은 WCDMA 송수신기를 설치해 이동통신 네트워크를 통해 스마트폰으로 드론을 원격조정하거나 드론의 비디오 데이터를 지상으로 전송하기도 합니다.

3. GNSS

1. GPS GNSS(Global Navigation Satellite System : 위성항법시스템)

: GPS는 인공위성으로부터 수신기까지 신호가 도달하는 데 걸린 시간(소요시간)을 기준으로 거리를 측정합니다.

GNSS는 크게 1) 위성, 2) 지상의 제어국, 3) 사용자로 구성되어 있습니다. 지상 제어국의 수신장치에서 고도 약 20,000km 중궤도에 위치해 있는 인공위성에서 신호를 받아 수 m 이내의 위치정보를 알아낼 수 있는 것이 GNSS의 기본 원리입니다.

 

'ETC > Drone' 카테고리의 다른 글

1. 드론(Drone)의 정의. 드론이란 무엇인가?  (0) 2022.04.13

WRITTEN BY
SiriusJ

,

요즘 러시아-우크라이나 전쟁으로 인해, 드론의 활용성과 중요성이 많이 각광받고 있습니다.

따라서, 드론이란 무엇인지 우리나라에서 법적으로 정의하고 있는 부분에 대하여 먼저 정의하고자 합니다.

 

o 드론이란? : 조종자가 탑승하지 아니한 상태로 항행할 수 있는 무인비행체 라고 정의할 수 있습니다.

  - 아래는 우리나라에서 드론에 대해 법으로 정의한 부분을 참조하였습니다.

1. 드론의 정의(드론 활용의 촉진 및 기반조성에 관한 법률, 약칭: 드론법)

1) 드론이란 조종자가 탑승하지 아니한 상태로 항행할 수 있는 비행체로서 국토교통부령으로 정하는 기준을 충족하는 다음 각 목의 어느 하나에 해당하는 기기를 말한다.

. 항공안전법2조제3호에 따른 무인비행장치

. 항공안전법2조제6호에 따른 무인항공기

. 그 밖에 원격자동자율 등 국토교통부령으로 정하는 방식에 따라 항행하는 비행체

-> 우리나라에서는 위의 드론법에서 보시는 바와 같이, 드론에 대한 정의를 하고있습니다. 여기서 핵심은 조종자가 탑승하지 않은 무인비행체 라는 부분입니다.

 

그럼 무인비행장치와 무인항공기는 무엇인가? -> 항공안전법에서 정의되어 있음

항공안전법 제2조에 따른 무인비행장치로 분류되며, 동법 시행규칙(항공안전법 시행규칙)에 따라 무인비행장치에서 무인동력장치, 무인비행선으로 분류된다고 볼 수 있습니다.

----------------------------------------------------------------------------------

[항공안전법 제2(정의)]

3. 초경량비행장치란 항공기와 경량항공기 외에 공기의 반작용으로 뜰 수 있는 장치로서 자체중량, 좌석 수 등 국토교통부령으로 정하는 기준에 해당하는 동력비행장치, 행글라이더, 패러글라이더, 기구류 및 무인비행장치 등을 말한다.

----------------------------------------------------------------------------------

[항공안전법 시행규칙]

5(초경량비행장치의 기준) 법 제2조제3호에서 자체중량, 좌석 수 등 국토교통부령으로 정하는 기준에 해당하는 동력비행장치, 행글라이더, 패러글라이더, 기구류 및 무인비행장치 이란 다음 각 호의 기준을 충족하는 동력비행장치, 행글라이더, 패러글라이더, 기구류, 무인비행장치, 회전익비행장치, 동력패러글라이더 및 낙하산류 등을 말한다.

5. 무인비행장치: 사람이 탑승하지 아니하는 것으로서 다음 각 목의 비행장치

. 무인동력비행장치: 연료의 중량을 제외한 자체중량이 150킬로그램 이하인 무인비행기, 무인헬리콥터 또는 무인멀티콥터*

. 무인비행선: 연료의 중량을 제외한 자체중량이 180킬로그램 이하이고 길이가 20미터 이하인 무인비행선

 

-> 여기서 드론은 일반항공기처럼 날개가 고정되어있는 고정익과, 로터를 갖고있는 회전익 으로 분류되며, 멀티콥터 (Multi Copter)란 여러 개의 로터(Rotor)를 가진 비행체로, 로터의 수에 따라 아래처럼 불리게 됩니다.

(2 : 바이콥터(bi copter), 3 : 트라이콥터(tri copter), 4 : 쿼드콥터(quad copter))

 

다음 포스팅에서는 드론에서 사용하는 주요 모듈 및 센서, 관련 통신방식 등 용어들에 대해 정리하고자 합니다.

'ETC > Drone' 카테고리의 다른 글

2. 드론의 구성, 주요 용어 및 통신기술  (0) 2022.04.28

WRITTEN BY
SiriusJ

,

1) 외부에서 본 프로그램의 동작은 변하지 않고, 

2) 프로그램 내부의 구조를 개선하는 것


따라서 debugging 이나 기능 추가와 같은 것은 리팩토링이라고 할 수 없다. 프로그램의 동작이 변하기 때문이다. 

그렇다면 Refactoring 의 목적은 무엇일까? 말했듯이, 디버깅 자체가 Refactoring 은 아니다. 하지만 리팩토링을 통해서 디버깅이 쉬워질 가능성이 있다. 복잡하고 어지러운 코드에서는 버그를 찾기 쉽지 않기 때문이다. 

기능 추가와 관련하여 다음 그림을 참고한다면 리팩토링의 장점을 알 수 있다. 


출처: http://www.hanbit.co.kr/preview/1511/sample_chapter0.pdf

당장은, 자기 생각대로 빨리 아무렇게나 코딩하는 것이 빠르다고 생각할지 모르겠지만, 처음부터 리팩토링을 생각하며 
코딩하는 것이 결국 전체적인 속도로 보았을 때에, 비교할 수 없을 정도의 차이를 낼 것으로 보인다. 리팩토링 없이 어지럽게 코딩을 마친 후 버그를 잡다가, 결국 전체적인 프로그래밍 설계를 모두 수정해야하는 사태까지 나올 수 있지 않을까 생각한다. 그런데 리팩토링을 하며, 보기 쉽고, 깔끔하게 정리하며 코딩을 하다 보면, 중간에 전체적인 설계가 잘못되어서 코드를 뒤집어야 한다고 하는 최악의 사태가 온다 하더라도, 빨리 판단하고 실행에 옮기게 되어 결국 전체적인 프로젝트 기간을 단축 시킬 수 있을 것 같다. 

다음은 언제 리팩토링을 해야하는가에 대한 펌 자료이니 참고하자. 
출처: http://outliers.tistory.com/entry/%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81Refactoring

언제 리팩토링을 해야 하는가?

  • 별도의 시간을 내는것이 아니라, 틈틈히 계속 해야 하는 것이다.
  • 어떤 것을 할 때 비슷한 어떤것을 하게 되면 리팩토링을 한다.(책에서는 3번째 부터 하라고 나와있지만 바로 한다.)
  • 기능을 추가할 때 리팩토링을 해라.
  • 버그를 수정해야 할 때 리팩토링을 하라.
  • 코드 검토(code review)를 할 때 리팩토링을 하라.
    • 읽기 어려운 프로그램은 수정하기 어렵다.
    • 중복된 로직을 가지고 있는 프로그램 수정하기 어렵다.
    • 실행중인 코드를 변경해야 하는 특별한 동작을 요구하는 프로그램은 수정하기 어렵다.
    • 복잡한 조건문이 포함된 프로그램은 수정하기 어렵다.

그러나 리팩토링을 지양해야할 때도 있다. 

언제 리팩토링을 하지 말아야 하는가?

  • 코드를 처음부터 다시 작성해야 할때
  • 마감일에 가까울 때


그렇다면 리팩토링과 디자인패턴 (design pattern) 과는 어떤 관계가 있을까? 

디자인패턴은 목표이고 리팩토링은 방법이라고들 말을 한다. 

다음은 디자인 패턴이 무엇인지 잘 정리되어있는 펌자료이다. 
출처: http://alleysark.tistory.com/entry/Design-pattern-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EC%9D%B4%EB%9E%80

- 디자인 패턴이란?

클래스 구조를 갖는 프로그래밍을 하다보면 클래스간에 구조가 짜여지고 다양한 방법으로 객체가 생성되며 관계에 따라 여러가지 형태의 행동들이 나타난다. 그런데 기초 설계가 제대로 되어있지 않은 상태로 프로그래밍이 시작된다면 얼마 못가 클래스 관계가 꼬일대로 꼬여 누더기 진흙탕 코드덩어리로 변하게된다. 엄청나게 뛰어난 사람이어서 초기 요구에 맞춰 잘 짜여진 클래스관계를 만든다 해도 요구 사항이 바뀌게되면 쉽게 대응하지 못한다. 이미 갈 때 까지 간 코드를 뒤엎는건 그만큼 큰 비용을 감수해야하는 행동이다.

 

그런데 Object oriented programming은 이게 아니지 않은가? 분명 클래스 구조의 프로그래밍을 했는데도 프로젝트가 진행되다보면 데이터의 은닉과 캡슐화, 코드의 재사용성과 확장성 등은 누더기 코드에 가려 보이지 않는다. 제대로된 OOP를 하지 못했다는 이야기이다. 그렇다면 제대로된 OOP란 무엇을 말하는것인지 의문이 생긴다. 많은 사람들이 이에대해 고민했고 프로그램의 목적이 어떻든간에 프로그램안에 클래스들이 갖는 구조에는 일정한 '형태' 혹은 '패턴' 이 존재한다는 것을 인지하기 시작했다. 이를 바탕으로 클래스간의 관계, 클래스간의 행동양식을 분류하고 각각에 대해 객체지향적인 설계를 따르는 노하우들이 차곡차곡 정리되어 객체지향적으로 합당한 클래스 설계 형태를 정립하기 시작했고 이를 클래스 디자인 패턴 이라 이름붙이게 되었다.

 

클래스 디자인 패턴은 "'이러한 상황' 이라면 '이러한 형태의 클래스 디자인'을 하는게 대게 좋더라" 라고 말해주는것이다. 프로젝트 규모가 커지고 협업 인원이 많아질수록 이러한 기준은 일을 효율적으로 처리할 수 있게 만들어준다. 하지만 주의해야한다. 표준화된 작업은 여러가지 상황을 고려하며 만들어지기 때문에 대체로 효율성이 떨어지기 마련이다. 또한 패턴간의 관계를 생각하지 못하면 설계를 복잡하게 만드는 요소가 되어버린다. 그렇기 때문에 클래스 설계자는 분류된 디자인 패턴의 사용 목적, 장단점, 강점과 약점에 대한 충분한 이해와 패턴간의 융합에 발생할 수 있는 문제점들을 확실히 예상할 수 있어야 하며 이를 바탕으로 디자인 패턴을 적용해야한다. 무분별한 패턴의 남용은 오히려 프로그램을 망치게된다.


디자인 패턴이 리팩토링을 위한 방법이라고 말했듯이, 디자인 패턴들이 분명 유용하긴 하나, 디자인패턴이 너무 강조될 경우, 오히려 더 코드가 지저분해질 염려도 된다고 퍼온 자료의 저자는 말한다. 결국, 목적이 더 좋은 설계가 되어야지, 디자인 패턴 자체가 되어서는 안된다는 뜻으로 받아드리려고 한다. 


다음과 같은 펌자료 저자의 의견도 함께 첨부한다. 


만약 무분별 하게 디자인 패턴이 사용되고 패턴들이(클래스들이) 유기적으로 결합되지 못한다면 클래스 설계에 있어서 디자인 패턴은 필요악 되어버린다. 설계자는 패턴에 목메기보다는 설계원칙을 잘 생각하면서 이를 받쳐줄 검증된 방법론으로서 디자인 패턴을 고려하여야 할 것이다.

 

또 한가지는 프로그램의 구동 환경에 있다. PC 어플리케이션이라면 디자인패턴이 가져오는 퍼포먼스에 대한 결점은 큰 문제가 되지 않을 것이다. 하지만 안드로이드 같은 모바일 환경이나 임베디드 환경이라면 디자인패턴은 사치품에 지나지 않는다.

 

마지막으로 프로그램의 구동 목적이 고려되어야 한다. 구동에 큰 설계가 필요하지 않거나 명확한 클래스구조를 갖고 코드의 변경을 고려하지 않아도 된다면 디자인패턴은 쓸데없는 비용을 늘리는 요소가 된다. 그리고 게임프로그램, 서버프로그램과 같은 고성능의 실행환경을 요구하는 프로그램이라면 퍼포먼스를 낮추는 디자인패턴은 필요성에 대해 신중에 신중을 기할 필요가 있다.



[전체 출처 : http://egloos.zum.com/johnny1984/v/9072065 ]


WRITTEN BY
SiriusJ

,

Raspberry Pi를 이용하여 개발을 할 때, 파이 내의 리눅스 시스템에서 코드를 작성하는 것은 상당히 불편함이 있습니다.

따라서, 윈도우에서 툴을 이용해 개발을 한 후, 간편하게 소스만 라즈베리파이로 옮겨서 실행하면 편할 것입니다.

따라서 개발자들이 주로 사용하는 툴인 Eclipse와 Raspberry Pi 간에 파일시스템을 통해 연동하는 부분을 하도록 하겠습니다.


1. 먼저, 아래의 그림처럼 Eclipse 내에서 프로젝트와, 여러 파일들을 만들었다고 가정해보겠습니다. 이제 왼쪽 weatherPro 라는 임의의 프로젝트를 우클릭하여 'export' 라는 메뉴를 클릭합니다.


2. Export를 클릭하면 다음과 같이 볼 수 있는데, Remote Systems 를 클릭 후, Remote File System을 선택한 후 next를 눌러줍니다. 간단히 설명하면 현 프로젝트를 file system으로 내보내겠다는 뜻입니다.


3. 위에서 next를 눌렀을 때, 다음과 같이 보일 것입니다. 

이 때, 중앙에 있는 Destination folder, quealified by its remote connection name :  [Browse...] 에서, Browse를 클릭하여 목적지 폴더를 설정해주고, Connection 할 이름을 정해줍니다.


4. Browse를 클릭하면 다음과 같이 보이는데, 현재 Connection이 Local로 되어있습니다. 우측의 New... 를 클릭합니다.


5. Host name은 LOCAL로 되어있을 것입니다. 이 부분에는 자신의 라즈베리파이의 IP주소를 입력해줍니다.

ex) 192.168.xxx.xxx ( 저는 무선 공유기를 사용하였습니다. xxx를 그대로 따라 치는분은 없으시리라 믿습니다.)

그리고 Connection name은 말그대로 Connection할 이름입니다. 저는 집에서 Wifi를 이용하는 라즈베리 파이이므로

homePi(wifi) 입니다. 이 부분은 각자 인식할 수 있는 이름으로만 지어주시면 됩니다.


6. next를 누르다보면 다음과 같은 창이 뜰것입니다. 그대로 next를 누릅니다.


7. Connection에서 homePi(wifi)가 생긴것을 볼 수 있습니다. Local에서 homePi(wifi)로 바꿔줍니다.

다음으로 연결된 PI의 어떤 폴더에 지금 이클립스의 프로젝트를 연동할 것인지 설정해주는 부분입니다.


8. Root를 클릭하면 다음과 같이 PI의 ID와 password를 입력하는 부분이 나옵니다.

 이 부분은 각자의 PI에 맞는 ID와 Password를 입력해 준 후, OK버튼을 클릭합니다.


9. 처음이라 인증을 하는 부분입니다. Connecting하기 위해 YES를 클릭해줍니다.


10. 현재 존재하지 않으므로 생성해주겠냐는 경고창입니다. Yes를 눌러서 생성해줍니다.


11. 위와 같습니다. Yes를 눌러줍니다.


12. 이제 Root에 접근할 수 있습니다. 먼저 / 루트 디렉토리를 클릭한 후, home 디렉토리의 하위 디렉토리(pi)로 이동하면 제가 이미 기존에 만들어준 이런저런 폴더가 있습니다.

pi를 클릭 한 후, OK를 눌러주면 pi 디렉토리 안에 해당 Eclipse의 프로젝트를 연동해줄 수 있습니다.


13. 다음으로 하단에 있는 Browse.. 를 클릭해준 후, 제가 연동해줄 Eclipse의 프로젝트는 weatherPro 라는 프로젝트이고,  '.rexpfd'파일을 만들면 됩니다. 저는 이름은 export로 하였는데 이 또한 각자 임의로 이름은 설정해주면 됩니다.


14. 이렇게 설정들을 전부 마쳐주면 다음과 같이 뜰 것입니다.

참, 이때 Options가 있는데 저는 첫번째 Review/Synchronize 를 선택하였습니다.

이는 Eclipse내에서 작업을 하고 저장을 하면 바로 pi로 이동하는 것이 아니라 Eclipse내에서 한번 더 'PUT'을 통해 라즈베리로 옮겨주는 작업을 해주겠다는 것입니다. 즉 사용자에게 한번 더 체크하도록 하는 부분입니다.

나는 굳이 체크하는 과정이 귀찮다 하시면 아래의 Overwrite existing files without warning 을 선택하시면 됩니다.

중간 과정 없이 바로 PI의 기존 파일에 Overwriting하겠다라는 뜻입니다.


15. Finish를 눌러주면 다음과 같은 화면이 나옵니다. 귀찮으므로 Remember my decision을 클릭해준 후 Yes를 눌러 다음엔 묻지 않도록 합니다. 

(저는 깜빡하고 선택을 안하고 Yes를 했더니, 다음번에 또 물어봐서 Remember ... 를 선택해주었습니다.)


16. 이렇게 다 마쳐주면, 다음과 같이 Eclipse와 Raspberry Pi 간에 Synchronizing 작업을 시작합니다.


17. 이제, 프로젝트로 돌아와서 파일을 확인하면 export.rexpfd가 생성된 것을 확인할 수 있습니다.

우클릭 한 후, Export to Remote File System을 클릭하여 원격 파일시스템을 이용하여 프로젝트를 Export하겠다 해주면 됩니다.


18. 다음과 같이 아래에 여러 폴더와 파일이 보입니다. (위에서 Review/Synchronize)를 선택하지 않고 Overwriting을 선택했다면 폴더들이 보이는 것 없이 바로바로 Overwriting 될 것입니다.


19. 아래에서 하나의 파일/폴더만 우클릭하여 PUT 을 통해 선택적으로 라즈베리파이에 옮겨줄 수도 있습니다. 전체를 해주고 싶다면 가장 위쪽의 프로젝트를 PUT하게 되면 프로젝트 하위의 모든 파일들이 옮겨지게 됩니다.


20. PI에서 확인해보겠습니다. 먼저 아직은 'PUT'하기 전이라 weatherPro 라는 프로젝트가 옮겨지기 전이므로 생성되지 않은 것을 확인할 수 있습니다.


21. 프로젝트를 이클립스에서 'PUT'하고 나면, pi내에서 가장 우측 3번째줄에 파랗게 weatherPro 폴더가 생긴 것을 확인할 수 있습니다.


이와 같이 Eclipse내에서 프로젝트를 Remote File System을 이용하여 Raspberry Pi와 연동해줄 수 있습니다.

이를 이용하면 불편하게 라즈베리파이에서 소스작업을 하는 것보다, 편리하게 Eclipse툴을 이용하여 소스작업을 끝낸 후 파일만 이동시켜주어 라즈베리파이 내에서는 실행만 시켜줄 수 있습니다.

처음 프로젝트를 PUT하게 되면 차후에는 소스 작업 시에 수정만하고 저장을 (꼭!) 눌러주면 eclipse 아래 Synchronize메뉴에서 수정된 파일만 뜹니다. 그 파일만 PUT해줌으로써 편리하게 차후 수정작업을 할 수 있습니다.


+추가적으로 프로젝트를 연동 후, 라즈베리파이에서 소스를 수정하면 'GET'을 통해 얻어올 수도 있지만, Sync때문에 조금 귀찮아질수도 있습니다. 웬만하면 파이에서는 소스를 수정하거나 건드리지 말고, 이클립스 툴을 이용해서 수정작업을 한 후, PUT을 통해 넣어주는게 편리합니다.

혹시라도 실수로 라즈베리에서 수정하여 Sync가 안맞거나 하여 문제가 생기면 댓글로 알려주시면 답변드리겠습니다.


WRITTEN BY
SiriusJ

,

16진수의 무작위 숫자에 대하여 1이 몇개인지 숫자를 carry하도록 하는 Assembly 코드입니다.


[Assembly code]

main NOP

       MOV r4, #32 //r432(0x20)의 값을 저장합니다.

       LDR r1, RANNUM //r1RANNUM의 값을 LOAD합니다.

       MOV r0, r4 //r4의 값을 r0에 저장하여 r0에는 32의값이 들어갑니다.

       MOV r3, #0 //r30의 값으로 초기화합니다.

LOOP MOV r2, r1, LSR #31 

/* r1의 값(0x04882C2A)31bit만큼 LSR연산하여 r2에 그 값을 저장 합니다. 위 연산을 거치게되면 r20또는 1의 값이 저장됩니다. */

       CMP r2, #1 //r2의 값과 1을 비교하여, 만약 같다면 아래 ADDEQ로 분기하여 r3 1을 더하여 줍니다.

       IT EQ

       ADDEQ r3, r3, #1

       MOV r1, r1, LSL #1 //이제, r1LSL 1bit만큼 shift하여 저장합니다.

       SUBS r0, r0, #1 //r0에서 1의값을 뺍니다.

       BNE LOOP

EXIT B EXIT

       DATA

RANNUM DCD 0x04882C2A

       END



다음은 IAR Embedded Workbench 툴에서 Assembly 코드로 직접 돌려본 후 분석하는 부분입니다.

보드를 선택하는 부분에서 ARM 계열의 Cortex-m3라는 보드를 선택하였습니다.


1. 초기화면입니다.


 

2. r1DATA RANNUMLOAD된 모습입니다.


3. r1을 왼쪽으로 shift 1bit만큼 해준 화면입니다.


 

4. r0의 값(32)에서 1만큼빼주어 31이 된 화면입니다.

 

5. r1의 값을 31bit만큼 오른쪽으로 shift해준 값을 r2에 저장합니다.


6. 만약, r2의 값이 1이라면, r3의 값에 1을 더해줍니다.


  7. 그리고 r1의 값을 다시 1bit만큼 왼쪽으로 shift해줍니다.


8. 이렇게 r0에 저장된 32번만큼 LOOP를 돌아서 r0의 값이 0이되면, exit됩니다.


WRITTEN BY
SiriusJ

,

다음은 16진수의 무작위 숫자에 대하여 짝수인지, 홀수인지를 파악하는 Assembly code입니다.


main NOP

       NUM EQU 10

       LDR r1, =RANNUM //r1RANNUM의 주소를 Load합니다.

       MOV r6, #NUM //r6은 총 10개의 숫자들의 개수를 가리킵니다.

       LDRB r5, [r1] //r5r1의 값을 저장합니다.

       MOV r2, #0 //r2는 홀수를 세는 count, 0으로 초기화합니다.

       MOV r3, #0 //r3는 짝수를 세는 count, 0으로 초기화합니다.

       LDRB r5, [r1], #1 //r5가 다음 r1을 가리키도록 합니다.

LOOP MOV r0, r5, LSL #31 

/* r5의 값을 31bit만큼 shift left하여 맨 뒤의 bit값만 저장합니다. 홀수라면 0x10000000이될것이고, 짝수라면 0x00000000일것입니다. */

       MOV r7, r0, LSR #31 

//다시 r7의 값을 31bit만큼 right shift시키면, 0x00000001(홀수), 0x00000000(짝수) 가 됩니다.

       CMP r7, #1 //이제, r7을 비교합니다.

       ITE EQ

       ADDEQ r2, r2, #1 //만약 같다면, 홀수의 카운트를 늘려주고, 다르다면 짝수의 카운트를 늘려줍니다.

       ADDNE r3, r3, #1

       LDRB r5, [r1], #1 //r5가 다음 r1값을 가리키도록 설정합니다.

       SUBS r6, r6, #1 //한번 수행할때마다 Num의 값을 1씩 줄여줍니다.

       BNE LOOP

EXIT B EXIT

       DATA

RANNUM DCB 0x10, 0x3, 0x23, 0x20, 0x43, 0x7, 0x21, 0x56, 0x67, 0x36

//임의의 무작위 수들 10가지 (0x10, 0x3, 0x23, 0x20, 0x43, 0x7, 0x21, 0x56, 0x67, 0x36)

       END 



다음은 IAR Embedded Workbench 툴에서 Assembly 코드로 직접 돌려본 후 분석하는 부분입니다.

보드를 선택하는 부분에서 ARM 계열의 Cortex-m3라는 보드를 선택하였습니다.


1. 초기화면입니다.


 2. R1에는 RANNUM의 주소값이, R6에는 총 NUM갯수인 10의 값(A), R2,R3는 각각 0으로 초기화된 화면입니다.


 3. 처음 R531bit만큼 shift해주어 r0에 저장하고, 다시 31bit만큼 shift해주면 0x00000000이 됩니다. 0x10은 짝수이기 때문에 0x00000000으로 되어, 0의 값이 R7에 저장됩니다. 다음으로 CMP를 이용하여 r71을 비교합니다.


 4. 0x10은 짝수이므로, R31을 더하여줍니다.


 5. 한번 시행되었을 때마다, R6에서 1씩 횟수(count)를 줄여줍니다.


6. 홀수일때의 모습입니다. R0에는 shift left된 모습이 저장되어있고, R2count되어 1더하여진 모습을 확인할 수 있습니다.


 7. 종료되었을 때의 화면으로, 총 홀수가 6, 짝수가 4개 있음을 확인할 수 있습니다.


WRITTEN BY
SiriusJ

,

다음은 4x4행렬의 곱셈을 Assembly 로 구현한 부분입니다.


[Assembly Code]

main NOP

       MOVS r9, #4 //r9count 하기위해 4를 저장합니다.

       MOV r10, #0x80

//r100x80번지 memorystore하기위해 해당번지(0x80)로 설정해둡니다.

 

//r1ARRAY1, r2ARRAY2의 주소를 가리키고, r3, r4에 각각 1, 2의 값이 저장되게 합니다.

       LDR r1, =ARRAY1

       LDR r2, =ARRAY2

       LDRB r3, [r1], #1

       LDRB r4, [r2], #1

LOOP1 CMP r9, #1

       MOVS r0, #4 //r0LOOP2에서 각 4번씩 count하기위해 4를 저장합니다.

       BL LOOP2

       LDR r2, =ARRAY2 //r2LOOP2를 돌면, 값이 변하므로, 다시 ARRAY2를 가리키게합니다.

       LDRB r4, [r2], #1

       LDRB r3, [r1], #1 //r1의 값을 ARRAY10x1에서 0x2load합니다.

       SUBS r9, r9, #1 //r9count값을 1 빼줍니다.

       BNE LOOP1

EXIT B EXIT

LOOP2 CMP r0, #1 //r0LOOP24번 수행하도록 비교합니다.

       MOVS r5, #0 //r5,r6은 아래 STMIA를 거치면 값이변하므로, 초기화합니다.

       MOVS r6, #0

       SMLAL r5, r6, r3, r4 //r3,r4의 값을 곱한후, r5,r6에 더하여줍니다.

       STMIA r10!, {r5,r6} //r5,r6의 값을 memory r10번지(0x80)store시킵니다.

       LDRB r4, [r2], #1 //r2의 값을 바꿔가며, r3r4를 곱해줍니다.

       SUBS r0, r0, #1 //r0의 카운트를 1 줄여줍니다.

       BNE LOOP2

       MOV pc, r14

       DATA

ARRAY1 DCB 0x1, 0x2, 0x3, 0x4

ARRAY2 DCB 0x2, 0x3, 0x4, 0x5

       END



다음은 IAR Embedded Workbench 툴에서 Assembly 코드로 직접 돌려본 후 분석하는 부분입니다.

보드를 선택하는 부분에서 ARM 계열의 Cortex-m3라는 보드를 선택하였습니다.


1. 처음 돌렸을때의 화면입니다. 아래 memory영역을 보면 ARRAY1, ARRAY2의 값이 memory 해당주소에 저장되있음을 확인할 수 있습니다.


 

2. 오른쪽 register창 에서, R1,R2의 값을 주소를 저장하고, R3,R4에는 각각 ARRAY1, ARRAY2의 값이 들어감을 확인할 수 있습니다또한 r9에는 count하기위한 값 ‘4’, r10에는 0x80번지가 저장됩니다.


3. LOOP2 내 에서 한번 수행했을 때입니다. r01줄었고, R31이고, R42를 수행하고 난 뒤인 3의 값을 가진 모습입니다. R5에는 R3(1) X R4(2)일때의 값인 2를 저장하고 있습니다. R108만큼 증가한 값을 가집니다.


4. LOOP1를 두 번째 돌기 직전의 화면으로, R0은 다시 4로 초기화되어있고R3의 값은 1일 때 R4(2,3,4,5)4번 곱한 후, 증가한 2의 값이 되어있습니다R9LOOP11번 돌았으므로 1만큼 감소한 3을 나타냅니다.


5. 아래 메모리를 확인하면, 0x80번지 메모리부터 차례로 R3XR4를 한 값들이 저장되어있음을 확인할 수 있습니다. LOOP13번 수행했을 때입니다.

1x2=2, 1x3=3, 1x4=4, 1x5=5 // 2x2=4, 2x3=6, 2x4=8, 2x5=A // 3x2=6, 3x3=9, 3x4=C, 3x5=F


 

6. 종료되었을때의 화면입니다. R0=0, R9=0으로 전부 카운트되었음을 확인할 수 있고아래 메모리에서도 값들이 전부 저장되었음을 확인할 수 있습니다.


WRITTEN BY
SiriusJ

,

먼저, 포스팅에서 진행 되는 IAR Embedded Workbench버전이 예전 버전이라 지금 버전과 많이 달라진 것 같습니다.

다만 분석하는 부분은 같을 거라는 예상에서 올려봅니다.

먼저 아래의 C코드를 수행하고 Line-by-Line으로 RegisterDisassembly 창의 결과를 분석하는 부분을 살펴보겠습니다.

int main() {

  int a = 2;

  int b = 4;

  a = xfunc(a, b);

  b = yfunc(a, b);


  return 0;

}

int xfunc(int a, int b) {

  return a*b;

}

int yfunc(int a, int b) {

  return xfunc(a, b);

} 


1. 먼저, Register창에서는 PC(Program counter)는 다음에 실행할 address를 임시로 저장합니. 지금은 main함수를 실행하기 위해 0x40을 가리키고 있고 Disassembly창에서 초록으로 표시된 부분은 다음에 수행할 부분을 표시한 상태입니. ( 현재 수행된 상태가 아니라는 것에 주의합니다. )

다음으로 수행할 부분은 PUSH {R4, LR}으로, Link Register(LR)R4레지스터를 stack에 저장하라는 명령입니. 현재 보이는 화면에서 Step Over 하게되면 Disassembly창에서는 address0x40인 부분을 실행하기 때문에 PC(program counter)는 다음에 실행할 0x42를 가르키게 됩니. 그리고 SP(stack pointer)0x08만큼 감소하여 2번과 같은 그림이 나오게 됩니다.


2. Disassembly의 창에서 ‘MOVS R0, #2’ -> ‘2’의 값을 레지스터 R0에 저장을 다음에 Step Over하게 되면 수행하게됩니다. Register창의 PC는 다음에 수행할 address주소인 0x42를 가르키게 됩니다.


3. 오른쪽 Register창에 보다시피 R02가 저장되었고, PC는 다음에 실행할 0x44를 가리키게 됩니다.

Disassembly창에서는 ‘MOVS R4, #4’ 에 따라서 다음번에 레지스터 R4‘4’의 값을 저장하게 됩니다.


4. Register창에서는 레지스터 R44의 값이 저장되었고, PC0x46을 가리킵니.

Disassembly창에서는 다음번에 ‘MOVS R1, R4’에 따라서 레지스터 R4의 값을 레지스터 R1에 저장하게 됩니.


5. Register창에서 보다시피 레지스터 R4의 값이 레지스터 R1로 저장되었습니다. PC0x48 을 가리킵니다.

Disassembly창에서 보면 다음에 수행할 ‘BL xfunc’ 는 계산된 위치의 서브루틴을 호출하게 되는데,

, xfuncbranch(분기)하고, 수행 시 Link Register에 다음번에 수행할 PC(0x48)+4의 값을 대입하게 됩니다.

다음으로 Step into를 클릭하여 xfunc함수 내로 이동합니다.


6. Register창을 보면, PC0x58을 가리키고, LR 레지스터에 PC(0x48)+4의 값을 대입한 값(0x4D)이 나오게 됩니. (계산대로라면 PC(0x48)+4를 하면 0x4C가 되어야하지만, little-endian big-endian 관계에 의하여 0x4D LR 레지스터에 저장됨)

Disassembly창에서 ‘MULS R0, R1, R0’ 은 레지스터 R1에 저장된 값과 레지스터 R0에 저장된 값을 곱한 후 R0에 저장하라는 명령입니. 다음으로 Step Into를 클릭하여 이동합니.


7. Register창에서 PC는 다음 address주소인 0x5A를 가리킵니다.

Disassembly창에서 ‘BX LR’ return; 의 의미이며, xfunc을 빠져나와 LR에 저장된 주소(0x4D)로 이동합니다.


 

 8. Register창은 위에서 LR 번지로 이동하였으므로 PC0x4C를 가리킵니다.

Disassembly창에서는 다음에 레지스터 R4의 값을 레지스터 R1의 값에 저장하게 합니다.

9. Register: PC에서 다음 번지 주소인 0x4E를 가리킵니다.

Disassembly: ‘BL yfunc’ yfuncbranch(분기)하고 LR 레지스터에 PC(0x4E)+4의 값을 저장하게 됩니다.

Step into를 클릭하여 yfunc로 이동하게 됩니다.


10. Register: Disassembly창의 address에 따라 0x5C를 가리키고, Link RegisterPC(0x4E)+4의 값을 저장하여 ‘0x53’이 되었고, 0x52가 아닌지는 위에서(Little-endian, Big-endian) 설명하였습니다.

Disassembly: ‘PUSH {R7, LR}’ ->Link Register 와 레지스터 R7stack에 담게 됩니다.


11. Register: SP0x08만큼 줄었고, PC는 다음 번지주소 0x5e를 가리킵니.

Disassembly: 다음번에 ‘BL xfunc’ 에 의해 xfunc으로 branch(분기)하게 됩니.


12. Register: LRPC(0x5E)+4인 값으로 0x63이 나오게 되며, PCxfunc의 다음번지 주소인 0x58을 가리킵니다.

  Disassembly: ‘MULS R0, R1, R0’ => R0R1의 값을 곱하여 R0에 저장합니다.

 

 

13. Register: R00x20이 대입되었는데 그 이유로는, R0(8) X R1(4) = 32 인데, 16진수형태이므로 0x20으로 나타내어지게 됩니. PC는 물론 다음 주소인 0x5A를 나타냅니다.

Disassembly: ‘BX LR’ -> return의 의미. LR이 가리키는 address로 이동하게 됩니다.


14.  Register: PC가 다음번지주소 0x62를 가리킵니다.

Disassembly: 다음번에 R1PC의 값을 꺼내게 됩니다. 


15. Register: R1의 값은 pop으로 꺼내졌으므로 0이 되고, SP0x08만큼 다시 증가하게 됩니다.

PCyfunc을 빠져나와, 다음번지 0x52를 가리킵니.

Disassembly: MOVS R4, R0 -> R0의 값을 R4에 저장합니.


16. Register: R420으로 저장되어졌고, PC는 다음번지 0x54를 가리킵니다.

Disassembly: R0 레지스터에 ‘0’의 값을 저장합니다.


17. Register: R00이 저장되었고, PC는 다음번지 0x56을 가리킵니.

Disassembly: PC와 결과값 레지스터 R4(0x20)의 값을 pop으로 꺼내게 됩니.

18. Register: R4의 값은 꺼내졌으므로 0이 되고, SP는 또한 0x08만큼 증가하여 원래의 값이 되고PC0x76을 가리키게 됩니다.

Disassembly: ‘BL exit’ ->exit로 분기하고, PC의 값에 +4를 더한값을 LR에 저장합니. 프로그램이 exit로 분기하며 끝났다고 볼 수 있습니다.



WRITTEN BY
SiriusJ

,