前言 无线通信技术相关应用中,用户体验一直是用户关系的重点。无线通讯距离近一点,通讯速度慢一点,这都不是致命的问题,在某些场合下是完全可以接受的,甚至 本身就是项目的技术需求;但是有一些设计缺陷却会严重影响用户体验的,一旦大面积的出现,基本上可以判定为产品失败了;总结起来,大家都无法忍受的问题主要是下述两个 : (1)通讯失败或者数据传输错误 (2)电池消耗快,很快没电 01 业内问题 在绝大部分用户的心目中,无线通讯本身就不如有线通讯技术稳定,如果一款产品还经常传输失败,试问用户会对这款产品有信心吗? 无线产品配合上电池供电,才能充分发挥无线技术可以随意移动的优势,因此很多的无线产品经常和低功耗或电池供电有非常紧密的联系;一旦这个产品电池消耗很快,那么必然将是其便携性,移动性大打折扣。 当然,在理论设计上产品的电池寿命肯定是非常长的,但是真正实现起来却比较困难,很多的产品设计电池寿命有 5 年之久,但是现场运行不到一年,甚至几个月就完全没电了,这种问题的发作经常没有任何规律,测试时间上又以年/月为单位,且呈现出偶发特性,定位起来极其困难,困扰了不少的无线通讯技术工程师,被认为是业界的重要难题之一。 02 技术难点 其实电池快速耗电和通讯不稳定说到底都是软件设计,特别是软件架构方面的设计问题;软件架构上的不完整或混乱,导致射频芯片的控制不准确甚至部分状态失去控制才是问题的源头。既然大家都认为功耗的管理是一个难题,那么到底难在哪些环节呢? (1) 产品的低功耗休眠唤醒设计,存在系统业务和应用层业务两种: 在系统层面讲,主要有OTA无线升级、远程诊断、远程控制(无线I/O)等;在应用层中则是回调机制、关闭端口上拉、检测用户按键、关闭工作指示灯等。系统层内容属于整个产品的躯干和骨架,通常需要交给经验丰富的工程师负责,因为涉及精密的规则和庞大的算法问题,需要较为强大的抽象能力和全面的视角。而应用层则是面向用户的,体现在软件部分则相对比较简单。 (2) 系统存在多种唤醒源: 如UART、GPIO、RTC、Timer等,这些唤醒源中断方式和清除规则略有不同,但是进入和退出休眠需要遵循相同的路径,因此其控制逻辑需要做一定的抽象化设计,具有一定的挑战。 (3) 基于RTC定时器的后台背景活动: 某些延迟操作,比如开启一个 LED 指示灯,十秒之后关闭,此时如果处理器全速运行就为了运行这一功能,是不太经济的;通常是设置一个状态标志,然后启动RTC定时器,并将处理器切入休眠状态,计时的时间到了之后会产生一个RTC中断,处理器可以在这种中断到达的时候关闭这个LED 指示灯。类似这些延迟操作,往往还会和其他的业务状态交织在一起,控制逻辑需要精确设计,稍有不慎就会失去控制。 (4) 被未知的电磁波干扰,吵醒 , 误唤醒等假唤醒行为: 无线电波由于空间开放的特性,其唤醒动作往往伴随着少量的模拟特性,偶尔会被一些未知的信号给误触发,处理器被唤醒之后, 需要对唤醒后的实时参数做一些分析计算,对唤醒源进行甄别筛选,如果不是有效的唤醒,需要提前终止业务逻辑。 (5) 存在多种不同模式的睡眠深度的低功耗模式: 处理器通常支持多种不同的睡眠 深度, 对应不同的功耗等级。不同睡眠模式下,处理器可以激活的外设不一样的,在唤醒之后,有些外设需要再次初始化之后才可以重新投入工作,只有深入了解处理器的工作特性,才能控制好处理器不同睡眠模式 的切换工作。 (6) 双芯片模式(独立的无线通讯模块)模式和单芯片模式(协议栈和应用层业务运行在一个芯片上),需要统一的编程接口 。 如果维持两套不同的编程接口,代码分支庞大不说,还很容易产生歧义,为后续的产品维护和架构升级带来困难。 综合以上难点,需要解决如此复杂的功耗控制要求,必须分而治之,采用分层的控制策略;行之有效的解决方案就是如下的内-中-外,三级环形架构。 03 三级环形架构 上图是一个电子价签的主程序框架。可以看出该程序主要分为三个主线程,分别是协议栈的主线程;低功耗休眠与唤醒的主线程与墨水屏应用业务的主线程。这三个主线程在同一个层级平行运行,具有相同的调度优先级。 局放图 我们将低功耗休眠与唤醒的主线程做局部放大,如上所示。 图中的三级环架构是休眠唤醒管理模块的核心,是整个休眠唤醒功能的局部放大。如图所示,由内环、中环、外环,三部分构成。因为考虑到在无线通信中,各种事件的复杂程度及其处理方式,分为以上三环。最内部一环主管电磁波唤醒,中层环主管GPIO唤醒、RTC唤醒、UART唤醒,最外层环则启动了整个协议栈以及业务层,面向用户进行交互。 三级环的目的突出的是分层做事原则。在内环中只进行电磁波唤醒的工作,这里主要有三部分,查询中断、分析中断状态、无线电波处理。当信号到达这一环,会根据信号类型分析是否进行无线电波的唤醒处理。 如果不是无线电波唤醒,则跳出该层,进入中环处理。这里的信号类型分析和处理是根据不同事件、不同时刻产生的耦合性而定的。 在中环,GPIO 唤醒是特定产品的唤醒模式;RTC 唤醒通常用于一些低优先级的后台任务,比如检测是否漏电或者执行一些延迟 I/O 操作;UART 串口唤醒 则是针对用户处理器。 外环则是面向用户的层级,如需要启动主程序固件升级或者业务逻辑,比如墨水屏的刷新屏幕显示内容等,则程序会被全面唤醒,此时就在外环中进行。 环形架构的优势由外环、中环到内环,视觉效果方面是越来越小的,越来越缩放的。自然在功能性方面也是越来越小,越来越简洁的过程。三级环从外到内,能做的 “ 事 ” 就越来越少,体现在软件代码方面就是,代码更少,功能性更加单一,逻辑更加清晰,运行更稳定。从而更加节省功耗。 为什么功耗更加节约?将电磁波唤醒独立拆分,做成了独立的单元结构,是出于这样的考虑的。当信号指令到达三级环,内环首先进行判定,是否需要电磁波唤醒,判定是,就进行电磁波唤醒;判定不是,则跳入中环选择唤醒类别,内环进入休眠。 考虑到事件的复杂性、多样性,需要从不同属性、不同时间等多角度考量休眠唤醒的执行,通俗点说就是“跟我相关起来干活,跟我无关继续睡觉”,这样的三级环设计针对性很强,在需要单一模式唤醒时,只需要调动少数软件资源和内部耗能就可以完成,完成相关作业后继续休眠,等待下一轮指令唤醒。从而这样的三级环设计是一款更加节约功耗的方案。 回调函数// ***** // Design Notes: // ----------------------------------------------------------------------------- char OnHostWakeup_Request( unsigned char iStatus, char iCause, char iReqAck ) { unsigned char iRetVal; // The callback status switch ( iStatus ) { case WIMINET_SLEEP_CALL_INIT: {
} break ; case WIMINET_SLEEP_CALL_OPEN: {
} break ; case WIMINET_SLEEP_CALL_WORK: {
} break ; case WIMINET_SLEEP_CALL_STOP: {
} break ; default: {
} break ; // The return status return iRetVal; 以上是一个 SoC 产品方案,回调函数的标准样本,通常需要实现“系统刚刚唤醒”,“已经完成初始化”,“执行用户任务”,“即将进入休眠”等几个重要的通知时刻: 系统刚刚唤醒** :** 系统运行在三级环的内环,处理器刚刚被中断唤醒,需要启用系统层级别的外设,比如 SPI 总线等; 已经完成初始化: 系统已经切换至三级环的外环,控制权准备释放给用户程序,通常在此时初始化用户任务; 执行用户任务** :** 系统运行在三级环的外环,此时协议栈程序也在同层级平行运作,用户程序执行完了之后,需要释放控制权给系统,通知系统进入睡眠模式 即将进入休眠 : 系统运行在三级环的中环,所有的数据都已经发送完毕或者超时终止,即将重新进入睡眠模式,通知用户关闭外设,执行任务的清理或者重置工作。 对于不太复杂的系统,通常仅仅需要实现上述四个通知的回调函数即可,其余的通知可以不做处理器;对于更加复杂的系统,可以根据需要实现其他更多的回调通知。 |
发到文章里去呢 |
stm8l051f3 TSSOP20 封装,待机模式下,2天后,电流突然增加到140UA
各位朋友,有没有STM32F0系列教程,最好是汇编语言的。
f407使用http连接做服务器时,程序不能进入http线程中,但是别的任务都顺利执行了 程序时cudemx生成的
STM32F4 上电不启动 固件损坏 程序丢失 FLASH数据被改写 PDR_ON
使用CubeMX配置生成STM32G431的工程文件,请问怎么设置FLASH的bank模式呢?
TouchGFX
STM32F103 ADC利用DMA进行采样问题求解
STM32F107搭配DP83825 使用lwip通信
STM32U575/585 MCU 硬件开发入门中硬件连接错误?
ST25R3912读取15693可以按byte读取么