ChibiOS 다운로드

ChibiOS/RT는 http://sourceforge.net/projects/chibios/files에서 최신 버젼을 다운로드 받을 수 있습니다. 상업용 라이센스를 요청하기 전에 제품 평가를 위해서 GPL 버젼을 사용할 수 있으며, 코드는 정확하게 같습니다. 2018.2월 기준, 버젼은 ChibiOS_18.2.0이고 이를 기준으로 설명합니다.


다운로드 받은 ChibiOS_18.2.0을 압축해제 하면 ChibiOS 폴더 내에 아래와 같은 폴더 구조를 볼 수 있습니다.

demos/ -- 각 플랫폼에 따른 예제입니다.

docs/ -- 문서입니다. 

ext/ -- ChibiOS는 아니지만 외부 라이브러리입니다. 예) fat, tcp/ip 스택

os/ -- ChibiOS 소스 코드입니다.

test/ -- 커널 테스트를 위한 소스 코드입니다.

testhal/ -- HAL integration 테스트 예제입니다.

community/

testex/

tools/


ext에 마련된 모듈은 SD 카드를 지원하기 위한 FAT 파일시스템과 네트워크를 지원하기 위한 오픈 소스 스택인 lwip 등이 포함되어 있으며 필요시 사용할 수 있습니다. testhal의 경우 각 플랫폼에 따른 마이크로컨트롤러의 주변장치를 사용하기 위한 HAL 예제가 마련되어 있습니다. 필요한 경우 가져다 쓰면 됩니다. 예를 들어 ADC의 사용 예제를 참고하고 싶으면 testhal\STM32\STM32F4xx\ADC 폴더에 완전한 소스 코드를 확인할 수 있습니다.


한편 docs 내에 readme.txt 파일 내용과 같은 절차에 따라 documentation을 HTML 문서로 만들 수 있으며 ChibiOS 사용시 도움을 얻을 수 있습니다. 사실 컴파일 시 요구되는 폴더는 소스 코드인 os 폴더와 필요하다면 ext 폴더 정도를 사용할 수 있습니다.


새로운 프로젝트 작성

작업의 편의를 위해서 ChibiOS 폴더 아래에 원하는 폴더를 생성합니다. 예를 들어 저렴한 STM32F411RE-NUCLEO64 보드를 사용한다고 가정하여 ~/ChibiOS_18.2.0/myProject/LED로 폴더를 만들었습니다. 그리고 원하는 프로젝트와 가장 유사한 예제를 우선 demos 폴더에서 찾아 자신이 만든 새폴더로 복사합니다.



위 그림과 같은 STM32F411RE-NUCLEO64 보드를 사용할 경우, demos\STM32\RT-STM32F411RE-NUCLEO64 폴더에 이미 친절하게 준비되어 있습니다. 복사한 파일은 반드시 있어야 하는 3개의 헤더 파일인 chconf.h, halconf.h, mcuconf.h와 자신이 코딩할 main.c 그리고 리눅스/유닉스와 같은 커맨드라인 환경에서 개발하는데 필요한 Makefile입니다.


    • chconf.h - Kernel에 관련된 세팅이 포함되며 예를 들어 시스템 타이머와 Kernel 파라미터, 디버깅에 연관된 스위치 설정.

    • halconf.h - ChibiOS/HAL 드라이버에 관련된 설정. 예를 들어, PAL, CAN, ADC, DAC, PWM, Serial 등이며 사용하지 않는 드라이버는 disable 시킴.

    • mcuconf.h - MCU에 관련된 모든 설정. 예를 들어 Clock 트리, DMA, IRQ 우선순위 등.


Makefile 편집

Makefile은 전통적인 make 명령이 이해할 수 있는 문법으로 구성되어 있어 컴파일 및 링크 등이 일괄 처리되도록 규명한 일종의 배치 파일입니다. 다음은 demos\STM32\RT-STM32F411RE-NUCLEO64 폴더에서 복사해 온 Makefile의 내용입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
##############################################################################
# Build global options
# NOTE: Can be overridden externally.
#
 
# Compiler options here.
ifeq ($(USE_OPT),)
  USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16
endif
 
# C specific options here (added to USE_OPT).
ifeq ($(USE_COPT),)
  USE_COPT = 
endif
 
# C++ specific options here (added to USE_OPT).
ifeq ($(USE_CPPOPT),)
  USE_CPPOPT = -fno-rtti
endif
 
# Enable this if you want the linker to remove unused code and data
ifeq ($(USE_LINK_GC),)
  USE_LINK_GC = yes
endif
 
# Linker extra options here.
ifeq ($(USE_LDOPT),)
  USE_LDOPT = 
endif
 
# Enable this if you want link time optimizations (LTO)
ifeq ($(USE_LTO),)
  USE_LTO = yes
endif
 
# If enabled, this option allows to compile the application in THUMB mode.
ifeq ($(USE_THUMB),)
  USE_THUMB = yes
endif
 
# Enable this if you want to see the full log while compiling.
ifeq ($(USE_VERBOSE_COMPILE),)
  USE_VERBOSE_COMPILE = no
endif
 
# If enabled, this option makes the build process faster by not compiling
# modules not used in the current configuration.
ifeq ($(USE_SMART_BUILD),)
  USE_SMART_BUILD = yes
endif
 
#
# Build global options
##############################################################################
 
##############################################################################
# Architecture or project specific options
#
 
# Stack size to be allocated to the Cortex-M process stack. This stack is
# the stack used by the main() thread.
ifeq ($(USE_PROCESS_STACKSIZE),)
  USE_PROCESS_STACKSIZE = 0x400
endif
 
# Stack size to the allocated to the Cortex-M main/exceptions stack. This
# stack is used for processing interrupts and exceptions.
ifeq ($(USE_EXCEPTIONS_STACKSIZE),)
  USE_EXCEPTIONS_STACKSIZE = 0x400
endif
 
# Enables the use of FPU (no, softfp, hard).
ifeq ($(USE_FPU),)
  USE_FPU = no
endif
 
#
# Architecture or project specific options
##############################################################################
 
##############################################################################
# Project, sources and paths
#
 
# Define project name here
PROJECT = ch
 
# Imported source files and paths
CHIBIOS = ../../..
# Startup files.
include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f4xx.mk
# HAL-OSAL files (optional).
include $(CHIBIOS)/os/hal/hal.mk
include $(CHIBIOS)/os/hal/ports/STM32/STM32F4xx/platform.mk
include $(CHIBIOS)/os/hal/boards/ST_NUCLEO64_F411RE/board.mk
include $(CHIBIOS)/os/hal/osal/rt/osal.mk
# RTOS files (optional).
include $(CHIBIOS)/os/rt/rt.mk
include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk
# Other files (optional).
include $(CHIBIOS)/test/lib/test.mk
include $(CHIBIOS)/test/rt/rt_test.mk
include $(CHIBIOS)/test/oslib/oslib_test.mk
 
# Define linker script file here
LDSCRIPT= $(STARTUPLD)/STM32F411xE.ld
 
# C sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CSRC = $(STARTUPSRC) \
       $(KERNSRC) \
       $(PORTSRC) \
       $(OSALSRC) \
       $(HALSRC) \
       $(PLATFORMSRC) \
       $(BOARDSRC) \
       $(TESTSRC) \
       main.c
 
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CPPSRC =
 
# C sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
#       option that results in lower performance and larger code size.
ACSRC =
 
# C++ sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
#       option that results in lower performance and larger code size.
ACPPSRC =
 
# C sources to be compiled in THUMB mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
#       option that results in lower performance and larger code size.
TCSRC =
 
# C sources to be compiled in THUMB mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
#       option that results in lower performance and larger code size.
TCPPSRC =
 
# List ASM source files here
ASMSRC =
ASMXSRC = $(STARTUPASM) $(PORTASM) $(OSALASM)
 
INCDIR = $(CHIBIOS)/os/license \
         $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \
         $(HALINC) $(PLATFORMINC) $(BOARDINC) $(TESTINC) \
         $(CHIBIOS)/os/various
 
#
# Project, sources and paths
##############################################################################
 
##############################################################################
# Compiler settings
#
 
MCU  = cortex-m4
 
#TRGT = arm-elf-
TRGT = arm-none-eabi-
CC   = $(TRGT)gcc
CPPC = $(TRGT)g++
# Enable loading with g++ only if you need C++ runtime support.
# NOTE: You can use C++ even without C++ support if you are careful. C++
#       runtime support makes code size explode.
LD   = $(TRGT)gcc
#LD   = $(TRGT)g++
CP   = $(TRGT)objcopy
AS   = $(TRGT)gcc -x assembler-with-cpp
AR   = $(TRGT)ar
OD   = $(TRGT)objdump
SZ   = $(TRGT)size
HEX  = $(CP) -O ihex
BIN  = $(CP) -O binary
 
# ARM-specific options here
AOPT =
 
# THUMB-specific options here
TOPT = -mthumb -DTHUMB
 
# Define C warning options here
CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes
 
# Define C++ warning options here
CPPWARN = -Wall -Wextra -Wundef
 
#
# Compiler settings
##############################################################################
 
##############################################################################
# Start of user section
#
 
# List all user C define here, like -D_DEBUG=1
UDEFS =
 
# Define ASM defines here
UADEFS =
 
# List all user directories here
UINCDIR =
 
# List the user directory to look for the libraries here
ULIBDIR =
 
# List all user libraries here
ULIBS =
 
#
# End of user defines
##############################################################################
 
RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC
include $(RULESPATH)/rules.mk
 
cs


86번 라인의 PROJECT는 프로젝트의 이름이자 생성되는 파일명과 같습니다. 89번 라인은 ChibiOS 폴더의 절대 경로 또는 상대 경로입니다. '~/ChibiOS_18.2.0'이 추천됩니다. 161번 라인은 STM32F411RE-NUCLEO64 보드가 STM32F406 디바이스를 내장하므로 'cortex-m4'입니다. 164번은 사용하는 Toolchain을 지정하는 것으로 기본적으로 GNU Toolchain을 사용하도록 되어 있으므로 그냥 둡니다.


95번 라인의 'board.mk'는 사용하는 보드의 설정 정보를 담은 것으로 아래와 같습니다. 여기서는 'board.h'와 'board.c' 파일을 include 하게 합니다. 우선 board.h 파일의 정보는 보드에서 마이크로컨트롤러의 핀이 어떻게 사용되었는지에 관한 정보입니다. 예를 들어 핀인 GPIO는 아날로그와 디지털 모드로 사용될 수 있으며, 디지털 모드는 그 쓰임새에 따라 입력 혹은 출력, pull-up, PWM, CAN, UART 등등 여러가지의 모드로 사용되며 이를 일일이 지정하게 됩니다. board.c 파일은 board.h 파일에서 GPIO 사용을 매크로 지정한데로 초기화하는 함수가 구현되어 있습니다. 따라서 핀의 사용이 달라진다면 board.h는 반드시 수정되어야 합니다.


1
2
3
4
5
6
7
8
9
# List of all the board related files.
BOARDSRC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO64_F411RE/board.c
 
# Required include directories
BOARDINC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO64_F411RE
 
# Shared variables
ALLCSRC += $(BOARDSRC)
ALLINC  += $(BOARDINC)
cs


그러나 사용하고자 하는 보드가 없거나 사용자가 직접 PCB를 제작하고 assemble 한 보드의 경우에는 가장 유사하다고 생각되는 demos 폴더 하에 보드 중에서 찾아보고 /os/hal/boards 폴더 하에 적당한 board.mk, board.h 그리고 board.c 파일을 자신이 생성한 폴더에 복사합니다. 그리고 board.mk 파일에서 경로를 수정하고 board.h 파일에서 GPIO를 수정해야 합니다.


애플리케이션 코딩

'main.c'에 사용자가 원하는 기능을 작성하면 됩니다. demos\STM32\RT-STM32F411RE-NUCLEO64 폴더에서 제공하는 예제인 main.c는 다음과 같습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
    ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
        http://www.apache.org/licenses/LICENSE-2.0
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/
 
#include "ch.h"
#include "hal.h"
#include "rt_test_root.h"
#include "oslib_test_root.h"
 
/*
 * Green LED blinker thread, times are in milliseconds.
 */
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {
 
  (void)arg;
  chRegSetThreadName("blinker");
  while (true) {
    palClearPad(GPIOA, GPIOA_LED_GREEN);
    chThdSleepMilliseconds(500);
    palSetPad(GPIOA, GPIOA_LED_GREEN);
    chThdSleepMilliseconds(500);
  }
}
 
/*
 * Application entry point.
 */
int main(void) {
 
  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();
 
  /*
   * Activates the serial driver 2 using the driver default configuration.
   */
  sdStart(&SD2, NULL);
 
  /*
   * Creates the blinker thread.
   */
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
 
  /*
   * Normal main() thread activity, in this demo it does nothing except
   * sleeping in a loop and check the button state.
   */
  while (true) {
    if (!palReadPad(GPIOC, GPIOC_BUTTON)) {
      test_execute((BaseSequentialStream *)&SD2, &rt_test_suite);
      test_execute((BaseSequentialStream *)&SD2, &oslib_test_suite);
    }
    chThdSleepMilliseconds(500);
  }
}
cs


ChibiOS는 멀티 쓰레드(multi-thread)를 지원하고 Thread1은 GPIOA의 5번 핀을 500ms 간격으로 컸다 켰다를 반복합니다. 여기서 chRegSetThreadName("blinker") 함수는 ChibiOS 이하의 os\rt\include\chregistry.h에 선언되어 있으며, chThdSleepMilliseconds() 함수는 ChibiOS 이하의 os\rt\include\chthreads.h에 선언되어 있고, palClearPad()와 palSetPad() 함수는 ChibiOS 이하의 os\hal\include\hal_pal.h에 선언되어 있습니다.


main() 함수에서 hallnit()는 ChibiOS/HAL과 HAL 서브 시스템을 초기화 하는 것이며, chSysInit()는 Kernel이 초기화되고 main 함수가 쓰레드가 되며 RTOS가 활성화되도록 합니다. 이후에는 main() 함수의 스레드와 다른 모든 스레드가 실행될 준비가 되지 않았을 때 실행되는 idle 스레드가 생성됩니다. 한편 halInit() 함수는 ChibiOS 이하의 os\hal\include\hal.h에 그리고 chSysInit() 함수는 ChibiOS 이하의 os\rt\include\chsys.h에 선언되어 있습니다.


sdStart(&SD2, NULL) 함수는 시리얼 드라이버 2를 디폴트 설정으로 활성화 하는 것으로 ChibiOS 이하의 os\hal\include\hal_serial.h에 정의되어 있습니다. chThdCreateStatic() 함수는 Thread1을 생성시키는 함수로 ChibiOS 이하의 os\rt\include\chthreads.h에 선언되어 있습니다.


while 문 내에 palReadPad(GPIOC, GPIOC_BUTTON)) 함수는 GPIOC의 13번 핀에 연결된 버튼 값을 읽어오는 것으로 ChibiOS 이하의 os\hal\include\hal_pal.h에 선언되어 있으며, 버튼이 눌러지면 조건 문 아래의 연속된 test_execute() 함수가 실행되고 이는 500ms 간격으로 버튼을 조사하게 됩니다. 이 test_execute()는 ChibiOS 이하의 test\lib\ch_test.h에 정의된 함수로 두번째 인자인 문자열을 시리얼 드라이버 2에 보내게 됩니다.


빌드

작성이 완료되었으며 make 명령으로 컴파일 합니다. 만일 헤더 파일이 수정되었다면 처음부터 다시 컴파일을 진행할 것이고 오류없이 컴파일이 성공하였다면 ~/ChibiOS_18.2.0/myProject/LED/build 폴더 안에 'ch.elf'를 확인할 수 있을 것입니다.



'Embedded Programming > ChibiOS' 카테고리의 다른 글

ChibiOS/RT의 특징  (0) 2018.02.25
Cortex-M4 환경에서 ChibiOS 사용한 기초 예제  (0) 2017.12.19
Posted by Nature & Life