MicroPython nRF 移植版完全指南:从 nRF51 到 nRF9160 的编译、烧录与 BLE 开发

📅 发布时间:2026/9/21 23:07:12
MicroPython nRF 移植版完全指南:从 nRF51 到 nRF9160 的编译、烧录与 BLE 开发
MicroPython nRF 移植版完全指南从 nRF51 到 nRF9160 的编译、烧录与 BLE 开发【免费下载链接】micropythonMicroPython - a lean and efficient Python implementation for microcontrollers and constrained systems项目地址: https://gitcode.com/gh_mirrors/mi/micropythonMicroPython 官方仓库micropython中的ports/nrf移植版port将 MicroPython 运行时带到了 Nordic Semiconductor 的 nRF 系列芯片上覆盖 nRF51如 micro:bit、nRF52832、nRF52840 以及蜂窝网络芯片 nRF9160。本文基于 ports/nrf/README.md 并结合该移植版源码系统讲解支持的功能特性、板卡选择、编译烧录流程、SoftDevice 蓝牙协议栈集成、文件系统VFS配置、BLE REPL 与引脚编号规则帮助你在真实 nRF 硬件上完成从构建到运行的完整闭环。一、移植版概览与支持的功能特性ports/nrf是 MicroPython 对 Nordic nRF 系列芯片的官方移植其目标是在资源受限的 MCU 上运行精简的 Python 运行时。README 中列出的核心功能包括UART串口通信与 REPL 支持SPI串行外设接口LED与Pin引脚GPIO 控制ADC模数转换I2CPWM仅 nRF52 系列支持硬件 PWMTemperature温度读取片上温度传感器RTCReal Time Counter低功耗计数器BLE 支持包括nRF51 目标上的Peripheral外设角色nRF52 目标上的Central主机和 Peripheral 角色通过 BLE 提供 REPL可选使用 WebBluetoothubluepy面向 MicroPython 的 BLE 模块连接建立后仍可运行1 个不可连接的广播advertiser。从源码结构可以印证这些功能的实现位置。在 ports/nrf/modules/machine 目录下分别有uart.c、spi.c、pin.c、adc.c、i2c.c、pwm.c、rtcounter.c、temp.c、timer.c、soft_pwm.c等模块实现BLE 相关代码位于 ports/nrf/modules/blemodble.c和 ports/nrf/modules/ubluepymachine模块入口则定义在 ports/nrf/modules/machine/modmachine.c。此外ports/nrf/mpconfigport.h 中为不同芯片设置了不同的功能等级MICROPY_CONFIG_ROM_LEVELnRF51822 在启用 SoftDevice 时使用MICROPY_CONFIG_ROM_LEVEL_MINIMUM因为协议栈占用闪存和 RAM否则为CORE_FEATURESnRF52832 为BASIC_FEATURESnRF52840 与 nRF9160 为EXTRA_FEATURES。这解释了为什么不同芯片上可用的 Python 功能集不同——资源越多ROM 等级越高。二、已测试硬件与板卡支持矩阵已测试的芯片与开发板README 记录了经过验证的硬件平台nRF51 系列micro:bitPCA10000donglePCA10001PCA10028PCA10031dongleWT51822-S4ATnRF52832PCA10040Adafruit Feather nRF52Thingy:52Arduino PrimoIBK-BLYST-NANObreakout 板BLUEIO-TAG-EVIM BLYST Nano Sensor 板uBlox EVK-NINA-B1nRF52840PCA10056PCA10059dongleParticle XenonnRF52840 MDK USB Dongle详见 boards/NRF52840_MDK_USB_DONGLE/README.mdnRF9160PCA10090nRF9160-DKActinius Icarus板卡BOARD、协议栈与烧录工具对照表下表是 README 提供的官方板卡支持矩阵包含默认的 SoftDeviceSD、BLE 支持角色、Bootloader 以及默认烧录工具Target BoardBOARD蓝牙协议栈SD蓝牙支持Bootloader默认烧录工具MICROBITs110PeripheralPyOCDPCA10000s110PeripheralSeggerPCA10001s110PeripheralSeggerPCA10028s110PeripheralSeggerPCA10031s110PeripheralSeggerWT51822_S4ATs110Peripheral手动见数据手册引脚图PCA10040s132Peripheral 与 CentralSeggerFEATHER52s132Peripheral 与 Central手动板底 SWDIO/SWCLK 焊点ARDUINO_PRIMOs132Peripheral 与 CentralPyOCDIBK_BLYST_NANOs132Peripheral 与 CentralIDAPIDK_BLYST_NANOs132Peripheral 与 CentralIDAPBLUEIO_TAG_EVIMs132Peripheral 与 CentralIDAPEVK_NINA_B1s132Peripheral 与 CentralSeggerPCA10056s140Peripheral 与 CentralSeggerPCA10059s140Peripheral 与 CentralOpenBootloadernrfutilPARTICLE_XENONs140Peripheral 与 CentralBlack Magic ProbeNRF52840_MDK_USB_DONGLEs140Peripheral 与 CentralOpenBootloadernrfutilPCA10090无bsdlib.a无LTE/GNSSSeggerACTINIUS_ICARUS无bsdlib.a无LTE/GNSSSegger注nRF9160PCA10090、ACTINIUS_ICARUS不运行 BLE 协议栈而是使用bsdlib.aNordic 的 BSD 库提供LTE/GNSS蜂窝通信能力因此表中“蓝牙支持”为“无”。当前仓库ports/nrf/boards/目录下实际包含的板卡还包括ARDUINO_NANO_33_BLE_SENSE、DVK_BL652、EVK_NINA_B3、SEEED_XIAO_NRF52等比 README 表格所列更多。以 PCA10040 为例其 mpconfigboard.mk 定义了MCU_SERIES m4 MCU_VARIANT nrf52 MCU_SUB_VARIANT nrf52832 SOFTDEV_VERSION 6.1.1 LD_FILES boards/nrf52832_512k_64k.ld NRF_DEFINES -DNRF52832_XXAA MICROPY_VFS_LFS2 1可以看出板卡配置由MCU_SERIES/MCU_VARIANT/MCU_SUB_VARIANT决定芯片型号SOFTDEV_VERSION决定 SoftDevice 版本LD_FILES指定链接脚本MICROPY_VFS_LFS2默认启用 littlefs v2 文件系统。三、编译与烧录从零开始构建 nRF 固件前置准备构建 nRF 移植版需要先克隆仓库并构建mpy-cross交叉编译器git clone URL.git micropython cd micropython make -C mpy-crossmpy-cross用于在编译期把 Python 源码预编译为.mpy字节码是冻结模块frozen modules的基础。默认目标板为PCA10040nRF52832这一默认值定义在 ports/nrf/Makefile 的第 8 行BOARD ? PCA10040。构建并烧录默认板进入ports/nrf/目录后执行make submodules make make deploy其中make submodules拉取lib/CMSIS_6、lib/nrfx、lib/tinyusb等 Git 子模块见 ports/nrf/Makefile 中GIT_SUBMODULES lib/CMSIS_6 lib/nrfx lib/tinyusbmake编译固件默认生成build-PCA10040/firmware.hex与.binmake deploy调用默认烧录器默认FLASHER ? jlink即 Segger JLink nrfjprog烧录固件。指定其他板卡make submodules make BOARDPCA10040 make BOARDPCA10040 deployBOARD变量会被映射到ports/nrf/boards/$(BOARD)目录见 ports/nrf/Makefile如果目录不存在会直接报错Invalid BOARD specified。构建产物目录名会随板卡变化build-$(BOARD)若指定了SD则为build-$(BOARD)-$(SD_LOWER)。关闭 LTO 编译为节省空间nRF 移植版在所有目标上默认启用LTO链接时优化通过-flto链接器标志实现见 ports/nrf/Makefile 中LTO ? 1及CFLAGS -flto。可以通过LTO参数关闭make BOARDPCA10040 LTO0当LTO0时Makefile 会改用-ffunction-sections -fdata-sections与-Wl,--gc-sections来去除未使用代码段。重要提示GNU ARM Embedded Toolchain 7.2.1/4Q17 与 LTO 组合曾出现多个问题建议使用该版本之后的工具链如 7.3.1/2Q18 或 8.2.1/4Q18或者按上述方式以LTO0构建。这也与 ports/nrf/Makefile 中$(PY_BUILD)/nlr%.o: CFLAGS -Os -fno-lto的特殊处理相互印证——NLR非本地跳转相关目标文件即使在 LTO 开启时也单独禁用 LTO以避免长跳转代码被优化破坏。芯片平台差异编译器前缀为arm-none-eabi-CROSS_COMPILE ? arm-none-eabi-nRF51Cortex-M0使用-mfloat-abisoft软浮点nRF52Cortex-M4使用-mfpufpv4-sp-d16 -mfloat-abihardnRF9160Cortex-M33使用-mcpucortex-m33 -marcharmv8-m.maindsp -mcmse见 ports/nrf/Makefile 中CFLAGS_MCU_m0/m4/m33nRF51822 还需在 ports/nrf/mpconfigport.h 中启用MICROPY_NLR_THUMB_USE_LONG_JUMP因为 Thumb-1 指令集在 LTO 下 NLR 跳转距离不确定nRF51 不支持浮点MICROPY_FLOAT_IMPL_NONEnRF52/nRF9160 使用MICROPY_FLOAT_IMPL_FLOAT。四、集成 Bluetooth StackSoftDevice的编译与烧录BLE 功能依赖 Nordic 的 SoftDevice 协议栈。首先下载对应协议栈与头文件./drivers/bluetooth/download_ble_stack.sh下载完成后编译时通过SD参数指定协议栈make BOARDPCA10040 SDs132烧录协议栈使用sd目标make BOARDPCA10040 SDs132 sd注意make sd会对芯片执行全片擦除nrfjprog --eraseall这可能同时抹掉第三方 bootloader。若板卡带 OpenBootloader如 PCA10059、NRF52840_MDK_USB_DONGLE协议栈与应用的烧录顺序由 nrfutil DFU 流程处理。从 ports/nrf/Makefile 的sd目标可以看到其烧录序列--eraseall全擦 → 烧录$(SOFTDEV_HEX)→ 烧录应用 → 复位。指定SD后链接脚本会自动追加boards/$(SD_LOWER)_$(SOFTDEV_VERSION).ld如s132_6.1.1.ld并引入drivers/bluetooth/bluetooth_common.mk以链接协议栈头文件。SOFTDEV_VERSION在各板卡mpconfigboard.mk中定义PCA10040/PCA10056 均为 6.1.1仓库ports/nrf/boards/下提供了s110_8.0.0.ld、s132_6.1.1.ld、s140_6.1.1.ld、s140_7.3.0.ld等链接脚本。关于 BLE 特性的进一步调优如 BLE REPL 等可通过编辑 ports/nrf/bluetooth_conf.h 实现。该文件按协议栈类型定义蓝牙功能开关BLUETOOTH_SD 110s110启用MICROPY_PY_BLE、MICROPY_PY_UBLUEPY、MICROPY_PY_UBLUEPY_PERIPHERALBLUETOOTH_WEBBLUETOOTH_REPL为 0BLUETOOTH_SD 132/140s132/s140额外启用MICROPY_PY_UBLUEPY_CENTRALCentral 角色。这正与 README 所述“nRF51 仅 Peripheral 角色、nRF52 支持 Peripheral 与 Central”对应。而MICROPY_PY_BLE_NUSNordic UART Service默认定义为0需要手动开启。五、冻结 manifestFreeze Manifest冻结freeze可以将 Python 源码或.mpy字节码编译进固件避免运行时从文件系统导入。通过FROZEN_MANIFEST指定一个manifest.py即可方式一make 命令行传入make BOARDPCA10040 FROZEN_MANIFESTpath/to/manifest.py方式二在板卡 makefile 中定义在具体板卡的mpconfigboard.mk中添加FROZEN_MANIFEST ? $(BOARD_DIR)/manifest.py两种方式同时存在时手动 make 命令行传入的值优先级更高因为?只在变量未定义时生效。实际上ports/nrf/Makefile 已根据MICROPY_PY_ASYNCIO自动选择 manifest启用 asyncio 时使用boards/manifest.py否则使用boards/manifest_minimal.py对应 boards/manifest.py 与 boards/manifest_minimal.py并且 nRF 移植版默认开启 asyncioMICROPY_PY_ASYNCIO ? 1。同时该移植版还包含freeze/目录与modules/scripts/_boot.py等可冻结内容。六、启用文件系统FATFS 与 littlefsVFSnRF 移植版支持多种片内文件系统。由于oofatfs模块没有可排除实现编译的头文件保护移植版提供了显式开关MICROPY_VFS_FAT默认值为 0需要显式设为 1 才会编译 FATFS 相关代码并且还需要在mpconfigport.h中设置MICROPY_VFSmake BOARDPCA10040 MICROPY_VFS_FAT1启用 FATFS 后ports/nrf/Makefile 会额外编译lib/oofatfs/ff.c与lib/oofatfs/ffunicode.c并配合 ports/nrf/fatfs_port.c 提供磁盘 I/O。启用 littlefsLFS1/LFS2若要使用 littlefs 作为片内闪存文件系统可设置MICROPY_VFS_LFS1或MICROPY_VFS_LFS2同样需要配合在mpconfigport.h或mpconfigboard.h中设置MICROPY_VFSmake BOARDPCA10056 MICROPY_VFS_LFS21从板卡配置看PCA10040 与 PCA10056 的mpconfigboard.mk中均已默认MICROPY_VFS_LFS2 1而mpconfigport.h中MICROPY_VFS默认按功能等级开启CORE_FEATMICROPY_MBFSmicro:bit 文件系统则在未启用 VFS 时自动启用。调整文件系统大小FS_SIZE文件系统在片内闪存中的大小由链接脚本参数_fs_size控制默认值为64K见 ports/nrf/boards/memory.ld 第 12 行。可以通过 makefile 的FS_SIZE动态覆盖make BOARDPCA10056 MICROPY_VFS_LFS21 FS_SIZE256KFS_SIZE的值会原样传给链接器-Wl,--defsym_fs_size$(FS_SIZE)因此必须使用链接脚本语法如256K。该值参与计算 Flash 布局_app_size _flash_size - _head_size - romfs - _fs_size - _bootloader_tail_size文件系统区域从_fs_start延伸到_fs_end。风险提示改变FS_SIZE会导致文件系统起始位置变化下次启动时固件会因位置变化而重新格式化文件系统可能丢失上一次固件中已有的文件。七、不同烧录工具Flash Util的部署方式除默认的 SeggerJLink nrfjprog外移植版支持多种烧录后端见 ports/nrf/Makefile 中FLASHER ? jlink及各个分支。README 对应给出了各工具的安装与使用说明IDAP-M/IDAP-Link 目标IBK_BLYST_NANO 等下载安装 IDAPnRFProgLinux/OSX/Windows 版本该工具通过 CMSIS-DAP 调试器烧录。Makefile 中对应FLASHERidap命令为IDAPnRFPRog hex。Segger 目标PCA10040、PCA10056 等安装 JLink 与 nrfjprog。Linux 下可能需要将 SEGGER 的libjlinkarm.so链接到 nrfjprog 的目录中。这是 nRF 移植版的默认烧录方式。PyOCD/OpenOCD 目标MICROBIT、ARDUINO_PRIMO 等sudo apt-get install openocd sudo pip install pyOCDMakefile 中对应FLASHERpyocd使用pyocd-flashtool与FLASHERopenocd使用openocd CMSIS-DAP 接口配置nRF51/nRF52 均使用target/nrf52.cfg。Black Magic Probe 目标PARTICLE_XENON仅需arm-none-eabi-gdb。make deploy会通过 GDB 加载并运行新固件对应FLASHERbmp使用target extended-remote连接 BMP 端口默认/dev/ttyACM0。nRFUtil 目标PCA10059、NRF52840_MDK_USB_DONGLE首先安装 Nordic 的nrfutilCLI然后安装 SDK 子包以获取pkg与dfu命令nrfutil install nrf5sdk-tools再安装 Python 依赖sudo pip install intelhexintelhex提供hexmerge.py工具Makefile 使用它对 SoftDevice 镜像做 MBR 裁剪--range0x1000:跳过 MBR 保护区。使用nrfutil作为烧录后端时除deploy目标外还必须指定串口参数make BOARDNRF52840_MDK_USB_DONGLE NRFUTIL_PORT/dev/ttyACM0 deploy若设备连接在默认串口/dev/ttyACM0则NRFUTIL_PORT可以省略Makefile 默认值。启用 BLE 时与其他烧录工具一样首次固件更新需要先烧录 SoftDevice使用sd目标而非deploymake BOARDNRF52840_MDK_USB_DONGLE SDs140 NRFUTIL_PORT/dev/ttyACM0 sdnrfutil 的sd流程会生成两个 DFU 包stripped_sd.zip裁剪 MBR 后的 SoftDevice与xxx_dfu.zip应用然后依次通过 USB 串口 DFU 推送。注意nRF52840 MDK USB Dongle 的 SoftDevice 请求标识为0xB6见 Makefile 中ifeq ($(SD), s140) NRFUTIL_SD_REQ 0xB6。八、Bluetooth LE REPL通过 BLE 使用交互式解释器该移植版实现了BLE REPL 驱动。此功能默认关闭因为启用后会停用 UART REPLnRF 部分器件只有一个 UART使用 BLE REPL 可以把 UART 释放出来当作普通外设使用。启用方式编辑 ports/nrf/bluetooth_conf.h将MICROPY_PY_BLE_NUS设为 1即 Nordic UART Service 的 REPL 通道。这与mpconfigport.h中MICROPY_HW_ENABLE_UART_REPL的默认逻辑呼应当MICROPY_PY_BLE_NUS或MICROPY_HW_USB_CDC启用时UART REPL 自动关闭。启用后可选择的测试工具NUS Console for Linux推荐命令行下连接 BLE NUS 服务WebBluetooth REPL实验性浏览器内连接。此外手机/平板可安装 nRF UART 应用连接。WebBluetooth 模式还可以进一步配置在bluetooth_conf.h中设置BLUETOOTH_WEBBLUETOOTH_REPL为 1。此时设备会在Eddystone URL 广播与普通可连接广播之间交替Eddystone URL 引导手机或电脑浏览器打开 WebBluetooth REPL 页面随后即可通过浏览器连接 BLE REPL。注意bluetooth_conf.h中 s110/s132/s140 三种协议栈的BLUETOOTH_WEBBLUETOOTH_REPL默认值均为 0需要手动开启。九、nRF52840 板卡的引脚编号规则对于 nRF52840 系列板卡软件引脚编号与物理引脚存在固定映射软件 Pin 0–31 对应物理引脚 0.xP0.00–P0.31软件 Pin 32–47 对应物理引脚 1.xP1.00–P1.15。例如在 PCA10059 上Pin(47)对应物理引脚1.15。这一规则的落地体现在板卡引脚生成机制中Makefile 通过 boards/make-pins.py 读取板卡的pins.csv、芯片的nrf52_af.csv及nrf52_prefix.c生成build/pins_gen.c与build/pins.h见 ports/nrf/Makefile 中MAKE_PINS/BOARD_PINS/AF_FILE/PREFIX_FILE定义。以 PCA10056 的 mpconfigboard.h 为例LED1–LED4 分别映射到引脚 13/14/15/16SPI0 的 SCK/MOSI/MISO 为 47/45/46UART1 的 RX/TX/CTS/RTS 为 8/6/7/5且启用硬件流控MICROPY_HW_UART1_HWFC (1)这些数字均遵循上述软件引脚编号规则。十、构建产物与固件目标ports/nrf/Makefile 定义了两个主要产物目标binary生成firmware.binobjcopy -O binaryhex生成firmware.hexobjcopy -O ihex这是deploy/sd烧录使用的格式。nRF91 平台的all目标还会额外构建secureboot因为 nRF9160 使用带 TrustZone 的 Cortex-M33需要安全启动镜像对应 drivers/secureboot/secureboot.mk。同时ports/nrf/mpconfigport.h 显示 nRF9160 未启用MICROPY_PY_MACHINE_MEM_BACKUP因为其POWER-GPREGRET为数组且涉及安全/非安全外设划分这也再次体现了不同芯片在移植版中的差异化处理。结语通过本文可以完成 nRF 移植版的完整开发闭环根据硬件选型nRF51/nRF52/nRF9160选择合适的BOARD与SD协议栈参数执行make submodules make make deploy或sd构建烧录需要文件系统时按需开启MICROPY_VFS_FAT/MICROPY_VFS_LFS2并用FS_SIZE调整分区大小想通过蓝牙调试时启用MICROPY_PY_BLE_NUS的 BLE REPL。深入阅读 ports/nrf/Makefile、ports/nrf/mpconfigport.h 与 ports/nrf/bluetooth_conf.h 等源码文件可以进一步掌握每个构建开关背后的底层实现为定制自己的 nRF 板卡固件打下基础。【免费下载链接】micropythonMicroPython - a lean and efficient Python implementation for microcontrollers and constrained systems项目地址: https://gitcode.com/gh_mirrors/mi/micropython创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考