ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

ISPU无NVM?电池供电振动节点的算法加载与功耗设计

ISPU无NVM?电池供电振动节点的算法加载与功耗设计 老哥们最近一直在折腾一个比较典型的低功耗振动监测节点用的就是ST的IIS3DWB10IS这颗带ISPU的高带宽加速度计。项目本身不复杂——磁吸安装在设备外壳上电池供电平时主控睡大觉隔一段时间醒来采集一次振动数据判断有没有异常。但做到一半我们卡在了一个绕不开的问题上ISPU这个内核没有NVM它的程序只能放在RAM里掉电就丢而整机为了省电偏偏还要做power gating每次唤醒都是冷启动。那ISPU里跑的FFT和异常检测算法代码到底放哪每次上电怎么恢复整个电池节点的功耗账该怎么算这篇文章就是我处理这个问题时踩出来的完整思路。我会先讲清楚ISPU没有NVM到底卡在哪再给出我认为最合理的几种方案和选型逻辑然后详细算一遍冷启动的时间与功耗账最后把调试中遇到的加载失败、掉电乱序、Flash寿命这些坑都列出来。如果你手上也在做IIS3DWB10IS或类似带ISPU传感器的电池节点这篇应该能帮你少走很多弯路。1. 先说清楚ISPU没有NVM到底卡在哪个环节1.1 IIS3DWB10IS在电池节点里的定位IIS3DWB10IS不是一颗普通的加速度计。它本身的振动测量带宽很高噪声也低适合轴承故障、齿轮箱、泵和风机这类旋转机械的状态监测。但真正让它区别于普通传感器的是这个集成的ISPU内核——一颗可以在传感器内部跑轻量级信号处理和机器学习推理的可编程单元。在电池供电的振动节点里ISPU的价值非常直接原始振动数据不用一路传到主控MCUISPU直接在传感器内部做FFT、RMS、峰值提取甚至跑一个异常检测模型最后只把诊断结果通过FIFO送出来。主控MCU大部分时间可以保持深度睡眠甚至整机断电。这样整个系统的平均功耗可以压到非常低一节电池用好几年的节点就是这么设计出来的。不过ISPU虽然能算但它本身没有非易失存储。这就引出一个所有做低功耗节点的人都要面对的问题——算法代码在掉电之后去哪了。1.2 “ISPU没有NVM”到底意味着什么先打个比方。ISPU就像一台没有硬盘的电脑你写好的算法程序放在它内部的SRAM里掉电以后连操作系统带应用程序全部清空。每次机器开机你都得先从外部U盘把系统重新灌进去灌完才能开始干活。放在IIS3DWB10IS上就是主控MCU每次上电后都需要通过SPI接口把ISPU的算法二进制文件推送到ISPU内部的程序区然后再让ISPU复位启动它才能正常跑起来。这个过程不是可选项而是必须做的因为ISPU自己没有任何可以持久化保存代码的空间。所以“power-gated battery node”和“ISPU无NVM”这两个条件放一起就构成了一个矛盾省电要求整机频繁断电但每次断电再上电ISPU都处于“空系统”状态必须重新加载算法。而加载算法本身要花时间、要耗电流这个开销在设计功耗预算时很容易被忽略但恰恰会决定节点的唤醒频率上限和电池寿命。很多第一次用这颗芯片的朋友会下意识问ST为什么不在ISPU里面放一点Flash其实从成本、晶圆面积和功耗的角度看这种设计是合理的毕竟ISPU的定位是辅助处理器算法代码由主机管理本来就是常见形态。但这就逼着系统设计者必须认真对待“算法从哪来、怎么加载、加载多快”这几个问题。2. 推荐方案算法代码应该放在哪里2.1 几个方案先摆出来对比一下针对ISPU没有NVM的问题我见过的主流做法有三类各有各的适用场景先用一张表说清楚。方案算法代码存放位置启动时序复杂度适合场景A主控Flash存储每次冷启动加载放主控MCU片内Flash或外挂NOR Flash上电后由MCU通过SPI写入ISPU低大多数电池振动节点唤醒不频繁B保持传感器供电不彻底断电算法留在ISPU RAM中不丢失无需重新加载ISPU直接续跑低唤醒频率较高待机电流可以接受C外挂SPI Flash统一管理算法包放独立SPI Flash主控只负责搬运比A多一次Flash读操作中高算法体积大、版本多、需要OTA升级先说结论绝大多数低功耗、间歇唤醒的振动节点我都推荐方案A也就是主控NVM存算法、上电后快速加载。方案B适合唤醒频繁但又能接受“不彻底关断”的场景方案C是算法体积和升级需求大到主控Flash装不下时的备选。2.2 我最推荐的组合主控Flash加SPI DMA加载方案A的具体做法其实不复杂但有几个细节决定能不能稳定运行。算法工程在ST的ISE环境里编译之后会生成一个二进制文件这个文件会嵌到主控MCU的固件里作为常量数组存在MCU的片内Flash中。注意这里说的Flash是主控的Flash不是ISPU的——ISPU没有但主控一定有。上电加载流程我一般是这样安排的主控上电初始化自己的时钟、GPIO和SPI外设。拉高传感器的电源域等待传感器内部上电稳定。对传感器做一次软复位确保它处于已知状态。配置SPI接口把ISPU算法二进制分块写入传感器的程序区。全部写完后发送启动或运行指令让ISPU程序真正跑起来。通过状态寄存器或者中断信号确认ISPU已经正常运行然后再初始化业务逻辑。这个流程里步骤4最容易被忽视的是“分块写入”和“传输校验”。我见过有人直接把数千字节的数组一次性往SPI上怼结果因为主机缓冲不够、或者SPI时钟边沿余量不足导致写进去的数据错位ISPU跑出来的完全是垃圾结果。正确的做法是把算法文件按256字节或512字节一块一块一块地写入每块写完都有明确的应答或寄存器状态可查最后做一次整体校验。在传输手段上强烈建议用DMA不要用CPU一个字节一个字节地搬。加载算法期间主控可以继续做别的事或者干脆进入一个低功耗等待状态直到DMA传输完成中断再醒来。我用DMA加载40KB左右的算法实际CPU占用几乎可以忽略整个过程由硬件自动完成这对功耗控制帮助很大。2.3 什么时候才需要外挂SPI Flash方案C我平时不太建议一上来就用除非你明确遇到了下面这些情况主控MCU片内Flash太小塞不下多版本算法或一套完整的升级镜像。算法体积已经大到几十上百KB而且还在不断膨胀。产品需要支持现场OTA升级算法需要在本地暂存新版本固件。主控MCU过于低端内部Flash本身就非常有限。外挂SPI Flash的缺点也很明显成本增加、PCB面积增加、加载前要多一次“从Flash读出来再写进ISPU”的搬运启动时间比方案A更久而且SPI Flash本身也是NVM一样要考虑擦写寿命。所以我的建议是预算和技术指标都允许的情况下先用主控Flash等确实不够了再考虑外挂Flash。3. 启动时序和功耗的账要会算3.1 一次完整的冷启动需要多长时间讨论“推荐做法”的时候不能回避一个核心指标冷启动到底要多久。这个指标直接影响节点是否能够在可接受的窗口里完成一次数据采集也直接决定平均功耗。完整的冷启动时间可以拆成几段看传感器电源域上电稳定通常几毫秒到十几毫秒取决于电源开关器件和去耦电容。主控上电和SPI初始化几毫秒。传感器软复位与会话建立几毫秒。ISPU算法加载这是大头取决于算法体积和SPI时钟。ISPU启动、初始化数据通路、FIFO开始填充几毫秒。其中第4步是可以量化计算的。假设算法bin的实际大小在40KB左右SPI时钟按10MHz跑理论传输时间大概是40 × 1024 × 8 / 10,000,000 ≈ 32.8毫秒但实际操作中有命令开销、块间切换、应答等待还要算上偶发的重传所以实际加载时间落在40到60毫秒是很正常的。如果SPI时钟能跑到20MHz理论时间可以砍半传输部分能做到16毫秒左右实际也就20到30毫秒。如果你按40KB算出来的加载时间比传感器本身的测量周期还长那就要警惕了这种场景下每次唤醒都重载算法的代价可能比你想象的高得多。3.2 用数字说话加载一次ISPU到底值多少功耗功耗账不能只看“时间短”要看“平均电流”。假设整个加载过程传感器和主控都处于工作状态整机电流取8mA左右加载时间按70毫秒算那么一次加载消耗的电量就是8mA × 0.07秒 ≈ 0.56毫安秒再换算成库仑约等于0.56mAs。这个数字单独看不吓人但放到整个工作周期里算平均电流就很直观了如果节点每60秒唤醒一次平均电流约 0.56mAs / 60s ≈ 9.3µA。如果节点每5秒唤醒一次平均电流约 0.56mAs / 5s ≈ 112µA。如果节点每1秒唤醒一次平均电流约 0.56mAs / 1s ≈ 560µA。注意这还只是加载算法这一件事的贡献没有算传感器配置、数据采集、无线发射的电流。也就是说在唤醒不频繁的节点里重新加载算法的功耗完全可以接受但唤醒频率一旦上去加载本身就会变成最大的耗电黑洞。这也是为什么我说“推荐方案”不能脱离场景。低频唤醒的轴承监测节点方案A非常好70毫秒加载时间换来极低的待机电流电池寿命完全达标但如果你的节点需要每秒都判断一次设备状态那方案A就没那么香了要么拉长休眠周期要么改用方案B让ISPU一直保持供电。3.3 降低加载开销的几个实操技巧如果确认走方案A有几个小技巧可以帮你把加载功耗压下来。一是优先用DMA传输。CPU在加载期间不用一直跑可以进入低功耗等待状态等DMA完成中断再唤醒这样峰值电流的时间和幅度都更可控。二是按需初始化硬件。SPI外设、GPIO、DMA通道这些尽量在加载前一次性配置好不要在加载过程中反复开关外设时钟那会引入额外的电流尖峰。三是检查算法bin体积。每次编译完都看一眼生成的二进制文件大小别让它在不知不觉中膨胀。关掉调试输出、缩减环形缓冲、精简模型结构能省下几十KB就相当于省下了几十毫秒加载时间和对应的功耗。四是把校准参数和用户配置交给主控统一管理。传感器内部的用户寄存器在掉电后同样会丢所以像偏移校准、阈值设置、滤波器系数这些都应该存在主控Flash里每次加载算法后重新写一遍。别指望ISPU自己能记住这些配置它没有NVM做不到。3.4 唤醒频率高时也许不该断电这一点值得单独拎出来说。不少团队一提到低功耗就条件反射地想到“全断”但全断并不是唯一的省电路径甚至不是最优路径。如果节点唤醒频率超过每5秒一次或者更极端地需要持续监测那每次唤醒都重新加载几十毫秒的算法反而比让ISPU保持在一个低功耗状态更费电。这种场景我建议改用“伪power gating”传感器电源不断让ISPU进入低功耗或睡眠模式中断唤醒后它可以直接从RAM里继续执行程序不需要重新加载。代价是待机电流不再是零可能是几十微安级别但换来的是微秒级的响应和完全不需要加载算法。在故障检测类应用里很多时候“睡得浅一点但能快速响应”比“彻底关机但要花几十毫秒才能醒”更划算。这个取舍一定要写在方案评审里别等到代码写完才改架构。4. 加载失败、掉电时序、Flash寿命这些坑我替你们踩过了4.1 ISPU程序加载失败的常见原因ISPU程序加载失败通常不会有什么明显的报错表现就是ISPU没有按预期输出结果或者传感器状态寄存器里的标志位不对。我排查过几次最后定位到的主要原因就这几个传感器还没就绪就开始写程序。上电后立刻发SPI命令传感器内部还在复位命令全部被丢弃。SPI时钟太快或信号完整性问题。飞线过长、上拉电阻不对、时钟边沿采样点配置错误都可能导致写入的数据错位。加载过程中电源电压跌落。电池节点上电瞬间电流冲击大电源没有稳定导致加载中途失败。算法bin版本与ISPU运行环境不匹配。比如用旧版本的IDE编译的算法或者字节序配置错误。加载后没有正确触发启动或者复位时序错误导致ISPU虽然收到了程序但并没有运行起来。这些问题的排查方式我建议从软件和硬件两头同时下手。软件上在加载流程里加CRC校验和状态检查每次写一块都确认写成功再写下一块硬件上用逻辑分析仪抓一次SPI波形看看时钟和数据是否对齐电源轨有没有明显跌落。4.2 MCU软复位后的状态一致性问题还有一个容易被忽略的坑MCU自己跑飞了软件看门狗复位但传感器的电源没有断过。这时候ISPU的程序其实还在RAM里还在继续跑而主控MCU的SPI配置、DMA状态、业务逻辑全部重新初始化了。两边处于“都知道对方存在但不知道对方状态”的尴尬境地表现出来就是数据错乱、中断唤醒异常、莫名其妙多出很多垃圾中断。所以我的建议是MCU的启动流程里必须包含一个“传感器复位并重新加载”的步骤即使传感器看起来还在正常运行也要先把它软复位掉然后重新加载ISPU算法保证整个系统回到一个确定性的初始状态。这样做虽然会让启动时间多几十毫秒但换来的是系统状态的一致性和可预期性在低功耗节点里这个代价是值得的。4.3 掉电顺序与电源管理电路的配合既然做了power gating就绕不开掉电顺序。最怕的情况是系统正在采集数据ISPU正在跑FFT主控突然把传感器电源关了ISPU跑到一半掉电。下次上电时传感器可能处于一个未定义状态SPI通信拉不起来加载算法也迟迟不成功。合理的做法是在硬件设计时就规划好掉电时序。传感器的电源开关要保证有明确的上下电延迟不能和主控的reset共用同一个毛刺源软件上主控在关断传感器电源之前应先把ISPU置于复位状态或者至少让它停止输出中断信号避免掉电瞬间ISPU给主控留下一个虚假的中断。另外中断线上最好加一个小的RC滤波或下拉避免掉电期间传感器电源上的残压耦合出干扰脉冲把主控从低功耗状态误唤醒。这种问题在实验室里很难复现一到现场就会变成“电池掉得特别快”的诡异Bug排查起来非常头疼。4.4 Flash擦写寿命、算法版本升级与现场维护如果算法放在主控Flash里就绕不开Flash寿命问题。算法本身是只读的不会频繁擦写但OT A升级时如果设计得不好频繁在同一个Flash分区写入几年下来就可能把片内Flash写穿。这不是危言耸听现场的工程设备往往要服役五到十年。我的建议是算法存储区与主程序存储区在逻辑上分开算法区域使用双备份结构。当前正在运行的算法放一块区域新升级的算法先写入另一块区域校验通过后再切换激活。万一升级过程中掉电下次启动还能用旧版本算法继续跑不会变砖。这套逻辑不复杂但对现场维护的可靠性提升非常大。给算法文件本身也建议带一个版本号和CRC字段主控加载前读出来校验一遍避免Flash区域数据出错ISPU跑了一个完全错误的算法。震动节点平时没人看管一旦数据异常几乎没法远程定位所以所有能自愈的机制都要尽量做在前面。4.5 程序保密性算法裸露在Flash里的风险还有一个很多人不会第一时间想到的点算法二进制放在主控Flash里本质上就是明文存放的。如果现场的设备被人拆走通过调试接口把Flash读出来你的振动诊断算法就完全暴露了。对很多做设备健康管理的公司来说算法模型本身就是核心资产。如果在意这个问题常见的做法是在主控侧对算法二进制做加密存储上电后解密再传给ISPU。但要注意解密会占用主控RAM和CPU时间在超低功耗节点上需要评估是否划算。对于比较敏感的工业客户这个权衡值得提前和产品经理对齐别等量产了再改加密方案。5. 回到标题我的recommended approach是什么5.1 一句话结论如果一定要用一句话回答标题里的问题我的答案是默认把ISPU算法二进制放在主控MCU的Flash里每次冷启动通过SPI DMA分块写入ISPU配合CRC校验和版本管理把加载时间控制在几十毫秒量级当唤醒频率高到重新加载的电量开销无法接受时再切换为ISPU保电加低功耗运行的“伪power gating”方案只有当算法体积大到主控Flash放不下、或者需要频繁OTA升级时才去引入外部SPI Flash。这个思路的出发点很简单在绝大多数电池供电的振动监测场景里唤醒频率并不高加载几十毫秒的算法换来的低待机功耗才是收益最大的。而真正决定成败的不是上电加载这个动作本身而是你为它设计的时序、校验、掉电保护和版本管理机制。5.2 选型时真正该留意的两件事第一件事是唤醒频率。在项目最早期就要把“平均多久醒一次”这个参数定下来因为它直接决定ISPU的供电策略。唤醒频率低于每30秒一次方案A几乎无脑用唤醒频率高于每5秒一次就要认真考虑方案B。第二件事是算法体积。哪怕现在只有20KB也要按未来增加故障类型、增加模型复杂度后的体积做评估看你选的主控Flash够不够用别等算法优化到一半发现塞不下了再换芯片。5.3 一点经验做这类低功耗传感器节点我个人的体会是不要怕ISPU没有NVM真正怕的是系统设计时没有把“冷启动加载”当成一个一等公民来对待。只要你在架构阶段就给加载流程留好时序预算、功耗预算和异常恢复路径这个“缺点”完全不会成为瓶颈。另外再分享一个小建议在固件里保留一个加载耗时的性能探针每次上电都记录一次从电源开启到ISPU开始运行的毫秒数。这个数字在调试时价值极大能帮你快速识别是电源不稳、SPI通信异常还是算法文件体积膨胀导致的问题。我在好几个项目里都是靠这个数据定位到硬件问题的强烈建议你加上。
返回列表