合理设置MCU滴答 千万不要累着它

  作者:光华居士 时间:2018-08-29来源:电子产品世界

2017年盛夏,北京街头,晴空万里,无风。

近乎凝滞的空气中一点风都没有,恼人的知了无停无休地叫着,不疲也不厌,让人很是怀疑它们的居心。被太阳晒得发焦的柏油路面热气腾腾,像被晒干了肚皮的鱼儿一样无声地嘶嚎着。呼啸而过的汽车排着滚烫的尾气,急匆匆地想要逃离这个世界,偶尔响起的一声喇叭,就像向太阳求饶一般。地铁站和周围的建筑被晒得无精打采的,无可奈何地矗立在似火骄阳的暴晒之下。刚从地铁站出来的人们行色匆匆,难得悠闲从容的面孔,笔者被裹挟在滚滚人流之中,不由自主地加快着脚步。站在十字路口,一股股热浪扑面而来,我顶着发烫的头皮,在心中一片哀号,“北京真热啊!”

笔者这次顶着大热天来帝都,是带着庄严而神圣的任务过来的:给一个车厂做了一款PEPS,领导让过来做总线测试。

出师不利,测试遇阻

整车厂进行的总线测试包括通信测试、网路管理测试和诊断协议测试三大块,通信测试主要包括工作电压、上升沿、下降沿、采样点、报文周期准确性、Bus-off后的快速恢复和慢速恢复等测试项,网络管理测试主要包括CAN节点的网络建环、掉线、Bus-off、协同休眠、本地唤醒和远程唤醒等测试项,诊断协议测试主要包括多帧收发、响应超时、诊断会话切换、诊断服务等测试项。

笔者其实是带着轻松愉快的心情过来测试的,因为做这款PEPS产品之前做了一款BCM,当时这款BCM已经量产,而且也在汽车厂进行过总线测试,对比来看,这两家车厂的测试条目差不多,笔者就把当时BCM上的代码移植到了这款PEPS上,根据不同之处进行了相应修改。按照红芯浏览器联合创始人的说法,虽然用的是开源代码,但是了解每一行代码的含义并知道怎么修改,就是自主可控,笔者盘算着,既然BCM的总线测试都通过了,而且我不仅知道怎么修改这些代码,这些代码还完全是我自己写的,所以PEPS这次测试也绝对是可控的,应该比较顺利。

等到看测试结果的时候,兴冲冲的我仿佛被浇了一头冷水,有两项测试没通过,这两项测试分别是用优先级最高和优先级最低的报文填充CAN总线带宽,让总线负载率达到100%,在全负荷的情况下检测PEPS周期发送报文的时间准确性。我扒拉着这两项测试条目的测试数据,眼睛都快看花了,终于发现,确实有一个周期为50ms的报文出现过一次报文漏发的情况,测试软件的判断条件是检查每个报文连续两次发送的时间间隔,如果时间间隔在45-55ms(报文周期的正负10%)之间,测试通过,反之测试失败。

中断频繁,MCU不堪重负

“不一样”的宫斗剧《延禧攻略》最近火得不得了,自带无敌光环的延禧宫主子魏璎珞说过,事情来了就不要怕!但是,当我发现报文周期准确性测试失败时,心中还是怕怕的,因为我本能地意识到,旅游计划肯定是泡汤了,总线负载率100%意味着CAN总线接收中断过于频繁,测试失败不是逻辑上的错误导致,而是MCU性能限制导致的系统性问题。在换不了MCU的情况下,需要做大量优化才能降低MCU的负荷,将有限的性能用在CAN报文接收中断的处理上和周期报文的发送上。

科学研究工作是严谨的,产品开发亦是如此,为了更好地量化MCU的负荷,我做了如下分析:

整车厂规定所有总线报文的数据场长度为8个字节,根据CAN报文格式,一个8字节数据场的CAN报文的位数为1(帧起始)+ 12(仲裁场)+ 6(控制场)+ 64(数据场)+ 16(CRC场)+ 2(应答场)+ 7(帧结尾)=108位。报文之间存在帧间空间INTERFRAME SPACE。帧间包括间歇场、总线空闲的位场。间歇场包括3 个“隐性”的位。总线空闲的(时间)长度是任意的。

所以,一个8字节的数据帧至少需要(108+3+1)* 位时长的时间,总线波特率为125KHz,位时长为8us,经计算得知,一条总线报文的最短时间长度为0.896ms,为了计算方便,按0.9ms计。

在这次测试中,PEPS发送报文消耗的总线带宽大约为3%,这就意味着,在总线负载率是100%的情况下,CAN报文接收中断的周期为0.9/0.97=0.93ms,即,PEPS每隔0.93ms都会触发一次CAN接收中断,执行一次中断服务程序。由于成本限制,这款PEPS选择的MCU是一款中档16位单片机,主频不过25MHz,却需要应付这么频繁的中断,心疼MCU三秒钟。。。

降低滴答中断频率

肿么办?CAN报文接收中断服务程序写得非常简洁,根本不存在任何优化空间,这条测试项目制造出100%总线负载率,CAN报文接收中断频率就是那么惨无人道地频繁,也是不可更改,因此,只能从别处下手。

嵌入式系统有大量定时应用,所以无论用不用操作系统,都会有一个“系统滴答”,它以固定的时间间隔触发中断,为各种定时应用提供时间基准。这也是一个频繁发生的中断,我检查了这款PEPS上的滴答,发现其周期设定为了2ms,之所以选择2ms,主要是出于代码复用,之前我在BCM上选择的系统滴答为2ms,它会牵扯到好多定时参数的设置,为了把BCM上的一些代码直接拿到到PEPS上来用,于是也原封不动地把系统滴答设置成了2ms。

CAN接收中断周期为0.93ms,滴答中断周期为2ms,假设不存在其它任何中断,系统的综合中断周期为0.64ms,那款BCM的MCU主频为64MHz,是现在这款MCU的25MHz主频的2.56倍,64MHz 主频可以顺利处理0.64ms周期性中断,25MHz主频就卡了壳了。

顺着这条思路,笔者将系统滴答设置成了10ms,在CAN接收中断周期0.93ms,滴答中断周期为10ms的条件下,系统综合中断周期为0.85ms,将中断负荷降低了33%。系统滴答修改后好多地方需要进行相应修改,这么折腾了两天,再次进行通信测试,报文周期准确性测试通过,笔者悬着的心才放了下来,至于是不是堪堪通过,MCU负荷的余量是否其实已经非常小了,那就非笔者水平能够判断了。

滴答更改的性能比较

为了量化滴答由2ms提高至10ms带来的性能提升,笔者定义了一个32位全局变量,在程序的主循环体中累加,每执行一次主循环体,该变量加一,然后根据单位时间(1秒)内的主循环执行次数,判断采用不同滴答的两个程序的运行效率。

测试发现,滴答设置为2ms时,每秒执行大约22200次循环,滴答设置为10ms时,每秒执行大约25100次循环,效率大约提升了13个百分点。

至于10ms的滴答是否合理,笔者接触过的ucos和FreeRTOS中的好多移植例程中都把系统滴答设置成了10ms,足可见10ms的滴答满足大多数嵌入式系统的需求。

后记

归程依然酷暑难耐,由于没有完成既定的旅游计划,笔者心中多多少少有那么一丢丢的小遗憾,但是这次测试让我对中断、MCU性能又有了更加深刻的认识,也算是收获满满不虚此行了。高铁窗外的景色飞速向后退去,眼前只模模糊糊地留下一片绿色的影像,旁边座位上的小姑娘正在叽叽喳喳地和妈妈嬉笑打闹,“如果人们像爱护小孩子那样爱护MCU,通过合理的设计减轻它的工作负荷,让它不要累着,那该是多么美好的机器世界啊。”我不禁暗暗想到。

关键词: MCU 滴答 测试

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW

或用微信扫描左侧二维码

相关文章


用户评论

请文明上网,做现代文明人
验证码:
查看电脑版