# mcm-ddc-ble 开发日志 独立 BLE 工程:从 0x01000000 直接起跑(无 bootloader、无 OTA),用于在单镜像环境下 验证 BLE 功能与后续功能开发。 --- 日期:2026-09-02 ## 1. 工程创建(基于 SDK rdtss 例程) ### 1.1 选型 以 `nations-tec/N32WB03x_SDK_V2.0.0/projects/n32wb03x_EVAL/ble/rdtss` 为蓝本: BLE 原始数据透传服务(128-bit UUID,下行写 + 上行 notify),与 mcm-ddc-04 的自定义 GATT 透传服务(CLS)形态最接近,适合作为手机 APP 通信协议的载体。heart_rate 是标准 profile,不适合做数据通道。 ### 1.2 移植方式 - 整目录复制 `src/`、`inc/`、`MDK-ARM/` 到 `mcm-ddc-ble/`,工程改名 `mcm-ddc-ble`, 输出 `bin/mcm-ddc-ble.bin`。 - uvprojx/uvoptx 中 268+11 处 SDK 相对路径由 `..\..\..\..\..\` 重定向为 `..\..\nations-tec\N32WB03x_SDK_V2.0.0\`(新工程深度不同); 另有 11+3 处 `..\..\..\dfu\common` 指向 SDK 的 `projects/n32wb03x_EVAL/dfu/common`。 `nations-tec/` 只读,未做任何修改。 - 只使用第一个 target `N32WB03x`(IROM 0x01000000/0x40000);`OTA_IMG_1`/`OTA_IMG_2` 两个 target 未适配(其 after-build 脚本会写 SDK 目录),不要构建。 ### 1.3 引脚核对(重点:避开 SWD) - SWD 调试管脚:SWCLK=PA4 / SWDIO=PA5,全工程无任何占用。 - LED1=PB0、LED2=PA6(与 mcm-ddc-04、STB 板一致)。 - USART1 透传通道:TX=PB6 / RX=PB7(AF4,115200 8N1),与我们板子一致。 - 日志 LPUART:TX=PB1(NS_LOG)。 - `app_usart.h` 里的 PIN_4/PIN_5 是被注释掉的 USART2 备选(PB4/PB5),无影响。 ### 1.4 保 SWD:禁止睡眠 例程主循环会进 deep sleep,SWD 随之断开(readme 也提示需 RESET 时机烧录)。 在 `main.c` 主循环前调用 `ns_sleep_lock_acquire()` 永久锁睡眠,SWD 全程可调试; 代价是功耗偏高(仅调试阶段,后续做低功耗时再评估)。 ### 1.5 构建 `UV4 -b mcm-ddc-ble.uvprojx -t "N32WB03x"`:0 Error / 0 Warning, `Code=23340 RO-data=3352 RW-data=1876 ZI-data=6052`,bin 28224B。 --- 日期:2026-09-02 ## 2. 接入 FreeRTOS + 点灯任务 ### 2.1 内容 - 内核:SDK 自带 FreeRTOS V9(`middlewares/Third_Party/FreeRTOS`),工程新增 FREERTOS 组: `tasks/queue/list/timers.c` + `heap_4.c` + `port.c`(RVDS/ARM_CM0),只加进 `N32WB03x` target。 - `inc/FreeRTOSConfig.h`:从 mcm-ddc-04 移植,heap 缩为 **8KB**(本工程仅 3 个任务); SVC/PendSV/SysTick 由 port 接管(宏映射),本工程无 `n32wb03x_it.c`,无重复定义问题。 - `main.c` 任务化: - `ble_schedule_task`(512 字栈,优先级 2):`rwip_schedule()` + 1ms 延时, 替代裸机 while 循环(rwip 只允许单上下文运行)。 - `led_task`(128 字栈,优先级 1):LED1(PB0) 每 500ms 翻转做运行指示; LED2(PA6) 仍由 app_ble.c 驱动作连接状态指示。 - 睡眠保持锁定(deep sleep 与 RTOS tick 冲突,且保 SWD)。 - 串口透传路径为事件驱动(`usart_forward_to_ble_loop` 由 profile 回调触发、 `app_usart_tx_process` 由 BLE 消息处理触发),rwip_schedule 进任务后行为不变。 ### 2.2 踩坑记录 脚本往 uvprojx 写路径时 `\t` 被 Python 解释成制表符(`Source\tasks.c` → `Sourceasks.c`), Keil 报 `cannot create command input file 'source tasks.__i'`;另外 `` 必须写纯文件名 (带路径会被 Keil 当成对象名,同样报此错)。修正后全量重建通过。 ### 2.3 构建 0 Error / 0 Warning,`Code=24736 RO-data=3352 RW-data=1964 ZI-data=14484`; bin ≈ 27.4KB,RAM(RW+ZI)≈ 16.1KB / 48KB(含 8KB FreeRTOS heap)。 ### 2.4 上板预期 LED1 每 500ms 闪烁;手机可搜到并连接 `NS_RDTSS`,连接后 LED2 亮; 串口(PB6/PB7,115200)与手机 BLE 互发透传。 --- 日期:2026-09-02 ## 3. 重链接到 APP1(0x01008000)+ Boot 联合整包 - 为验证产线形态(Boot 跳转 → APP1),工程 IROM 从 0x01000000/0x40000 改为 **0x01008000/0x38000**(APP1 bank)。RAM 布局本来就是 SDK 的 0x20004000 起,无需动。 - 构建 target `N32WB03x` 0E0W(map:Load Region Base 0x01008000,Max 0x38000)。 - 打包:`python tools/merge_image.py mcm-ddc-ble/MDK-ARM/bin/mcm-ddc-ble.bin caiic_ble_full` → `tools/out/caiic_ble_full.{hex,bin}`(Boot 0x01000000 + 缺省 bootsetting 0x01004000 + 本工程 0x01008000)。烧录:`tools\flash_package.bat tools\out\caiic_ble_full.hex`。 - 若要恢复单跑(无 Boot):Keil Target 里 IROM1 改回 `0x01000000, 0x40000` 即可。 --- 日期:2026-09-02 ## 4. 从 mcm-ddc-04 搬迁 CLI 框架 + UART 驱动 mcm-ddc-04 在 Boot 跳转路径下仍有问题,以本工程为基座并入其成熟组件。 ### 4.1 搬入文件 - `bsp_usart.c/h`:USART1(PB6/PB7,115200 8N1)printf 重定向(polling TX)+ DMA TX (CH1)+ RXDNE 中断字节队列 + TX 互斥锁;新增 `bsp_usart_rx_inject()`(任务上下文注入 RX 队列,供 BLE 下行喂 CLI)。 - `cli_core.c/h`:命令表/分词/执行原样搬入;默认输出为**双通道**(UART DMA + BLE notify)。 命令集适配为 `help`/`version`/`sysinfo`/`led`;`log`(04 的主动打印系统)、`bankinfo` (依赖 OTA/dfu_layout)与 Ctrl+Z 未搬。 - `app_cli.c/h`:独立 CLI 任务(栈 1024 字,优先级 3),提示符 `caiic->`,Tab 补全、 上下键历史(8 条)、四种行结束符全保留;新增 `AppCli_InputBytes()` 接 BLE 下行。 - `ble_up.c/h`(新写):CLI 应答的 BLE notify 上行。ke_msg 只允许在 BLE 调度任务上下文 运行,因此 CLI 任务只入队(512B 环形缓冲,满则丢),`ble_up_poll()` 挂在 ble_schedule_task 里按 20B/包发送,`rdtss` ntf cfm 回调 `ble_up_on_cfm()` 节流续发。 - `n32wb03x_it.c`:USART1_IRQHandler 转发 + HardFault 异常栈帧打印(ARMv6-M 无 CFSR)。 - `app_version.h`:V1.00.01。 ### 4.2 拆除与改接 - 移除 `app_usart.c`(原透传 FIFO 方案)与 `ns_log_lpuart.c`(占用 `fputc`,与 bsp_usart 的 printf 重定向冲突;`NS_LOG_LPUART_ENABLE` 置 0,NS_LOG 变空操作)。 - rdtss 下行写特征 → `AppCli_InputBytes()`(原 `app_usart_tx_fifo_enter`); ntf cfm → `ble_up_on_cfm()`(原 `usart_forward_to_ble_loop`); `rdtss_send_notify` 的 `ble_sending` 引用随 app_usart 一并清除。 - app_ble.c:连接/断开不再开关 usart DMA(CLI 常开);`APP_CUSTS_TEST_EVT` 不再触发 usart 发送。 - main.c:新增 VTOR 预置(`0x80000000|0x01008000`,BLE init 前 USART1 RX 中断需要; BLE init 后 VTOR 归 0 不动)、启动 banner(版本/时钟/广播名)、`AppCli_Init()`。 - FreeRTOS heap 用 20KB(用户设定,保留):RW+ZI≈27.4KB / 48KB 窗口。 ### 4.3 踩坑:Keil 跨 target 同名组合并 从 target `N32WB03x` 的 USER 组删除 app_usart.c 后,构建仍把它编进链接——µVision 在 uvoptx 缺失/不同步时会把三个 target 的同名组文件清单合并。**解决办法:三个 target 的 条目全部删除**(OTA_IMG_1/2 反正不用)。验证方式:看 `Objects/*.lnp` 链接清单无残留。 ### 4.4 构建与产物 0E/0W:`Code=30536 RO-data=3504 RW-data=1960 ZI-data=26088`。 整包:`tools\out\caiic_ble_full.{hex,bin}`(68344B,APP1 35576B)。 ### 4.5 上板预期 串口(PB6/PB7,115200):banner + `caiic->`,`help`/`sysinfo`/`led 1 toggle` 可用。 BLE:手机连 `CAIIC-MCM-20260902`,使能 notify 后向写特征发 `help\r\n` 应收到底层应答。