18 KiB
AGENTS.md
项目概述
本仓库是 mothercup(母乳杯) 产品的完整代码仓库,包含三大部分:
- 设备固件 — 基于国民技术(Nations)N32WB031 BLE SoC(实际型号 N32WB031KEQ6-2:Cortex-M0,64MHz HSI,Flash 512KB,RAM 48KB+16KB):
mcm-ddc-ble/— 唯一活跃的应用固件工程(APP,链接在 APP1 bank0x01008000/224KB)。以 SDK rdtss 例程为蓝本,集成 FreeRTOS、UART CLI、BLE 自定义 GATT 服务(CLI 透传 / 设备信息查询 / BLE OTA 双 bank 直写升级)、bootsetting 与 APP_DATA 参数区结构化读写命令。当前版本 V1.00.09(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。
- 手机 App
SmartAssiter/— uni-app Vue3 + TypeScript 工程(HBuilderX 项目管理,无 package.json),通过 BLE 连接设备:查看运行参数(温度/电压/转速等)、CLI 终端、OTA 升级页(当前停用,见下)。另有登录/注册/用户信息等云端业务页面。 - PC 工具
tools/— 整片烧录包制作/烧录脚本 + bleak 蓝牙测试客户端。
关键文档:
docs/开发日志.md— 固件全程开发日志(29 节,含所有踩坑根因与设计决策,排查问题先查这里)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/ # 出包产物(caiic_ble_full.{hex,bin} + _ota.bin/_ota.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 布局(铁律)
Flash 布局(512KB,Boot/src/dfu_layout.h 为唯一权威定义,官方 256KB DFU 布局每区加倍):
| 区域 | 地址 | 大小 |
|---|---|---|
| Bootloader | 0x01000000 | 16KB |
| bootsetting | 0x01004000 | 8KB(用 1 个 4KB 扇区,结构体见 dfu_layout.h) |
| APP_DATA | 0x01006000 | 8KB(区头为 caiic_params_t 参数记录,见 app_params.h) |
| APP1 | 0x01008000 | 224KB(0x38000) |
| APP2 | 0x01040000 | 224KB(0x38000) |
- RAM 铁律:SRAM 为 48KB+16KB,低 16KB(0x20000000~0x20003FFF)由芯片 ROM/BLE 子系统占用(rwip 堆描述符、patch 数组、中断中继表,由 ROM 启动代码预备)。任何工程的 IRAM 执行区必须从 0x20004000 起(含 Boot 和任何小工具),否则 .data/.bss 初始化冲掉 ROM 数据,BLE init 必然 HardFault(实测根因,开发日志 §21)。注意: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, 115200 8N1):fputc 重定向 + DMA TX(CH1) + RXDNE 中断字节队列 + 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 / param / bsdump / bsset
│ ├── 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)+ param 命令(led1_blink_ms/pwm_duty_pct)
│ ├── app_bootset.c # bootsetting 结构化读写 bsdump/bsset(自动重算 CRC,防裸写变砖)
│ ├── ble_up.c # CLI 应答的 BLE notify 上行(ke_msg 上下文约束:环形缓冲 + BLE 任务内发送)
│ ├── n32wb03x_it.c # 异常处理(HardFault 栈帧打印)+ USART1_IRQHandler 转发
│ ├── app_usart.c # 遗留文件,已不在工程中编译(rdtss 原透传 FIFO,勿使用)
│ └── 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;
# OTA_IMG_1/2 是 rdtss 遗产,保留不用)、Objects/、bin/、Listings/
工程配置:器件 N32WB031KEQ6-2,IROM 0x01008000/0x38000(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.09):Code=38352 RO-data=4192 RW-data=2028 ZI-data=27580。
固件版本号约定(重要):每次修改固件代码必须递增 mcm-ddc-ble/inc/app_version.h 中的 APP_FW_VERSION 与 APP_FW_VERSION_NUM(格式 0x00MMmmpp,通常补丁位 +1),用于识别板上实际运行的固件;工程名与出包文件名保持不变。
出包约定(重要):每次固件修改构建通过后,必须直接运行 tools\make_package.bat 重新生成整片包与 OTA 升级包到 tools/out/(与代码改动一起交付,不要只交付源码)。
出包与烧录:
tools\make_package.bat— 一键:UV4 -r全量重建 Boot + APP(出包必须-r,增量构建曾产生栈顶/ZI 不一致的砖包,见开发日志 §24)→merge_image.py合并。产物在tools/out/:caiic_ble_full.hex/.bin— 整片包(Boot + 缺省 bootsetting + APP1)caiic_ble_full_ota.bin+_ota.json— OTA 载荷与清单(size/crc32/version;version 自动取APP_FW_VERSION_NUM,手机端 OTA_BEGIN 直接取用)- 注意:
merge_image.py不带参数运行时默认 app 路径仍指向已删除的mcm-ddc-04/,手动调用必须显式传参:python tools/merge_image.py mcm-ddc-ble/MDK-ARM/bin/mcm-ddc-ble.bin caiic_ble_full
- 首次/变砖恢复:
tools\flash_package.bat tools\out\caiic_ble_full.hex(调 SDK 自带 NSpyocd,整片擦除 + 烧录;需 NS-LINK 接 SWD PA4/PA5 + 复位脚,先关闭 Keil) - 日常开发调试:Keil F7 编译、F8 下载即可(Boot 不校验镜像 CRC,可直接下载 APP 调试);Keil 下载选项必须是 "Erase Sectors",整片擦除会杀掉 Boot/bootsetting(杀掉后需重烧整片包恢复)。板子上烧过其他 0x01000000 起步的程序同样会覆盖 Boot,恢复也是重烧整片包。
- 日常固件升级设计路径是 BLE OTA(手机 App 或 PC bleak 客户端)。
验证运行:串口助手接 PB6(TX)/PB7(RX),115200 8N1,复位后应看到 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)→ 读同一特征取回输出文本(≤512B),V1.00.02 新增 |
...c72ee004 |
Read | 只读参数特征:读出全部信息项 TLV(同 INFO_RSP(all)),V1.00.04 新增 |
- 已知未决问题:固件 notify 上行链路不通(帧协议应答收不到,下行写入正常),见开发日志 §28 末尾。因此 App(SmartAssiter)已整体切换为只使用
...e0003/...e0004两个读写特征,删除了 notify/帧协议代码;App 的 OTA 页当前停用(OTA 应答依赖 notify)。固件侧帧协议与 OTA 代码仍完整保留,PC 端tools/ble_cli_test.py两种方式都支持。修复 notify 是本仓库最重要的待办。 - 帧格式:
0xCA | TYPE | SEQ | LEN(LE16) | PAYLOAD | CRC16-CCITT(0x1021/0xFFFF, LE);OTA 为双 bank 直写、扇区级 ack 流控、END 整镜像 zlib CRC32 校验后更新 bootsetting 并复位。详见 ble_protocol.md。 - 连接后设备主动发起 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)。 - 调试手段:CLI 命令
blelog on后,串口打印每个收/发协议帧 hex dump、连接/断开、CCCD 订阅事件(走 printf,不经 BLE 通道,避免自激)。 - 维护命令(V1.00.09 起):bootsetting 与 APP_DATA 参数区为结构化读写(
param/bsdump/bsset,不暴露裸读写),UART 与 BLE CLI 读写特征...e0003均可调用。详见docs/ble_protocol.md§6.5。
手机 App(SmartAssiter)
- uni-app Vue3 + TypeScript(
manifest.jsonvueVersion 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全局回调 + 内部串行队列 + 3s 超时;连接状态经uni.$emit("bleState", state)广播,0=已连接可用)src/mcm/— 设备业务层:McmCli.ts(CLI 特征写命令/读应答,Promise 链串行)、McmInfo.ts(参数特征 TLV 解析)、McmCommands.ts(业务命令封装)pages/tabbar/— home(设备连接+参数展示)、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;自动从app_version.h取APP_FW_VERSION_NUM写入清单make_package.bat/flash_package.bat— 一键出包 / NSpyocd 整片烧录(脚本会自动找 Python312 全路径,本机python可能是商店占位 stub)ble_cli_test.py+ble_cli.bat— PC 端 bleak 蓝牙 CLI 测试客户端(帧协议模式 +-rw读写特征模式,交互模式-i,venv 在tools/.venv-ble,首次运行 bat 自动创建)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 官方组件。
测试策略
无自动化测试框架;验证方式为:
- Keil 命令行构建必须保持 0 Error / 0 Warning;出包必须
UV4 -r全量重建,并核对 map 的__initial_sp与 bin 向量表初始 SP 一致; - 烧录后通过串口输出(banner/
caiic->/devinfo)、LED 行为人工确认; - BLE 链路用
tools/ble_cli_test.py(PC bleak)或手机 App 实测,配合固件blelog on串口抓帧对照docs/ble_protocol.md§8.3 示例帧; - 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),否则无法识别板上实际固件。