Mbed OS 5的自定义开发板移植 - NRF51
嗯,真香,比Arduino不知高到哪里去了
前言
最开始看到Mbed OS5的时候没太在意,然而最近Nucleo买多了就变成了……
真香!
步骤
正好手头的BLE开发板就又开始痒痒,那就上咯
手头的NRF51开发板是微雪的NRF51822开发板,芯片型号为_AC,意即32KB SRAM+256KB Flash的型号。我们首先用Mbed CLI新建一个项目,起名叫nrf51_hello就好了。
mbed new nrf51_hello
会在当前目录创建工程目录,随便写一个main.cpp,包含main函数用来对付链接问题((
#include <mbed.h> DigitalOut led(LED1); int main() { while(true) { led = !led; wait(0.5); } }
嗯,点灯工程师。
于是我们来处理板子的问题。Mbed OS 5的大致结构如下
. ├── [3.5K] CONTRIBUTING.md ├── [ 254] DOXYGEN_FRONTPAGE.md ├── [ 73] Jenkinsfile ├── [8.9K] LICENSE ├── [2.5K] README.md ├── [4.0K] TESTS ├── [4.0K] TEST_APPS ├── [4.0K] UNITTESTS ├── [ 0] astyle-branch.out ├── [4.0K] cmsis ├── [4.0K] components ├── [4.0K] docs ├── [107K] doxyfile_options ├── [2.3K] doxygen_options.json ├── [4.0K] drivers ├── [4.0K] events ├── [4.0K] features ├── [4.0K] hal ├── [ 36K] logo.png ├── [2.9K] mbed.h ├── [4.0K] platform ├── [ 381] requirements.txt ├── [4.0K] rtos ├── [4.0K] targets └── [4.0K] tools 14 directories, 11 files
添加板子定义的时候,我们需要在如下几个部分添加相应的文件
targets/targets.json
targets.json记录了所有板子的型号和特性,也是Mbed CLI寻找编译对象的入口
我们在其中添加自己的板子信息(照着SoC差不多的板子抄过来即可)
diff --git a/targets/targets.json b/targets/targets.json index 3d0c2bdf5..1dc765096 100755 --- a/targets/targets.json +++ b/targets/targets.json @@ -2709,6 +2709,24 @@ "extra_labels_add": ["DELTA_DFCM_NNN50"], "macros_add": ["TARGET_DELTA_DFCM_NNN50"] }, + "WAVESHARE_NRF51822": { + "supported_form_factors": ["ARDUINO"], + "inherits": ["MCU_NRF51_32K_UNIFIED"], + "device_has": ["USTICKER", "LPTICKER", "ANALOGIN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE"], + "device_name": "nRF51822_xxAC" + }, + "WAVESHARE_NRF51822_BOOT": { + "supported_form_factors": ["ARDUINO"], + "inherits": ["MCU_NRF51_32K_BOOT"], + "extra_labels_add": ["WAVESHARE_NRF51822"], + "macros_add": ["TARGET_WAVESHARE_NRF51822"] + }, + "WAVESHARE_NRF51822_OTA": { + "supported_form_factors": ["ARDUINO"], + "inherits": ["MCU_NRF51_32K_OTA"], + "extra_labels_add": ["WAVESHARE_NRF51822"], + "macros_add": ["TARGET_WAVESHARE_NRF51822"] + }, "NRF51_DK_LEGACY": { "supported_form_factors": ["ARDUINO"], "inherits": ["MCU_NRF51_32K"],
可以看出我们的板子叫做 WAVESHARE_NRF51822
。
2. Target定义文件,上述的 inherits
已经给定了这个板子所属的厂商和型号,在对应目录里添加相应定义文件,包含引脚定义 PinNames.h
和设备定义 device.h
。根据板子的外设和引脚信息修改对应文件即可。我们正在添加的板子应位于
targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF51/TARGET_MCU_NRF51822_UNIFIED/TARGET_WAVESHARE_NRF51822
中。
*** ../TARGET_NRF51_DK/PinNames.h 2018-10-27 12:42:18.034690786 +0800 --- PinNames.h 2018-10-27 13:43:22.036980344 +0800 *************** *** 120,134 **** P0_29 = p29, P0_30 = p30, ! LED1 = p21, ! LED2 = p22, ! LED3 = p23, ! LED4 = p24, ! BUTTON1 = p17, ! BUTTON2 = p18, ! BUTTON3 = p19, ! BUTTON4 = p20, RX_PIN_NUMBER = p11, TX_PIN_NUMBER = p9, --- 120,132 ---- P0_29 = p29, P0_30 = p30, ! LED1 = p18, ! LED2 = p19, ! LED3 = p20, ! LED4 = p21, ! BUTTON1 = p16, ! BUTTON2 = p17, RX_PIN_NUMBER = p11, TX_PIN_NUMBER = p9,
本例中 device.h
无需修改。
添加完板子定义我们来简单测试一下
imi415@imi415 ..ts/Hardwares/Mbed_Projects/nrf51_hello (git)-[master] % mbed compile -m WAVESHARE_NRF51822 -t GCC_ARM -j8
...
Compile [ 99.5%]: gpio_api.c Compile [ 99.6%]: qspi_api.c Compile [ 99.7%]: port_api.c Compile [ 99.9%]: rtc_api.c Compile [100.0%]: us_ticker.c Link: nrf51_hello Elf2Bin: nrf51_hello | Module | .text | .data | .bss | |--------------------|------------|----------|----------| | [fill] | 171(+4) | 19(+0) | 55(+0) | | [lib]/c.a | 22739(+0) | 2472(+0) | 56(+0) | | [lib]/gcc.a | 7142(+0) | 0(+0) | 0(+0) | | [lib]/misc | 208(+0) | 12(+0) | 25(+0) | | [lib]/stdc++.a | 1(+0) | 0(+0) | 0(+0) | | main.o | 2229(+7) | 5(+0) | 97(+0) | | mbed-os/components | 54(+0) | 0(+0) | 0(+0) | | mbed-os/drivers | 787(+16) | 0(+0) | 0(+0) | | mbed-os/events | 1240(+0) | 0(+0) | 0(+0) | | mbed-os/features | 40015(+6) | 4(+0) | 1334(+0) | | mbed-os/hal | 1758(-2) | 8(+0) | 130(+0) | | mbed-os/platform | 3898(-4) | 260(+0) | 221(+0) | | mbed-os/rtos | 10287(-2) | 168(+0) | 6113(+0) | | mbed-os/targets | 9281(-3) | 20(+0) | 865(+0) | | Subtotals | 99810(+22) | 2968(+0) | 8896(+0) | Total Static RAM memory (data + bss): 11864(+0) bytes Total Flash memory (text + data): 102778(+22) bytes Image: ./BUILD/WAVESHARE_NRF51822/GCC_ARM/nrf51_hello.hex mbed compile -m WAVESHARE_NRF51822 -t GCC_ARM -j8 146.18s user 37.11s system 536% cpu 34.191 total imi415@imi415 ..ts/Hardwares/Mbed_Projects/nrf51_hello (git)-[master] %
我们就可以在生成目录 BUILD/
下找到ELF和IHEX文件了。
NRF51需要一个闭源静态库用来实现驱动和蓝牙,Nordic管他叫SoftDevice。我们首先需要下载SoftDevice到设备。
本例中依然使用OpenOCD,调试器使用LPC11U35开发板运行DAPLink(CMSIS-DAP)固件,制作方法后述。
运行
openocd -f /usr/share/openocd/scripts/interface/cmsis-dap.cfg -f /usr/share/openocd/scripts/target/nrf51.cfg
Open On-Chip Debugger 0.10.0+dev-00523-g2a3b709aa (2018-08-30-22:25) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'. cortex_m reset_config sysresetreq adapter speed: 1000 kHz Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections Info : CMSIS-DAP: SWD Supported Info : CMSIS-DAP: FW Version = 1.10 Info : CMSIS-DAP: Interface Initialised (SWD) Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1 Info : CMSIS-DAP: Interface ready Info : clock speed 1000 kHz Info : SWD DPIDR 0x0bb11477 Info : nrf51.cpu: hardware has 4 breakpoints, 2 watchpoints Info : Listening on port 3333 for gdb connections
一如既往,显示连接成功。
运行 telnet localhost 4444
连接到OpenOCD的CLI界面,运行
reset init
halt CPU,接着运行
flash write_image erase /path/to/softdevice/s130.hex
下载SoftDevice到设备。
最后运行
flash write_image erase /path/to/nrf51_hello.elf
下载应用程序到设备,执行 reset
即可点灯成功(
おまけ
P.S. NRF51822 的串口默认流控,请确认CTS/RTS pin连接正常,否则串口会卡死目标板。
我们来运行一下Mbed OS的心率传感器示例
由于之前已经下载过SoftDevice,本次无需重新下载。直接下载应用程序到设备即可。
通过Nordic的BLE App,就可以看到心率了…… 170了,我要挂了.jpg