mothercup/AGENTS.md
evan.liu 8a7cebcf77 V1.00.26: UART baud 115200 -> 460800
- firmware BSP_USART_BAUDRATE 460800 (divider error +0.03%); uartrst/
  uartinfo follow the macro
- RX DMA ring 2KB -> 3KB: at 460800 2KB only covers 44ms, less than the
  ~45ms flash-erase interrupt-off window; stack top now 0x2000BDE8
  (guard warns <1KB from the 0x2000C000 cliff, by design)
- tools: ble_ota_update.py UartTransport and uart_cap.py default baud
- Verified: stream OTA 55832B in 2.6s @23kB/s (one lost frame recovered
  by go-back-N), PASS after reboot; text CLI fine at 460800
- docs: ble_protocol.md, design spec, AGENTS.md, dev log section 48
2026-09-05 10:01:23 +08:00

22 KiB
Raw Blame History

AGENTS.md

项目概述

本仓库是 mothercup(母乳杯) 产品的完整代码仓库,包含三大部分:

  1. 设备固件 — 基于国民技术(Nations)N32WB031 BLE SoC(Cortex-M0,64MHz HSI,板载硅片实测 256KB Flash(0x01000000~0x0103FFFF,开发日志 §37),RAM 48KB+16KB):
    • mcm-ddc-ble/ — 唯一活跃的应用固件工程(APP,链接在 APP1 bank 0x01008000/112KB)。以 SDK rdtss 例程为蓝本,集成 FreeRTOS、UART CLI、BLE 自定义 GATT 服务(CLI 透传 / 设备信息查询 / BLE OTA 双 bank 直写升级)、bootsetting 与 APP_DATA 参数区结构化读写命令。当前版本 V1.00.26(mcm-ddc-ble/inc/app_version.h)。历史上曾有 mcm-ddc-04/ 主工程,已删除,其功能已全部并入本工程。
    • Boot/ — 自写精简 bootloader(链接在 0x01000000/16KB):校验 bootsetting 记录自身完整性(magic + 结构体 CRC32)后按 active bank 的 start_address 直接跳转;不校验镜像 CRC(CRC 校验在 OTA 升级过程中完成);记录无效或地址越界回退 APP1。
  2. 手机 App SmartAssiter/ — uni-app Vue3 + TypeScript 工程(HBuilderX 项目管理,无 package.json),通过 BLE 连接设备:查看运行参数(温度/电压/转速/bank/堆等)、CLI 终端、参数读写(appget/appset)、OTA 升级页(e0005 锁步,已恢复)。另有登录/注册/用户信息等云端业务页面。
  3. PC 工具 tools/ — 整片烧录包制作/烧录脚本 + bleak 蓝牙测试客户端。

关键文档:

  • docs/开发日志.md — 固件全程开发日志(45 节,含所有踩坑根因与设计决策,排查问题先查这里)
  • docs/ble_protocol.md — CAIIC BLE 通信协议 V1.1(帧格式/GATT UUID/三类业务流程/维护命令/手机端开发指南)
  • SmartAssiter/docs/修改记录_*.md — App 侧每次改造的详细记录

仓库顶层结构

mothercup/
├── mcm-ddc-ble/     # 应用固件工程(src/ inc/ MDK-ARM/)
├── Boot/            # bootloader 工程(src/ + MDK-ARM/caiic_boot.uvprojx)
├── SmartAssiter/    # 手机 App(uni-app vue3,HBuilderX 工程)
├── tools/           # merge_image.py / make_package.bat / flash_package.bat / ble_cli_test.py 等
├── docs/            # 开发日志.md + ble_protocol.md(仓库级权威文档)
├── nations-tec/     # 厂商资源:SDK V2.0.0、DFP 器件包、STB 开发板资料、官方 PDF。**只读,不要修改**
└── tools/out/       # 出包产物(mothercup_ble_prod.{hex,bin} 生产整包 + mothercup_ble_ota.bin 单文件升级包 + 调试用 _ota.bin/_ota_app2.bin 及 json)

SDK 源码(固件库、CMSIS、FreeRTOS V9.0.0、BLE 协议栈/profile/ns_library、启动文件)通过相对路径 ..\..\nations-tec\N32WB03x_SDK_V2.0.0 被 uvprojx 引用,不复制进工程;Bootloader 共享代码(Boot/src/dfu_layout.h、boot_crc32.c)经 ..\..\Boot\src 被 APP 工程引用。因此各工程目录不能脱离仓库根单独移动。

Flash / RAM 布局(铁律)

板载硅片实测 256KB Flash(0x01000000~0x0103FFFF;曾按 512KB 规划,实测 0x01040000 起 CPU 读回绕、SWD fault,见开发日志 §37)。以下布局已按 256KB 重排(§38),双 bank 切换 appsw 实测通过。

Flash 布局(256KB,Boot/src/dfu_layout.h 为唯一权威定义;Boot/bootsetting/APP_DATA 保持 16/8/8KB,余下 224KB 均分双 bank):

区域 地址 大小
Bootloader 0x01000000 16KB
bootsetting 0x01004000 8KB(用 1 个 4KB 扇区,结构体见 dfu_layout.h)
APP_DATA 0x01006000 8KB(区头为 caiic_params_t 参数记录,见 app_params.h)
APP1 0x01008000 112KB(0x1C000)
APP2 0x01024000 112KB(0x1C000)
  • RAM 铁律:低 16KB(0x20000000~0x20003FFF)由芯片 ROM/BLE 子系统占用(rwip 堆描述符、patch 数组、中断中继表,由 ROM 启动代码预备),任何工程的 IRAM 执行区必须从 0x20004000 起(含 Boot 和任何小工具),否则 .data/.bss 初始化冲掉 ROM 数据,BLE init 必然 HardFault(实测根因,开发日志 §21)。顶部同样悬崖(实测 SWD 探明,§47):0x2000C000 起访问即 fault,APP 可用 SRAM 实为 32KB(0x20004000~0x2000BFFF)——IRAM 配置里的 0xC000(48KB)上限是虚的,栈顶 __initial_sp 必须 < 0x2000C000;merge_image.py 已加硬卡(出包时校验 bin 向量表首字,越线直接失败)。ZI 膨胀(加大缓冲/堆)把栈顶推过线会导致上电即 HardFault/Lockup(V1.00.24 的 2KB DMA ring 事故,heap 已降为 18KB 腾位)。注意:mcm-ddc-ble.uvprojx 里 <IRAM> 镜像元素显示 0x20000000 是过期显示值,实际生效的是 OCR_RVCT9=0x20004000/0xC000——以 Listings/mcm-ddc-ble.map 的 RW_IRAM1 (Exec base: 0x20004000) 为准。
  • VTOR:Cortex-M0 无 SCB->VTOR,用 PWR->VTOR_REG(bit31=EN|[30:0]=基址)。规则:BLE 初始化之前 VTOR 指向 APP 自身向量表(main 开头设 0x80000000|0x01008000,USART1 RX 中断需要);ns_ble_stack_init() 之后 VTOR 必须为 0,此后所有中断经芯片 ROM 跳板 + RAM 中继。绝对不要在 BLE init 后重设 VTOR(实测崩溃根因,开发日志 §18)。

固件工程(mcm-ddc-ble)

mcm-ddc-ble/
├── src/
│   ├── main.c            # 入口:VTOR 预置 → USART+banner → LED → app_ble_init → app_params_init
│   │                     #   → ns_sleep_lock_acquire(锁睡眠保 SWD) → 建 BLE 调度/LED/CLI 任务 → vTaskStartScheduler
│   ├── bsp_usart.c       # USART1(PB6/PB7, 460800 8N1, V1.00.26 起):fputc 重定向 + DMA TX(CH1) + RX DMA 循环环形缓冲(CH2, 3KB, IDLE 中断唤醒;擦扇区关中断期间不丢字节) + TX 互斥锁
│   ├── app_gpio.c        # LED1(PB0)/LED2(PA6)
│   ├── app_cli.c         # CLI UART 前端:CliTask 行接收/编辑/历史/Tab/Ctrl+Z,提示符 caiic->
│   ├── cli_core.c        # CLI 核心(命令表 s_cmds[]/handler/分词执行),输出经可切换 cli_out_fn
│   │                     #   命令:help / version / sysinfo / devinfo / blelog / led / appget / appset /
│   │                     #   bsdump / bsset / appsw / reset / factory / uartrst / uartinfo
│   ├── app_ble.c         # BLE 栈初始化/广播(名 CAIIC-MCM-20260902)/连接事件 + BLE 调度任务
│   ├── app_ble_proto.c   # 0xCA 帧协议:字节流重组、CLI_REQ/RSP、INFO_QUERY/RSP、OTA 帧分发、
│   │                     #   CLI 读写特征(...e0003) 与只读参数特征(...e0004) 的执行/应答
│   ├── app_info.c        # 设备信息:ADC 芯片温度(CH7)/电压(CH6)、运行时长、堆剩余;风扇 weak 数据源
│   ├── app_ota.c         # BLE OTA:双 bank 直写(惰性擦扇区,仅 4B 对齐暂存)+ CRC32 校验 + bootsetting 更新 + 复位
│   ├── app_params.c      # APP_DATA 参数记录(caiic_params_t,magic+CRC)+ appget/appset 命令(led/pwm)
│   ├── app_bootset.c     # bootsetting 结构化读写 bsdump/bsset + appsw 切 bank(自动重算 CRC,防裸写变砖;
│   │                     #   appsw 切前复算目标镜像 CRC32)
│   ├── ble_up.c          # CLI 应答的 BLE notify 上行(ke_msg 上下文约束:环形缓冲 + BLE 任务内发送)
│   ├── n32wb03x_it.c     # 异常处理(HardFault 栈帧打印)+ USART1_IRQHandler 转发
│   ├── app_usart.c       # 遗留文件,已不在工程中编译(rdtss 原透传 FIFO,勿使用)
│   ├── infra/            # vendored cJSON v1.7.18(MIT)+ infra_cjson.c(分配挂 pvPortMalloc,
│   │                     #   惰性初始化);供参数接口 JSON 化等使用,MicroLIB 下整数走 %d 快路径
│   └── app_profile/      # app_rdtss.c(GATT 服务实现,读请求按 att_idx 分发 CLI_VAL/INFO_VAL)等
├── inc/                  # 对应头文件 + FreeRTOSConfig.h(heap 20KB)+ app_user_config.h(广播名/连接参数)
└── MDK-ARM/              # mcm-ddc-ble.uvprojx(target "N32WB03x" 为活跃 target,链接 APP1;
                          #   target "APP2" 为同源码链接 0x01024000 的 APP2 bank 构建(同版本),
                          #   供 make_dual_package.bat 出双 APP 整包;OTA_IMG_1/2 是 rdtss 遗产,保留不用)、
                          #   Objects/、Objects-app2/、bin/、Listings/、Listings-app2/

工程配置:器件 N32WB031KEQ6-2(实际硅片 256KB),IROM 0x01008000/0x1C000(APP1),IRAM 0x20004000/0xC000,MicroLIB,全局宏 N32WB03X, USE_STDPERIPH_DRIVER;链接器 Misc 附加 BLE ROM 符号表 symbol_g15.obj(SDK middlewares/Nationstech/ble_library/ns_ble_stack/symdef/)。

构建与烧录

工具链:Keil µVision5(ARMCC V5.06 update 6),安装于 D:\Keil_v5。

命令行构建(工作目录在对应工程的 MDK-ARM/):

"D:\Keil_v5\UV4\UV4.exe" -b mcm-ddc-ble.uvprojx -j0 -o build.log   # APP 增量构建
"D:\Keil_v5\UV4\UV4.exe" -b caiic_boot.uvprojx -j0 -o build.log    # Boot 增量构建

要求保持 0 Error(s), 0 Warning(s)。当前基线(V1.00.26):Code=48996 RO-data=4980 RW-data=2088 ZI-data=30144。

固件版本号约定(重要):每次修改固件代码必须递增 mcm-ddc-ble/inc/app_version.h 中的 APP_FW_VERSION 与 APP_FW_VERSION_NUM(格式 0x00MMmmpp,通常补丁位 +1),用于识别板上实际运行的固件;工程名与出包文件名保持不变。

出包约定(重要):每次固件修改构建通过后,必须直接运行 tools\make_package.bat 重新生成整片包与 OTA 升级包到 tools/out/(与代码改动一起交付,不要只交付源码)。

出包与烧录:

  1. tools\make_package.bat — 一键:UV4 -r 全量重建 Boot + APP1 + APP2 target(出包必须 -r,增量构建曾产生栈顶/ZI 不一致的砖包,见开发日志 §24)→ merge_image.py 合并。产物在 tools/out/:
    • mothercup_ble_prod.hex/.bin — 生产整片包(Boot + 缺省 bootsetting + APP1,只含一个 APP)
    • mothercup_ble_ota.bin — OTA 单文件发布件(52B 头含 version/总大小/总 CRC + 双 bank 载荷索引,格式见 ble_protocol.md §7);调试用单 bank 载荷 mothercup_ble_prod_ota.bin(bank1)/ _ota_app2.bin(bank2)+ json 也保留。客户端按信息项 0x07 CUR_BANK 选对侧 bank 的载荷;固件 OTA_END 有向量表防呆(status=6 bank_mismatch)
    • 注意:merge_image.py 不带参数运行时默认 app 路径仍指向已删除的 mcm-ddc-04/,手动调用必须显式传参:python tools/merge_image.py mcm-ddc-ble/MDK-ARM/bin/mcm-ddc-ble.bin mothercup_ble_prod
  2. 首次/变砖恢复:tools\flash_package.bat tools\out\mothercup_ble_prod.hex(调 SDK 自带 NSpyocd,整片擦除 + 烧录;需 NS-LINK 接 SWD PA4/PA5 + 复位脚,先关闭 Keil;target 用 DFP pack 的 n32wb031keq6_2 + -O smart_flash=false)
    • 双 APP 整包(appsw 测试):tools\make_dual_package.bat 出 caiic_ble_dual.{hex,bin}(Boot+bootsetting 双 bank 记录+APP_DATA 缺省记录+APP1/APP2 同版本双镜像,APP2 由 uvprojx target "APP2" 链接 0x01024000 构建;运行 bank 用信息项 0x07 CUR_BANK 识别);flash_package.bat tools\out\caiic_ble_dual.hex 烧录后可用 appsw 在两 bank 间切换(已实测双向切换)。
    • OTA 双 bank 选包:OTA 写对侧 bank,载荷必须链接在目标 bank 地址;两份载荷见上,客户端按 CUR_BANK 选包(详见开发日志 §39)。
  3. 日常开发调试:Keil F7 编译、F8 下载即可(Boot 不校验镜像 CRC,可直接下载 APP 调试);Keil 下载选项必须是 "Erase Sectors",整片擦除会杀掉 Boot/bootsetting(杀掉后需重烧整片包恢复)。板子上烧过其他 0x01000000 起步的程序同样会覆盖 Boot,恢复也是重烧整片包。
  4. 日常固件升级设计路径是 BLE OTA(手机 App 或 PC bleak 客户端)。

验证运行:串口助手接 PB6(TX)/PB7(RX),460800 8N1(V1.00.26 起),复位后应看到 banner 与 caiic-> 提示符(help 查看命令);手机应能搜到广播名 CAIIC-MCM-20260902。

BLE 接口与协议

协议权威文档:docs/ble_protocol.md(V1.1)。广播名 CAIIC-MCM-20260902,自定义 128-bit UUID 服务 00002760-08c2-11e1-9073-0e8ac72e1001(SDK rdtss 服务),特征:

特征 UUID 尾段 属性 用途
...c72ee001 Write Without Response 0xCA 帧协议下行(CLI_REQ / INFO_QUERY / OTA_*)
...c72ee002 Notify 帧协议上行应答(CLI_RSP / INFO_RSP / OTA_RSP)
...c72ee003 Read + Write(带响应) CLI 读写特征:写原始命令行(≤63B)→ 分包读回输出文本(每片 ≤att_mtu−2,0 长度包=结束,V1.00.13 起;此前单读 ≤512B),V1.00.02 新增
...c72ee004 Read 只读参数特征:读出全部信息项 TLV(同 INFO_RSP(all)),V1.00.04 新增
...c72ee005 Read + Write(带响应) OTA 专用特征(V1.00.19 新增):写携带一帧 OTA 传输帧 → 读同一特征取回 OTA_RSP(轮询至非空),见 ble_protocol.md §6.6
  • notify 上行已修复(V1.00.19):根因是固件帧 CRC16 漏算最后一个 payload 字节(3+payLen vs 协议规定的 4+payLen),所有帧被静默丢弃,与 notify 硬件链路无关(开发日志 §42)。帧协议通道(e0001/e0002)已实测恢复。App(SmartAssiter)走 ...e0003/...e0004 读写特征 + ...e0005 OTA 特征(App 侧参考 src/mcm/McmOta.ts,PC 参考 tools/ble_ota_update.py)。
  • 帧格式:0xCA | TYPE | SEQ | LEN(LE16) | PAYLOAD | CRC16-CCITT(0x1021/0xFFFF, LE),CRC 覆盖 TYPE..PAYLOAD 共 4+payLen 字节;OTA 为双 bank 直写、END 整镜像 zlib CRC32 + 向量表 bank 校验后更新 bootsetting 并复位。OTA 传输层通道无关:BLE e0005(逐帧锁步)/ UART 二进制模式(CLI ota;V1.00.24 起流式模式:BEGIN 16B flags、8KB 窗口流水线、扇区边界 ack、go-back-N,旧固件自动回退锁步)/ 旧帧协议通道,详见 ble_protocol.md §6.6/§6.7。
  • 连接后设备主动发起 MTU=247 交换;失败退化为默认 20B/包,协议按字节流重组,两种情形都正确。
  • 信息项 id:0x01 固件版本 u32 / 0x02 芯片温度 i16(0.1°C,ADC CH7) / 0x03 风扇转速 u16(0xFFFF=无硬件,app_fan_get_rpm() 弱符号,产品板重写即可) / 0x04 电压 u16(mV,ADC CH6) / 0x05 运行时长 u32(s) / 0x06 剩余堆 u32(B) / 0x07 当前运行 bank u8(1=APP1,2=APP2,OTA 选包依据)。
  • 调试手段:CLI 命令 blelog on 后,串口打印每个收/发协议帧 hex dump、连接/断开、CCCD 订阅事件(走 printf,不经 BLE 通道,避免自激)。
  • 维护命令(V1.00.10 起):bootsetting 与 APP_DATA 参数区为结构化读写(appget/appset/bsdump/bsset,不暴露裸读写),UART 与 BLE CLI 读写特征 ...e0003 均可调用;V1.00.11 起新增 reset(复位单板)/factory(恢复出厂设置)/uartrst(复位串口)/uartinfo(查询串口参数);V1.00.15 起新增 appsw(切换运行 bank,切前复算目标镜像 CRC32)。详见 docs/ble_protocol.md §6.5。

手机 App(SmartAssiter)

  • uni-app Vue3 + TypeScript(manifest.json vueVersion 3,appid __UNI__884AC41),HBuilderX 工程(有 .hbuilderx/,无 package.json/vite 配置)——开发/运行/打包均在 HBuilderX IDE 内进行(运行→运行到手机或模拟器;发行→原生 App 云打包)。目标平台为 Android/iOS App(BLE 功能仅 App 端有效;manifest 里保留 mp-weixin 配置但蓝牙不依赖它)。
  • 由 uni-app x(uvue/uts)+ 第三方蓝牙插件迁移而来,现蓝牙全部用 uni 内置 BLE API(vue3 App 端内置),标准基座即可运行(见 SmartAssiter/docs/修改记录_2026-09-03_迁移uni-app-vue3与蓝牙去插件.md)。
  • 结构:
    • src/BluetoothManager.ts — 蓝牙管理核心(扫描/连接/服务发现/读写/MTU/RSSI;读写按特征值独立通道:读请求经 onBLECharacteristicValueChange 按 characteristicId 分发到各特征自己的队列/超时(3s),写无跨特征阻塞;链路未稳误报的 10007 读/写各延时重试一次;连接状态经 uni.$emit("bleState", state) 广播,0=已连接可用)
    • src/mcm/ — 设备业务层:McmCli.ts(CLI 特征写命令/分包读应答——读到 0 长度包止,Promise 链串行)、McmInfo.ts(参数特征 TLV 解析,含 0x07 CUR_BANK)、McmCommands.ts(业务命令封装:sysinfo/devinfo/appget/appset 等)、McmOta.ts(combo 包解析 + e0005 锁步 OTA,重发/再同步/中止)
    • pages/tabbar/ — home(设备连接+参数展示+APP_DATA 参数读写)、ota(升级页:选择 mothercup_ble_ota.bin→e0005 锁步 OTA→复位回连复核)、my;pages/bleTest/bluetoothOperation/(CLI 终端页);login/register/displayUserInfo 为云端账号业务
    • api/ — 云端 HTTP 封装(httpInstance.ts 含服务器列表 SERVER_LIST,正式/测试/DEBUG 三地址,token 鉴权);common/auth.ts(token 本地存储)、common/bleInfo.ts(已连设备名/MAC 记忆)
    • uni_modules/ 仅 uni-icons、uni-scss(官方组件,无第三方插件)
  • App 侧错误码约定(BluetoothManager):0=成功,10000=连接失败,10001=已断开,10002=蓝牙未开,10003=无权限,10004/10005=服务/特征缺失,10008=读写/MTU 失败或超时。

PC 工具(tools/)

  • merge_image.py — 纯 Python 无三方依赖;合并 boot+bootsetting(缺省记录,脚本生成)+APP 为整片 hex/bin,同时产出 _ota.bin/_ota.json(bank1 载荷);--ota-app2 追加 bank2 载荷 _ota_app2.bin/.json;--app2 <bin> --with-appdata 生成双 bank 整包(make_dual_package.bat 使用);自动从 app_version.h 取 APP_FW_VERSION_NUM 写入清单(含 target_bank 字段)
  • make_package.bat / flash_package.bat — 一键出包 / NSpyocd 整片烧录(脚本会自动找 Python312 全路径,本机 python 可能是商店占位 stub)
  • make_dual_package.bat — 双 APP 整包(Boot+bootsetting 双 bank+APP_DATA+APP1+APP2,APP2 升一版链接 0x01024000),用于 appsw 切换测试
  • ble_cli_test.py + ble_cli.bat — PC 端 bleak 蓝牙 CLI 测试客户端(帧协议模式 + -rw 读写特征模式,交互模式 -i,venv 在 tools/.venv-ble,首次运行 bat 自动创建)
  • ble_ota_update.py + ble_ota.bat — BLE OTA 升级器(解析单文件升级包 mothercup_ble_ota.bin、按 CUR_BANK 选对侧 bank 载荷、经 OTA 特征 ...e0005 逐帧锁步、复位检测+重连校验;--uart COMx 走串口二进制模式:握手标记进入/ABORT 退出;V1.00.24 起默认流式(8KB 窗口+扇区 ack+go-back-N),--lockstep 或旧固件自动回退锁步)。BLE 与 UART 双通道均已实测通过(§42/§44),流式见 §47
  • ble_temp_watch.py — 温度监测小工具

实时架构约定(固件)

  • 使用 FreeRTOS V9.0.0 原生 API,不使用 cmsis_os 封装。
  • 任务:BLE 调度任务(栈 512 字,优先级 2,循环 rwip_schedule(); vTaskDelay(1ms);——ke_msg/ke_timer 只允许在该任务上下文运行);LED 任务(LED1 闪烁半周期读 APP_DATA 参数 led1_blink_ms);CliTask(优先级 3);CLI 输出经环形缓冲由 BLE 任务上下文发 notify(ble_up.c)。configTOTAL_HEAP_SIZE = 20KB(heap_4)。
  • SysTick 由 FreeRTOS port 接管:main 中不要手动 SysTick_Config,n32wb03x_it.c 中不要重复定义 SVC/PendSV/SysTick_Handler。
  • USART1_IRQn 优先级为 3(最低),因 ISR 内调用 FreeRTOS FromISR API,必须 ≥ configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY(=3)。BLE_SW/FIFO IRQ 优先级 0,其 ISR 内禁止调用 FromISR API。
  • 串口输出并发:多任务/CLI 输出分别持有 bsp_usart_tx_lock() 互斥锁;调度器启动前为空操作。不要在中断或多个任务里直接 printf。
  • 不接 ns_sleep 低功耗(与 FreeRTOS tick 冲突):main.c 里 ns_sleep_lock_acquire() 永久锁睡眠,SWD 全程可调试;ns_sleep.c 仍需编译(ns_ble.c 引用其符号)。

硬件引脚约束(重要)

  • SWD 调试管脚 SWCLK=PA4 / SWDIO=PA5:应用程序绝对禁止占用,否则下载/调试失效。
  • 板载 LED:LED1=PB0(跳线 J21)、LED2=PA6(跳线 J22),蓝色,4.7K 限流。
  • USART1:TX=PB6 / RX=PB7,复用 AF4,经排针 J3 引出。
  • PB8/PB9 默认接 32.768K 晶振;PB3 有下拉注意事项(用户手册 5.2.4)。
  • 新增 GPIO 前必须核对开发日志第 4 节引脚分配表。
  • 寄存器级勘误修复必须先在 SDK 源码交叉验证地址用途——曾按勘误表写 0x40011004 |= 0x40(AFEC 寄存器,与 BLE 协议栈共享)导致 BLE 射频挂死,已撤回(开发日志 §28 教训)。

代码风格

  • 固件为 C(ARMCC,MicroLIB):文件头/函数头用 Doxygen 注释(@file/@brief),注释用英文;BSP 层函数 bsp_<module>_<action>;引脚/时钟等硬件参数集中在头文件顶部宏定义;使用 SDK 标准外设库 API,不要直接操作寄存器(确有例外需交叉验证,见上)。
  • App 为 TypeScript/Vue3:注释用中文;BLE 通信统一走 src/BluetoothManager.ts 的 MyApiResult 回调约定,设备业务封装在 src/mcm/;不改 uni_modules 官方组件。

测试策略

无自动化测试框架;验证方式为:

  1. Keil 命令行构建必须保持 0 Error / 0 Warning;出包必须 UV4 -r 全量重建,并核对 map 的 __initial_sp 与 bin 向量表初始 SP 一致;
  2. 烧录后通过串口输出(banner/caiic->/devinfo)、LED 行为人工确认;
  3. BLE 链路用 tools/ble_cli_test.py(PC bleak)或手机 App 实测,配合固件 blelog on 串口抓帧对照 docs/ble_protocol.md §8.3 示例帧;
  4. App 侧改动记录写入 SmartAssiter/docs/修改记录_日期_主题.md(沿用现有命名格式)。

其他注意事项

  • nations-tec/ 下的 SDK、器件包与 PDF 为第三方只读资料,改动应只发生在 mcm-ddc-ble/、Boot/、SmartAssiter/、tools/、docs/ 内。
  • 固件重大改动应同步追加 docs/开发日志.md 新章节(现有格式:## N. 标题(日期)),协议改动同步 docs/ble_protocol.md。
  • 每改固件必递增版本号(mcm-ddc-ble/inc/app_version.h),否则无法识别板上实际固件。