如何判断CPU是否正在执行中断函数?

640?wx_fmt=jpeg


1.这是一个有许多经验的攻城狮都遇到过的坑,本文教你正确绕过这个坑;


2.教大家了解__get_CONTROL的用法,及xQueueSendxQueueSendFromISR的区别;


问题来源


今天在FreeRTOS系统上移植了部分别人写的代码,移植前仔细看了下源码,确认没问题后,编译,下载,运行,突然“死机了”······


于是,我又再次确认了移植的代码,没有发现Bug所在。此时,我开启了在线调试功能,发现程序死在了“vPortEnterCritical”函数中的断言语句里。如下:


640?wx_fmt=png


解决问题的过程


我解决问题还是按照常规思维,一步一步跟踪,很多问题其实都是类似道理,有规律可循。


1.查看configASSERT断言做了什么事?

跟踪代码:

 
 

#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }

其中,里面taskDISABLE_ INTERRUPTS();就是关中断的意思。紧跟着后面执行了for( ;; );


看到这里,我明白了一点,就是死在for( ;; );里面了。


2.进一步查找问题

我又开始了思考,为什么会执行到这里来呢? 为什么会执行portDISABLE_INTERRUPTS(); uxCriticalNesting++;   if( uxCriticalNesting == 1 )等这些语句呢?


这就是我们常说的“临界段”,这一点我学习RTOS的时候已经明白了,这一个函数肯定会被调用。于是,我把目标锁定了portNVIC_INT_CTRL_REG这个参数:

 
 

#define portNVIC_INT_CTRL_REG        ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )

0xe000ed04?  这个地址,相信之前了解过NVIC的都知道,就是Interrupt control state register.即中断控制状态寄存器。


3.确定问题点

从上面的分析,其实问题都已经浮现出来了。于是查看了【Cortex-M3权威指南】中相关的内容。(PS:这本手册真的能解决很多问题,翻译成中文,对大部分朋友来说是一件好事)


其实,有这个一个寄存器:控制寄存器(CONTROL),里面讲述的非常清楚:

640?wx_fmt=png


看上图,大概意思就是:在中断模式下,CONTROL[1]为0。于是,又把思路转向了core_cm3.c文件中的源码:

 
 

__ASM uint32_t __get_CONTROL(void) {  mrs r0, control  bx lr }

懂一点汇编的,相信在这里都已经明白,大概意思就是过去控制寄存器状态,这也是我开篇说的,让大家了解的__get_CONTROL


4.在线调试,分析结论

上面分析出来控制寄存器CONTROL,那么我们需要验证是否符合我们预期的效果,通过在线调试,断电就可得出,如下面两图:

a.在非中断情况下的值0x02


640?wx_fmt=png


b.在中断情况下的值0x00


640?wx_fmt=png


至此,问题已经查明就是CONTROL。


get_CONTROL的应用


一般在RTOS实时操作系统中,常常使用队列来处理我们的数据,也就是常说的FIFO(先入先出)。


比如:我们在FreeRTOS系统中,要将UART发送、或者接收的数据加入队列:中断里加入队列,在非中断里加入队列。这个时候,就需要使用get_CONTROL来判断当前是否处于中断函数里。


当然,类似的情况很多,像CAN、I2C、SPI等一样的道理。


举例,CAN总线发送数据加入队列:


640?wx_fmt=png


多说两句


以上的分析,看似很简单,其实包含的内容很多,可能有很多人觉得:这些问题对于我来说是小菜一碟。


说句实话,我和大家一样,都是慢慢学习过来的,这里面跳过的坑其实很多,是因为我跳过了太多的坑,所以才会对一些问题更加了解。


上面类似的问题,在我学习RTOS、移植CANOpen等等那些时候都有遇到过,想要知道我遇到那些问题,处理起来难不难,明确回答:很多问题在初学的时候都很难,但我还是走过来了。


说到这里,多说一句,关于问问题的话,后台每天都有许多人问我问题,但是有些问题其实真的很简单,比如:编译有个变量未调用的警告、重复定义,多了一个分号等,这些看一下提示都知道。不要告诉我你英语差,我英语初高中从来都没有及格过,依然还是得看英文手册。确实不懂,安装一个翻译软件不难吧。

640?

640?wx_fmt=jpeg

1.AI芯片,是噱头还是趋势?

2.Linux 内核版本那么多,你的嵌入式项目要选哪个版本?

3.用STM32做开发,为什么要先开启外设模块时钟?

4.安卓,是嵌入式工程师不可逾越的坎吗?

5.单片机按键软硬件设计技巧!

6.如何才能写出好的软件设计文档?640?wx_fmt=gif

免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值