nuttx에 예제 애플리케이션과 직접 만든 애플리케이션을 포함해 빌드하는 방법
nuttx 애플리케이션 작성하기
제 환경은 윈도우 10 빌드 2004 + Cygwin, 타겟 보드는 nucleo-l432kc(stm32l432kc)입니다. nuttx OS 개발환경 구축과 바이너리 플래시 방법은 전 포스트를 참고해주세요.
helloworld 예제 빌드해보기
OS 경로에서 make menuconfig
→ Application Configuration
→ Examples
→ "Hello, World!" example"
을 Y
를 눌러 추가하고 Save
한 후 빠져나옵니다. 이제 make -j4
를 실행해 빌드하고 openocd를 이용해 nuttx.hex
파일을 플래시해줍니다. 이후 타겟 보드와 시리얼 연결을 열고 nsh에서 help
를 실행하면 아래와 같이 우리가 추가한 애플리케이션이 추가된 것을 확인할 수 있습니다.
nsh> help
help usage: help [-v] [<cmd>]
. cd echo kill mount set uname
[ cp exec ls mv sleep umount
? cmp exit mb mw source unset
basename dirname false mkdir pwd test usleep
break date help mkrd rm time xd
cat dd hexdump mh rmdir true
Builtin Apps:
alarm hello nsh ostest rand sh
그럼, nsh에서 우리가 추가한 앱을 실행시켜봅시다.
nsh> hello
Hello, World!!
잘 실행되는걸 확인할 수 있는데요. 그럼 앱 구조를 분석해볼까요. <APPS 폴더 경로>/examples/hello
로 들어가시면, 크게 3가지 파일을 확인하실 수 있습니다. 실제 소스를 담고 있는 hello_main.c
, Kconfig(우리가 주로 menuconfig라는 프론트엔드로 접하는) 설정 내용을 담고 있는 Kconfig
, 빌드 방법과 세부 사항을 담고 있는 Makefile
입니다. 각각 내용을 살펴보면,
//hello_main.c
#include <nuttx/config.h>
#include <stdio.h>
int main(int argc, FAR char *argv[])
{
printf("Hello, World!!\n");
return 0;
}
hello_main.c
은 정말 진입점 함수 int main(...)
과 동작을 기술하고 있습니다. <nuttx/config.h>
는 일반적으로 모든 nuttx 앱에 포함되어야 합니다. 그다음으로,
config EXAMPLES_HELLO
tristate "\"Hello, World!\" example"
default n
---help---
Enable the \"Hello, World!\" example
if EXAMPLES_HELLO
config EXAMPLES_HELLO_PROGNAME
string "Program name"
default "hello"
---help---
This is the name of the program that will be used when the NSH ELF
program is installed.
config EXAMPLES_HELLO_PRIORITY
int "Hello task priority"
default 100
config EXAMPLES_HELLO_STACKSIZE
int "Hello stack size"
default DEFAULT_TASK_STACKSIZE
endif
Kconfig
파일은 프로그램 빌드 시 적용될 매개변수들을 알려주고 있습니다. kconfig의 프론트앤드가 이 파일을 읽어 빌드시 지정하는 역할을 맡는데요, 크게 이 앱을 빌드 시 포함할지 여부인 EXAMPLES_HELLO
, 앱의 이름을 결정하는 EXAMPLES_HELLO_PROGNAME
, Task의 우선 순위를 결정하는 EXAMPLES_HELLO_PRIORITY
와 Task의 스택 크기를 결정하는 EXAMPLES_HELLO_STACKSIZE
의 4개의 변수가 정의되어 있습니다. 이 변수들은 Makefile에서 불러와 사용하는데요,
include $(APPDIR)/Make.defs
PROGNAME = $(CONFIG_EXAMPLES_HELLO_PROGNAME)
PRIORITY = $(CONFIG_EXAMPLES_HELLO_PRIORITY)
STACKSIZE = $(CONFIG_EXAMPLES_HELLO_STACKSIZE)
MODULE = $(CONFIG_EXAMPLES_HELLO)
MAINSRC = hello_main.c
include $(APPDIR)/Application.mk
Makefile
엔 Kconfig
에서 선언한 변수를 빌드시 같이 붙여서 적용합니다. $(APPDIR)/Make.defs, $(APPDIR)/Application.mk
는 전역 make 설정과 매크로를 포함하는 구문이고 여기서 hello/Make.defs
를 포함하는데, CONFIG_EXAMPLES_HELLO
가 참이면 CONFIGURED_APPS += $(APPDIR)/examples/hello
를 정의하여 빌드할 앱에 자신을 추가합니다. 이후 PROGNAME
, PRIORITY
, STACKSIZE
로 각각 속성을 정의하고, OS 빌드시 포함 여부인 MODULE
(빌트인 | 모듈 | 미포함)와 앱의 주 진입점 소스파일인 MAINSRC
를 설정하는 구조입니다.
직접 앱 만들어보기
APP 경로 최상위에 직접 나만의 어플리케이션을 만들어봅니다. <APP 경로>/myapp
디렉터리를 추가해주시고 아래와 같은 내용의 파일 4개를 생성해주세요.
# myapp/Kconfig
config MY_APP
tristate "my app"
default n
---help---
Enable the my app
# myapp/Make.defs
ifneq ($(CONFIG_MY_APP),)
CONFIGURED_APPS += $(APPDIR)/myapp
endif
# myapp/Makefile
include $(APPDIR)/Make.defs
PROGNAME = myapp
PRIORITY = 100
STACKSIZE = CONFIG_DEFAULT_TASK_STACKSIZE
MODULE = $(CONFIG_MY_APP)
MAINSRC = my_app_main.c
include $(APPDIR)/Application.mk
// myapp/my_app_main.c
#include <nuttx/config.h>
#include <stdio.h>
int main(int argc, FAR char *argv[])
{
printf("Hello my app!!!\n");
return 0;
}
그리고 <APP 경로>/Kconfig
파일 마지막줄에 source "<APP 경로까지의 절대경로>/myapp/Kconfig"
을 추가해 우리 앱의 Kconfig 위치를 알려줍시다. 이제 터미널에서 OS 경로로 들어가 make menuconfig
를 실행하고 Application Configuration → my app
을 선택하고 y
키를 입력해 빌드 결과물에 포함시켜주고 <Save>
를 선택해서 저장하고 나오면 설정은 끝입니다. 이제 make
를 입력해 빌드하고 openocd를 이용해 플래시한후 nsh에서 확인하보면 우리의 앱이 추가된 것을 확인할 수 있습니다.
nsh> help
help usage: help [-v] [<cmd>]
. cd echo kill mount set uname
[ cp exec ls mv sleep umount
? cmp exit mb mw source unset
basename dirname false mkdir pwd test usleep
break date help mkrd rm time xd
cat dd hexdump mh rmdir true
Builtin Apps:
alarm hello myapp nsh ostest rand sh
nsh> myapp
Hello my app!!!