금요일, 2월 06, 2015

STM32CubeMX와 Eclipse CDT/GNU 툴을 사용한 예제:LED 켜기 (2편 컴파일 과 빌드)

STM32CubeMX와 Eclipse CDT/GNU 툴을 사용한 예제:
LED 켜기 (2편 컴파일 과 빌드)

3. Eclipse 에서 컴파일
    3-1. 시작 (워크 스페이스)
    3-2. 프로젝트 생성/GNU 툴 체인 선택
    3-3. 인클루드 패스 지정
    3-4. STM32용 디파인 매크로(USE_HAL_DRIVER, STM32F103xE)
    3-5. 불필요한 파일 컴파일에서 제외
    3-6. 스타트-업 코드 명 변경(화일 확장자 .S)
    3-7. 링크 스크립트 적용
    3-8. 빌드 완료

----------------------------------------------------------
3. Eclipse 에서 컴파일
----------------------------------------------------------

3-1. 시작 (워크 스페이스)
-----------------------

Eclipse를 실행 한다. 처음 Workspace 를 지정하라고 나올 것이다. 앞서 STM32CubeMX에서 생성했던 C 코드의 상위 폴더를 지정한다. 프로젝트 폴더를 공유하기 위함이다.

예: CubeMX에서 생성한 폴더가 아래와 같다면,

C:\Users\goodkook\Documents\STM32Cube\GPIO_PB5_LED

Eclipse 의 워크스페이스 폴더는

C:\Users\goodkook\Documents\STM32Cube



3-2. 프로젝트 생성/GNU 툴 체인 선택
----------------------------------

Eclipse에서 프로젝트를 생성한다. 메뉴, File > New > C Project 를 선택하면 프로젝트 생성 창이 나온다.

Project Name을 무엇으로 하던 상관 없으나 CubeMX와 동일한 이름으로 하면 두 도구사이에 한 폴더를 공유할 수 있다.

Project Type은 Executable > Empty Project 로 선택하자. 그 아래 STM32F10X C/C++ Project 라는 항목이 있는데 CubeMX 이전의 라이브러리 소스를 사용한 경우에 해당된다. 또한 복잡한 GCC 와 칩마다 다른 링크 옵션을 골라야 하는데 초보로서 쉽지 않다. CubeMX 가 생성해준 링크 스크립트를 이용하기로 하자.



이어서 "Select Configuration"은 그냥 넘어가고, "Cross GNU ARM Toolchain"은 주의하여 살펴본다.

- "Toolchain Name"에 "arm-none-eabi-gcc"를 확인한다. 바로 앞서 설치했던 GCC의 실행 파일 이름이다.
- "Toolchain Path"는 Browse 버튼을 눌러 앞서 설치한 GCC의 폴더 경로를 지정해준다. "arm-none-eabi-gcc.exe"가 존재하는 bin 폴더까지 지정한다.

아래의 예에서 경로명은,

C:\Program Files (x86)\GNU Tools ARM Embedded\4.9 2014q4\bin



이제 Eclipse의 "Project Explorer" 영역에 CubeMX에서 생성되었던 파일들이 모두 보일 것이다.



3-3. 인클루드 패스 지정
---------------------

메뉴, Project > Build All 해서 무작정 컴파일 해보자. 오류가 난다. 당연하다. 언제 인생이 그리 만만했던가.

무슨 오류인지 살펴보자. 오류 메시지를 잘읽고 적절하게 대처하는 것도 기술자가 갖춰야 할 중요한 덕목이다.

먼저 GNU 답게 빌드 과정(컴파일 과 링크)에서 make 유틸리티가 사용되고 있다.
오류는 c 파일 main.c에서 stm32f1xx.h 를 찾지 못했다고 한다. 컴파일러 환경 변수에 "Incluse Path"를 지정해 주지 않아서 발생한 것이다.



인클루드 패쓰에 지정되어야할 경로는 총 4군데다. 프로젝트 최상위 폴더에서,

/Drivers/CMSIS/Device/ST/STM32F1xx/Include
/Drivers/CMSIS/Include
/Drivers/STM32F1xx_HAL_Driver/Inc
/Inc

메뉴, Project > Properties 를 선택하여 컴파일러 추가설정 창을 띄운다.

+ C/C++ Build > Settings 를 선택하면 "Cross ARM Compiler"아래에 "Includes"를 지정하는 항목이 있다. 브라우즈 버튼으로 위의 네군데 폴더를 추가해준다.



3-4. STM32용 디파인 매크로(USE_HAL_DRIVER, STM32F103xE)
---------------------------------------------------------

컴파일 해보자. 다시 무지막지한 컴파일 에러가 보일 것이다. 좌절하지 말자. 오류를 보니 이상하다. GCC는 범용 C 언어 컴파일러다. GPIOB 같은 ST에서 제공하는 라이브러리에서 정의된 특수한 변수나 자료형을 인식하지 못한다. 아마 .h 파일 어딘가에 정의되어 있을 것이다. C 언어에서 이런 특수한 경우를 처리 할 때 define 매크로를 사용한다.


CubeMX 에서 생성된 매크로 이름은 USE_HAL_DRIVER 이다. GCC 컴파일러에게 이 매크로를 추가해 주자.



다시 컴파일 하면 또 다시컴파일 해보면 엄청난 오류 메시지를 보게된다. 무엇이 문제인지 에러난 파일을 따라가 보자. 해당 파일을 더블 클릭하면 편잡창에 열린다. 에러 위치를 보자.

선택한 마이크로 컨트롤러를 지정하는 매크로 성의가 더 필요하다. 이 예제에서 선택한 마이크로 컨트롤러는 STM32F103VET 였다. 이에 해당하는 매크로는 STM32F103xE 다.





3-5. 불필요한 파일 컴파일에서 제외
--------------------------------

다시 컴파일 해보면 역시 컴파일 오류가 날 것이다. 이번에도 원인을 찾아보자. DSP_Lib에서 발생된 에러다. DSP 라이브러리가 제공된다는 것은 Cortex-M이 DSP용으로 사용할 만큼 성능이 나온다는 반증이 아닐까? 어쨌든 지금은 필요 없으니 컴파일에서 제거해 준다. RTOS 도 필요 없으니 제거해 준다.

사실 HAL 드라이버 소스도 모두 컴파일 할 필요 없다. HAL 이란 Hardware Abstraction Layer 로서 동원된 하드웨어의 초기화와 구동을 위해 마련된 루틴들이다. 이번 예제는 RCC와 GPIO만 사용되었으므로 해당 파일만 컴파일 하면된다. 비록 컴파일 되었더라도 링크시 실행 파일에는 포함되지 않는다. 다만 컴파일 시간이 더 소요된다.


다시 컴파일 빌드 해보자. 또 에러다. 이제 끝이 보이니 인내심을 가지고 찾아보자.

에러 메시지를 보니 링커(Linker)에서 오류가 났다. 오류 메시지를 보니 "HAL_MspInit"라는 함수가 두개나 있다고 한다.

C:\Users\goodkook\Documents\STM32Cube\GPIO_PB5_LED\Debug/../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_msp_template.c:78: multiple definition of `HAL_MspInit'

아래 파일은 코드 생성을 위한 틀에 해당하는 파일이니 컴파일에서 제외 시키자.

/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_msp_template.c



그리고 여러개의 스타트-업 코드가 존재할 필요 없다. STM32F103VE 용 스타트업 코드 한개만 두고 나머지는 제외시키자.



다시 빌드해 보자.

만쉐~~!!!!!
드디어 성공적으로 컴파일 되었다!



어? 그런데 이상하다. 실행 코드 크기가 너무작다. 그리고 바로 위 링크 경고도 보인다.

... arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld.exe: warning: cannot find entry symbol Reset_Handler; defaulting to 08000000

리셋 핸들러 Reset_Handler 가 없단다. 리셋 핸들러를 비롯해 각종 인터럽트 벡터 테이블은 스타트-업 코드에 정의되어 있다. 그렇다면 스타트-업 코드가 빠졌다는 말인데....

3-6. 스타트-업 코드 명 변경(화일 확장자 .S)
----------------------------------------

스타트-업 코드는 여기에 있다. 어셈블러 소스다. 그런데 화일 확장자가 .s 이다. GCC 의 어셈블러는 확장자가 .S로 대문자 이어야 한다. 화일명을 startup_stm32f103xe.S 로 바꾸자.


그리고 다시 빌드 한다. 실행 파일을 생성하기 위해 링크 스크립트가 포함되어야 한다. 링크 스크립트에는 실행코드가 적제될 주소 영역 정보가 포함되어 있으므로 타겟 CPU마다 다르다. STM32CubeMX에서 생성해준 링크 스크립트를 적용해야 한다.



3-7. 링크 스크립트 적용
---------------------

링크 스크립트를 적용하기 위한 옵션은 다음과 같다.

-T "..\TrueSTUDIO\GPIO_PB5_LED Configuration\STM32F103VE_FLASH.ld"




만쉐~~!!!!!
드디어 성공적으로 컴파일 되었다! 



3-8. 빌드 완료
-------------

그런데 별것도 아닌 프로그램이 실행 코드가 너무 크다. 컴파일러 최적화 옵션을 좀 손봐야 하겠다. 앞으로도 몇번의 연습이 필요할 것이다.

어쨌든 칩에 다운로드하고 실행 시켜보자. GDB로 디버깅도 해보고....


댓글 없음:

댓글 쓰기