Professional Documents
Culture Documents
2. 프로젝트 만들기
TrueStudio를 통해 프로젝트 생성시에 크게 2가지 방법으로 프로젝트를 생성할 수 있습니다. 첫 번째는 TrueStduio의
.cproject와 같이 TrueStudio의 XML 프로젝트 파일을 통해 프로젝트를 관리하는 방법(TrueStudio의 IDE를 통해 관리가 됩니
다.)과 MakeFile을 통해 관리하는 방법이 있습니다. 둘 다 장단점을 갖고 있지만, 주로 MakeFile을 통해 관리하는 방법을 사용
합니다. MakeFile을 사용하게 되면 GCC 컴파일러로 쉽게 빌드를 할 수 있습니다.
TrueStudio의 프로젝트는 C언어만을 지원하는 프로젝트와 C/C++ 모두를 지원하는 프로젝트를 생성할 수 있는데, 여기에서는
C/C++ 모두를 지원하는 프로젝트를 사용합니다.
2.3.1 .project
TrueStudio의 프로젝트 파일로써 프로젝트 이름이 포함되어 있습니다.
2.3.2 .cproject
TrueStudio에서 소스 파일 및 빌드관련한 정보를 포함하고 있습니다. 빌드시스템을 atollic를 사용할지 MakeFile을 사용할지
에 대한 정보는 다음과 같이 .cproject XML 파일의 다음 항목에서 확인을 할 수 있습니다.
Atollic 프로젝트
...
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="attolic_project.com.atollic.truestudio.exe.887755257" name="Executable"
projectType="com.atollic.truestudio.exe"/>
</storageModule>
...
Makefile 프로젝트
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="make.null.639095045" name="make"/>
</storageModule>
3. 프로젝트 설정 변경하기
프로젝트 설정에서 TrueStudio 프로젝트와 MakeFile의 사용에 대해 설정하는 방법이 공통적인 것도 있고 다른 것들도 있습니
다. 프로젝트 설정은 "Project Explorer"에서 먼저 프로젝트를 선택 한 후에 메뉴의 "Project"->"Properties"를 선택하면 됩
니다.
여기에서 중요한 몇가지에 대해서만 설명을 합니다.
4.2.1 보드 타겟 만들기
두개의 보드는 서로 다르기 때문에 각각의 보드에 따라 서로 다른 빌드가 되어야 합니다. 그럼므로 두개의 보드를 구별하기 위
해 TARGET_BOARD라는 환경 변수에 보드이름을 할당합니다.
TARGET_BOARD=STEVAL_FCU001V1
TARGET_BOARD=STEVAL_STM32H743ZI
Name : TARGET_BOARD
Value : NUCLEO_H743ZI
Name : DEBUG
Value : 1
Name : DEBUG
Value : 0
OS_NAME = WINDOWS
SHELL = cmd
else
GCC_PREFIX := arm-atollic-eabi
CC = arm-atollic-eabi-gcc
CXX = arm-atollic-eabi-g++
OBJCOPY = arm-atollic-eabi-objcopy
SIZE = arm-atollic-eabi-size
MKDIR_CMD = mkdir -p
MKDIR_FROM_CHAR = \
MKDIR_TO_CHAR = /
MKDIR_OPTION = 2> /dev/null
OS_NAME = LINUX
SHELL = /bin/sh
endif
else
GCC_PREFIX := arm-none-eabi
CC = ./toolchain/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc
CXX = ./toolchain/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-g++
OBJCOPY = ./toolchain/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-objcopy
SIZE = ./toolchain/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-size
MKDIR_CMD = mkdir -p
MKDIR_FROM_CHAR = \
MKDIR_TO_CHAR = /
MKDIR_OPTION = 2> /dev/null
OS_NAME = LINUX
SHELL = /bin/sh
endif
* 만약 윈도우즈를 제대로 인식하지 못하면 윈도우즈의 CMD창을 열어 PATH를 실행하여 "C:\Windows\System32"라는 문자열이
다르게 되어 있으면 해당 문자열로 변경을 합니다.
* 리눅스에서 TrueStudio 빌드인지 GCC 빌드인지에 대해서는 TrueStudio의 환경변수 "TRUESTUDIO_BUILD" 변수에 1을 설정합
니다. GCC일때는 정의를 하지 않습니다.
STEVAL_FCU001V1
ifeq ("$(TARGET_BOARD)", "STEVAL_FCU001V1")
TARGET_MCU += -mcpu=cortex-m4
TARGET_FPU += -mfpu=fpv4-sp-d16
TARGET_INSTRUCTION += -mthumb -mhard-float
TARGET_C_EXTRA += -ffunction-sections -fdata-sections -specs=nano.specs
TARGET_CXX_EXTRA += -fno-threadsafe-statics -ffunction-sections -fdata-sections -fno-exceptions -fno-
rtti
TARGET_A_EXTRA += -specs=nano.specs -x assembler-with-cpp
USB_DEVICE := CDC
USE_USB_DEVICE := USED
ifeq ("$(DEBUG)", "1")
TARGET := $(TARGET_BOARD)_DEBUG
BUILD_OPTION += -g -O0
TARGET_MODEL_DEFINITION += -DDEBUG_STRING_LEVEL_WARN -DDEBUG_STRING_LEVEL_DEBUG -
DDEBUG_STRING_LEVEL_FN_TRACE -DDEBUG_STRING_LEVEL_INFO -DDEBUG_STRING_LEVEL_DUMP
else
TARGET := $(TARGET_BOARD)_RELEASE
BUILD_OPTION += -O3
endif
# for HAL library & CMSIS
INCLUDE_DIR += -I./Drivers/F4_V1.21.0/CMSIS/Include
INCLUDE_DIR += -I./Drivers/F4_V1.21.0/CMSIS/Device/ST/STM32F4xx/Include
INCLUDE_DIR += -I./Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Inc
INCLUDE_DIR += -I./Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Inc/Legacy
endif
DISCOVERY_STM32F7
ifeq ("$(TARGET_BOARD)", "DISCOVERY_STM32F7")
TARGET_MCU += -mcpu=cortex-m7
TARGET_FPU += -mfpu=fpv5-sp-d16
TARGET_INSTRUCTION += -mthumb -mhard-float
TARGET_C_EXTRA += -ffunction-sections -fdata-sections -specs=nano.specs
TARGET_CXX_EXTRA += -fno-threadsafe-statics -ffunction-sections -fdata-sections -fno-exceptions -fno-
rtti
TARGET_A_EXTRA += -specs=nano.specs -x assembler-with-cpp
TARGET_HAL_DEFINITION += -D"STM32F746xx"
TARGET_MODEL_DEFINITION += -D$(TARGET_BOARD) -DUART_DEBUG_PORT=1 -DSUPPORT_DEBUG_OUTPUT -
DUART_DEBUG_OUTPUT -DDEBUG_STRING_LEVEL_ERROR
TARGET_MODEL_DEFINITION += -DUSE_USB_CDC_DEVICE -DUSE_USB_HS
TARGET_MODEL_DEFINITION +=
USB_DEVICE := CDC
USE_USB_DEVICE := USED
ifeq ("$(DEBUG)", "1")
TARGET := $(TARGET_BOARD)_DEBUG
BUILD_OPTION += -g -O0
TARGET_MODEL_DEFINITION += -DDEBUG_STRING_LEVEL_WARN -DDEBUG_STRING_LEVEL_DEBUG -
DDEBUG_STRING_LEVEL_FN_TRACE -DDEBUG_STRING_LEVEL_INFO -DDEBUG_STRING_LEVEL_DUMP
else
TARGET := $(TARGET_BOARD)_RELEASE
BUILD_OPTION += -O3
endif
# for HAL library & CMSIS
INCLUDE_DIR += -I./Drivers/F7_V1.11.0/CMSIS/Include
INCLUDE_DIR += -I./Drivers/F7_V1.11.0/CMSIS/Device/ST/STM32F4xx/Include
INCLUDE_DIR += -I./Drivers/F7_V1.11.0/STM32F4xx_HAL_Driver/Inc
INCLUDE_DIR += -I./Drivers/F7_V1.11.0/STM32F4xx_HAL_Driver/Inc/Legacy
endif
NUCLEO_H743ZI
ifeq ("$(TARGET_BOARD)", "NUCLEO_H743ZI")
TARGET_MCU += -mcpu=cortex-m7
TARGET_FPU += -mfpu=fpv5-sp-d16
TARGET_INSTRUCTION += -mthumb -mhard-float
TARGET_C_EXTRA += -ffunction-sections -fdata-sections -specs=nano.specs
TARGET_CXX_EXTRA += -fno-threadsafe-statics -ffunction-sections -fdata-sections -fno-exceptions -fno-
rtti
TARGET_A_EXTRA += -specs=nano.specs -x assembler-with-cpp
USB_DEVICE := CDC
USE_USB_DEVICE := USED
ifeq ("$(DEBUG)", "1")
TARGET := $(TARGET_BOARD)_DEBUG
BUILD_OPTION += -g -O0
TARGET_MODEL_DEFINITION += -DDEBUG_STRING_LEVEL_WARN -DDEBUG_STRING_LEVEL_DEBUG -
DDEBUG_STRING_LEVEL_FN_TRACE -DDEBUG_STRING_LEVEL_INFO -DDEBUG_STRING_LEVEL_DUMP
else
TARGET := $(TARGET_BOARD)_RELEASE
BUILD_OPTION == -O3
endif
STEVAL_FCU001V1
ifeq ("$(TARGET_BOARD)", "STEVAL_FCU001V1")
# HAL Library Source
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c
ifeq ($(USE_USB_DEVICE),USED)
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c
HAL_LIBRARY_C_SRC += Drivers/F4_V1.21.0/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c
endif
endif
# -----------------------------------------------------------------------------
# Middle Source
# C Source of USB
ifeq ($(USB_DEVICE),CDC)
MIDDLEWARE_C_SRC += $(wildcard ./Middlewares/ST/STM32_USB_Device_Library/Core/Src/*.c)
MIDDLEWARE_C_SRC += $(wildcard ./Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/*.c)
MIDDLEWARE_C_SRC += $(wildcard ./src/drivers/usb/cdc/src/*.c)
INCLUDE_DIR += -I./Middlewares/ST/STM32_USB_Device_Library/Core/Inc
INCLUDE_DIR += -I./Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc
INCLUDE_DIR += -I./src/drivers/usb/cdc/inc
endif
ifeq ($(USB_DEVICE),BULK)
MIDDLEWARE_C_SRC += $(wildcard ./Middlewares/ST/STM32_USB_Device_Library/Core/Src/*.c)
MIDDLEWARE_C_SRC += $(wildcard ./Middlewares/ST/STM32_USB_Device_Library/Class/BULK/Src/*.c)
MIDDLEWARE_C_SRC += $(wildcard ./src/drivers/usb/bulk/src/*.c)
INCLUDE_DIR += -I./Middlewares/ST/STM32_USB_Device_Library/Core/Inc
INCLUDE_DIR += -I./Middlewares/ST/STM32_USB_Device_Library/Class/BULK/Inc
INCLUDE_DIR += -I./src/drivers/usb/bulk/inc
endif
4.3.5 보드별 소스 추가
보드에 관련된 소스는 공통적인 소스와 보드에 종속적인 소스로 구별해서 추가가 됩니다. C++ 소스는 DRIVERS_CXX_SRC
나 MODEL_CXX_SRC에 추가를 하면 됩니다.
# -----------------------------------------------------------------------------
# Common Driver Source
ifeq ($(USE_USB_DEVICE),USED)
DRIVERS_C_SRC += src/drivers/usb/usb_device.c
INCLUDE_DIR += -Isrc/drivers/usb/inc
endif
# C Source of common
DRIVERS_C_SRC += src/common/src/printf.c
DRIVERS_C_SRC += src/common/src/uart_debug.c
DRIVERS_C_SRC += src/common/src/scheduler.c
INCLUDE_DIR += -Isrc/common/inc
# -----------------------------------------------------------------------------
# Model Source
# "STEVAL_FCU001V1"
ifeq ("$(TARGET_BOARD)", "STEVAL_FCU001V1")
INCLUDE_DIR += -Isrc/model/$(TARGET_BOARD)/inc
INCLUDE_DIR += -Isrc/drivers/$(TARGET_BOARD)/inc
ASM_SRC += src/startup/$(TARGET_BOARD)/startup_stm32f401xc.s
MODEL_C_SRC += src/model/$(TARGET_BOARD)/src/stm32f4xx_hal_msp.c
MODEL_C_SRC += src/model/$(TARGET_BOARD)/src/stm32f4xx_it.c
MODEL_C_SRC += src/model/$(TARGET_BOARD)/src/system_stm32f4xx.c
MODEL_CXX_SRC +=
endif
4.3.6 기타
그 외 추가된 것은 빌드 관련되어 추가된 사항으로 특별하게 빌드에 문제가 되지 않는 한 변경되는 일이 거의 없습니다. C소스
및 C++ 소스는 아래와 같이 결국에는 C_SRC와 CXX_SRC로 정리가 됩니다.
C_SRC := $(HAL_LIBRARY_C_SRC) $(MIDDLEWARE_C_SRC) $(DRIVERS_C_SRC) $(MODEL_C_SRC)
CXX_SRC := $(HAL_LIBRARY_CXX_SRC) $(MIDDLEWARE_CXX_SRC) $(DRIVERS_CXX_SRC) $(MODEL_CXX_SRC)
모델용으로 작성된 C언어 파일을 "MODEL_C_SRC"에 추가하지 않고 "HAL_LIBRARY_C_SRC"에 추가해도 문제없이 빌드가 됩니다.
이는 논리적으로 구분을 해 놓은 것입니다. 다만 C 언어 파일을 MODEL_CXX_SRC와 같이 CXX에 추가를 하면 됩니다. C 언어는 C
언어 쪽에 C++ 언어는 C++ 언어쪽에 놓아야 합니다.
5. 빌드 및 디버깅
여기에서는 TrueStudio를 통해 빌드하는 방법과 GCC를 통해 빌드하는 방법에 대해 설명을 합니다.
5.1 빌드하기
5.1.1 TrueStudio 9.1에서 빌드하기
불행스럽게 Makefile을 통한 빌드시에는 TrueStudio의 "Manage Build Configuration"을 통해 빌드가 되지 않습니다. 그렇기
때문에 불편하지만 다음과 같이 환경변수를 수정하여 빌드를 합니다.
TrueStudio의 Project->Properties(Project Explorer의 프로젝트 명에서 마우스 오른쪽 버튼 선택시 팝업메뉴에서
Properties)를 선택합니다. Properties 다이얼로그박스의 왼쪽 메뉴에서 C/C++ Build->Environment(펼쳐져 있지 않으면 >를
선택하면 펼쳐집니다.)를 선택합니다. 그리고 오른쪽에 있는 다음 항목을 수정하여 빌드를 할 수 있습니다.
TARGET_BOARD
DEBUG
다른 보드나 릴리즈 모드 등으로 빌드를 하기 위해서는 위의 값을 변경하여 빌드를 합니다. 그 외의 값들은 변경하지 않습니다.
* 만약 Header 파일(.h)을 수정하였다면, TrueStudio의 Project->Clean Project를 실행 한 후에 TrueStudio의 Project-
>Rebuild Project를 해야 됩니다.(Makefile에서 헤더파일에 대한 종속성(dependency)이 설정되어 있지 않아서 발생하는 문제
입니다.)
5.2 디버깅하기
보드별 디버깅을 하기 위해서는 빌드시와 같이 여러개의 환경을 추가해서 디버깅이 TrueStudio의 버그인지 동작이 잘 되지 않
습니다. 아마도 TrueStudio의 프로젝트는 하나의 코어에 대해서 작성하도록 되어 있어 그런 문제가 발생하는 것 같습니다.
메뉴에서 Project->Properties를 선택한 후, Properties화면에서 "Run/Debug Setting"를 선택한 후 왼쪽에 추가된 설정이
있으면 삭제를 한 후에 New를 선택합니다. Select Config 다이얼로그 박스에서 "Embedded C/C++ Application"을 선택한 후
OK 버튼을 선택합니다.
C/C++ Application
여기에는 elf파일을 추가하는 항목으로 Browse 버튼을 선택하여 elf파일을 선택합니다.(OUTPUT 디렉토리 밑에 .elf 파일이 생
성됩니다.)
STEVAL_FCU001V1 : STM32F401CC
DISCOVERY_STM32F7 : STM32F746NG
NUCLEO_H743ZI : STM32H743Zi
6.1 Makefile
Makefile에서는 같은 코어를 사용한 보드가 있으면(cortex-m4나 coretex-m7) 추가하기가 쉬우나, 다른 코어를 사용했다면 다
음과 추가로 작성하는 일이 그리 쉽지는 않습니다.
먼저 Makefile에서 유사한 다른 보드의 설정을 복사합니다. 만약 DISCOVERY_STM32F와 유사한 보드라고 가정을 할 때, "ifeq
("$(TARGET_BOARD)", "DISCOVERY_STM32F7")"로 검색을 한 후에 각각을 복사하여 바로 밑에 추가를 합니다.
ifeq ("$(TARGET_BOARD)", "DISCOVERY_STM32F7")
...
endif
그리고 HAL 라이브러리를 사용하기 위해 참조로 만든 Makefile에 보면 칩에 대한 정의가 있습니다. 다음 항목을 적당한 값으로
변경을 합니다.
TARGET_HAL_DEFINITION += -D"STM32F746xx"
6.2 필수 Source하기
신규보드에 맞는 필수 파일을 추가해야 합니다.
6.2.1 ldscript
링크스크립트 파일은 참조로 만든 소스에 .ld로 생성되어 있습니다. 해당 파일을 다음과 같은 디렉토리를 생성한 후에 이름을
변경하여 추가를 합니다.
./ldscript/NEW_BOARD/NEW_BOARD_FLASH.ld
stm32fxxx_hal_msp.c
stm32fxxx_it.c
system_stm32fxxx.c
* 참조로 생성한 main.c 함수에 있는 void SystemClock_Config(void) 함수는 위의 system_stm32fxxx.c 파일로 코드를 복사
합니다.
main.h
stm32fxxx_hal_conf.h : ST의 HAL Configuration 설정 파일입니다.