昨天半夜两点,哥们给我发微信,说项目又炸了。
产品出货前最后一天,测试妹子跑过来跟你说"哥,又死机了"。当时我正在打游戏,一看消息差点把手机摔了。
赶紧连上调试器一看,好家伙,中断服务函数里卡死了。再往深了追查,问题居然出在中断优先级的设置上。
说起来你可能不信,STM32死机这个问题,十有八九都是中断优先级没设对闹的。今天就跟大家聊聊这个话题。
先说说中断优先级是啥STM32用的是NVIC嵌套向量中断控制器,简单理解就是:芯片里有一堆中断信号在排队,谁先谁后,得看优先级。
STM32F1系列有16个优先级(0-15),数值越小优先级越高。你可以把它想象成医院的急诊系统——心脏骤停的肯定比感冒发烧的先看。
但STM32的中断优先级有点特殊,它分两层:抢占优先级和响应优先级。
抢占优先级 vs 响应优先级
这个概念很多教程讲得云里雾里的,我直接说人话。
抢占优先级:能不能打断别人
如果一个中断的抢占优先级比另一个高,那它可以直接把正在执行的中断服务函数给停了,先去执行自己的。这叫中断嵌套。
响应优先级:不能打断别人的时候,谁先来
如果两个中断抢占优先级一样,那谁响应优先级高谁先执行。但这种情况下,低优先级的中断必须等高优先级的完全执行完才能轮到自己。
几种经典的作死配置按我的经验,下面这几种配置最容易让STM32原地升天。
1. 所有中断优先级一样有人觉得省事,所有中断都设成相同优先级。看起来没问题,但实际上一旦两个中断同时发生,系统就不知道该先处理谁了——严重的时候直接死循环。
2. 在中断里做耗时操作这是新手最容易犯的毛病。中断服务函数里又是延时、又是打印、还调了一大堆其他函数。CPU全卡在中断里出不来,其他中断压根没机会执行,系统直接卡死。
3. 优先级数值搞反了我见过有人以为0是最低优先级,结果配置全反了。按我的经验,你记一点就行:数值越小,优先级越高。
正确设置优先级的几个建议说完坑了,聊聊怎么设才对。
第一,按业务重要性分配
紧急的、不能被打断的控制类中断(比如PWM控制、电机刹车)设高优先级。通讯类的、可以稍微等等的(串口、CAN)可以设低一些。
第二,合理利用分组
STM32支持几种分组方式,按我的经验,嵌入式场景用2位抢占+2位响应的分组比较多,够用又不会太复杂。
第三,中断函数要快进快出
进中断后赶紧把数据取出来、标志位置好,然后立刻出去。复杂的处理放到主循环里去做。
说说我的真实踩坑经历有一回做无人机项目,用的是STM32F407。飞控要求姿态解算要稳定,我单独写了个定时器中断来做这事,优先级设的5。
后来加了GPS模块,串口中优先级设的4。按理说GPS应该更快才对,但实际跑起来,姿态数据抖得厉害。
排查了三天,最后发现是串口中断优先级设太高了——GPS数据一来就打断姿态解算,数据时序全乱了。
解决方法很简单:把串口优先级改成6,低于姿态解算的那个中断。问题迎刃而解。
所以你看,优先级这东西真不是随便设设就行的,得结合整个系统的时序来考虑。
总结一下STM32中断优先级这块,关键就几点:数值越小优先级越高;抢占优先级决定能不能嵌套;响应优先级决定同时发生时的先后顺序;中断函数要快进快出;最重要的一点——结合业务需求来设,别偷懒。
暂无评论