Stm32F103 + NuttX(四):自定义板级配置与应用
从本章起,系列文章都会配套开源代码
仓库链接:https://github.com/jklincn/nuttxspace
本章代码:https://github.com/jklincn/nuttxspace/tree/series/ch04
由于我手头不仅有一个开发板,还配备了一个 LCD 屏幕,以及自己购买了一个温湿度传感器以及一个 WIFI 模块,因此一个自定义的板级配置还是比较重要的,便于后续的开发。
新建板级配置
本文通过借鉴 stm32f103-minimum 的配置,自己写一个树外的板级配置文件夹,名字就叫做 atk-dnf103-v2 吧。这里需要先创建一个总的配置文件夹 myboard,然后再创建特定板的文件夹,最后的目录结构如下:
|
|
对比使用 myboard/atk-dnf103-v2/configs/nsh/defconfig 生成的与使用 stm32f103-minimum:nsh 生成的 .config 文件,只改动了部分关键配置(生成调试信息、芯片型号、板级型号、是否有 LED 和 按钮),其余配置保留不变。
|
|
这里不给具体的代码了,src 文件夹中所有的函数都可以是空实现,因为我们只做一个串口输出,这在内核初始化时会自动配置。主要是以下几个函数需要定义一下。
board_app_initializestm32_boardinitializestm32_bringup
重新配置一下
cmake -B build -DBOARD_CONFIG=../myboard/atk-dnf103-v2/configs/nsh -GNinja
编译烧录 ctrl+shift+B,切换回 Windows 串口界面,板子自动复位输出 NuttShell (NSH) NuttX-12.12.0,且一切正常,这说明当前配置已经可以正常运行 NuttX。
这里有个坑是不能依赖 menuconfig 的 Save minimal config,它输出的最小配置因为 Kconfig 配置原因无法在 out-of-tree 情况下加入 ARCH 等配置,需要手动添加。
但看起来
cmake --build build -t savedefconfig来生成最小配置是正常的。
自己编写 APP
我们之前的例程都是用 nuttx-apps 中的内容,即官方为我们准备的 APP。本节会开始自己编写一些在 nuttx 上运行的用户应用程序。
参考:Custom Apps How-to — NuttX latest documentation,但官网的教程用的是 makefile,本文使用的是 cmake,因此这个教程只能略微参考一下。
我们还是希望用 Outside of the Main Source Trees 的方式添加,以保持目录结构清晰。
创建 hello 应用
在根目录下创建 myapps 文件夹,链接到 apps 中。
mkdir myapps
cd apps/
ln -s ../myapps/ myapps
链接(看上去又不像是 oot 了)的作用有两个,
- 可以直接在
apps/CMakeLists.txt中添加目录 - 可以让
nuttx_generate_kconfig()自动生成 kconfig
先修改 apps/CMakeLists.txt,在 add_subdirectory(wireless) 后添加
add_subdirectory(myapps)
让整个 apps 构建系统知道我们的自定义应用。
然后在 myapps 下创建一个 CMakeLists.txt,其作用是包含了子目录以及在 menuconfig 中生成一个 My Apps 的菜单,用于我们选择要编译进固件的应用。
|
|
再创建 hello 文件夹,在其中创建
-
Kconfig:定义一个
MY_APPS_HELLOConfig,用来选择是否编译 hello 应用。config MY_APPS_HELLO tristate "Hello" default n ---help--- Enable the My Hello App -
CMakeLists.txt:这里用
CONFIG_MY_APPS_HELLO包裹nuttx_add_application,具体原因可以看下文的《坑:CMake 目标重复定义》1 2 3 4 5 6 7 8 9 10 11if(CONFIG_MY_APPS_HELLO) nuttx_add_application( NAME my_hello SRCS hello.c STACKSIZE 2048 PRIORITY 100) endif() -
hello.c:写个最简单的输出
1 2 3 4 5 6 7#include <stdio.h> int main(int argc, char *argv[]) { printf("Hello, world!\n"); return 0; }
总体的目录如下:
lin@future:~/nuttxspace$ tree myapps/
myapps/
├── CMakeLists.txt
└── hello
├── CMakeLists.txt
├── hello.c
└── Kconfig
手动加入 hello 应用
删除原有配置
cd nuttx
rm -rf build
先进行配置
cmake -B build -DBOARD_CONFIG=../myboard/atk-dnf103-v2/configs/nsh -GNinja
进入配置菜单
cmake --build build -t menuconfig
选择 Application Configuration -> My Apps -> Hello,空格选中,然后按 Q 退出,按 Y 选择保存退出。
可以在 nuttx/build/.config 中看到
#
# My Apps
#
CONFIG_MY_APPS_HELLO=y
# end of My Apps
之后就是编译、烧录、运行,不再重复,最后放一张截图
如果你想每一次配置后,hello 都自动勾选中,可以从以下方法二选一
在
myapps/hello/Kconfig中将MY_APPS_HELLO的 default 改成 y在
myboard/atk-dnf103-v2/configs/nsh/defconfig中加入CONFIG_MY_APPS_HELLO=y
坑:CMake 目标重复定义
起初写完后进行配置会报重复定义的错:
CMake Error at cmake/nuttx_add_application.cmake:155 (add_library):
add_library cannot create target "apps_my_hello" because another target
with the same name already exists. The existing target is a static library
created in source directory "/home/lin/nuttxspace/myapps/hello". See
documentation for policy CMP0002 for more details.
Call Stack (most recent call first):
/home/lin/nuttxspace/myapps/hello/CMakeLists.txt:28 (nuttx_add_application)
排查后发现,NuttX 的 CMake 会将 apps 目录添加两次。
第一次在 245 行,用于扫描所有应用并生成 Kconfig 菜单。在这个阶段,项目的 .config 配置还没有被加载到 CMake 中,因此所有的 CONFIG 变量此时都是未定义的,因此官方的 apps 此时都不会被添加。
|
|
第二次在 631 行,用于真正的 apps 添加。
|
|
因此在自定义的 app 中,需要采取方法来解决重复定义问题,这里采取和官方例程一样的做法,使用 CONFIG 来保护
|
|
加入 LED
目前的代码是最简单的,没有使用任何外设资源,只使用了 USART1 来做串口,下一步的想法是逐步加入更多的板级支持。
首先加一个 LED,这个之前我们做过,因此这边简单写一下。
修改板级配置
在 src/CMakeLists.txt 中加入 LED 支持,宏 CONFIG_USERLED 表示让用户自己管理 LED,而不是交给内核自动管理(对应宏 CONFIG_ARCH_LEDS)。
|
|
在 board.h 中加入 LED 的数量
|
|
在 atk-dnf103-v2.h 中定义两个 LED
|
|
在 stm32_userleds.c 中修改 g_ledcfg 数组与板级 LED 接口函数
|
|
在 stm32_bringup.c 中加入用户 LED 初始化代码
|
|
启用 LED 支持
在配置菜单中启用板级自定义 LED 控制,
- Board Selection -> Custom Board Configuration -> Custom board LEDs (选中)
- Board Selection -> Custom Board Configuration -> Board LED Status support(取消选中)
- Device Drivers -> LED Support -> LED driver(选中)
- Device Drivers -> LED Support -> Generic Lower Half LED Driver(选中)\
和原配置对比下来,主要是启用了 4 个配置。
CONFIG_BOARD_CUSTOM_LEDS=y
CONFIG_ARCH_HAVE_LEDS=y
CONFIG_USERLED=y
CONFIG_USERLED_LOWER=y
重新下板(指代配置、编译、烧录,后面的文章都会使用下板来代替这三步)后,可以在 /dev 下看到设备节点已经被创建了。
NuttShell (NSH) NuttX-12.12.0
nsh> ls /dev
/dev:
console
ttyS0
userleds
nsh>
创建 led 应用
由于我们刚刚已经学会了怎么创建自定义应用,因此我们这节就不使用原来的 apps/examples/leds 了,直接自己手写一个更简单一点的。
在 myapps 目录下创建 led 文件夹,分别创建以下文件
Kconfig
config MY_APPS_LED
tristate "LED"
default n
---help---
Enable the My LED App
CMakeLists.txt
if(CONFIG_MY_APPS_LED)
nuttx_add_application(
NAME
led
SRCS
led.c
STACKSIZE
2048
PRIORITY
100)
endif()
led.c
|
|
编写完代码后,还需要和之前一样在配置菜单中手动启用 LED 应用,最后上板测试
nsh>
NuttShell (NSH) NuttX-12.12.0
nsh> ?
help usage: help [-v] [<cmd>]
[ cp false mkdir sleep umount
? echo help mount test xd
cat exec hexdump pwd true
cd exit ls rm uname
Builtin Apps:
nsh sh led
nsh> led
Turning LEDs ON
nsh> led
Turning LEDs OFF
保存成新配置
最后,为了以后复现方便,这里用 cmake --build build -t savedefconfig 把 LED 的配置做了导出,保存到 myboard/atk-dnf103-v2/configs/led/defconfig。它是 nsh 的增量配置,后续就可以直接配置而无需重复修改 menuconfig。
本站不记录浏览量,但如果您觉得本内容有帮助,请点个小红心,让我知道您的喜欢。