0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

黄工的嵌入式技术圈 来源:黄工的嵌入式技术圈 2020-03-12 11:25 次阅读

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

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

Ⅰ问题来源

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

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

Ⅱ解决问题的过程

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

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),里面讲述的非常清楚:

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

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

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

4.在线调试,分析结论

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

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

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

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

Ⅲget_CONTROL的应用

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

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

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

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

Ⅳ多说两句

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

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

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

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

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10436

    浏览量

    206523
  • RTOS
    +关注

    关注

    20

    文章

    775

    浏览量

    118781
  • FreeRTOS
    +关注

    关注

    12

    文章

    473

    浏览量

    61345
收藏 人收藏

    评论

    相关推荐

    如果单片机的程序正在执行中断服务程序,期间又有比正在执行中断级别高的中断结果会如何?

    请教一下,如果单片机的程序正在执行中断服务程序,期间又有比正在执行中断级别高的
    发表于 04-09 07:46

    执行判断CPU怎么设计?

    需要使用JUMP函数跳出吗,还是可以在EXE阶段的乘法器后面的精确乘法器上加一个使能段,根据预测结果判断要不要激活精确乘法器。但是这样会不会让EXE阶段的时钟周期过长?
    发表于 03-30 18:18

    CPU中断程序:从硬件看什么是中断

    CPU响应中断转去执行中断服务程序前,需要把被中断程序的现场信息保存起来,以便执行
    发表于 03-26 11:36 201次阅读
    <b class='flag-5'>CPU</b><b class='flag-5'>中断</b>程序:从硬件看什么是<b class='flag-5'>中断</b>?

    GD32 MCU是如何进入中断函数

    用过GD32 MCU的小伙伴们都知道,程序是顺序执行的,但当有中断来的时候程序会跳转到中断函数执行
    的头像 发表于 01-30 09:45 296次阅读
    GD32 MCU是如何进入<b class='flag-5'>中断</b><b class='flag-5'>函数</b>的

    中断函数的基本概念

    单片机:中断函数
    的头像 发表于 12-05 09:08 317次阅读
    <b class='flag-5'>中断</b><b class='flag-5'>函数</b>的基本概念

    reset_primary函数执行流程

    reset_primary函数执行 以CONFIG_BOOT_SYNC_CPU使能为例, 在使能PSCI系统中,不需要使能此宏 。 reset_primary函数
    的头像 发表于 11-02 18:06 292次阅读
    reset_primary<b class='flag-5'>函数</b>的<b class='flag-5'>执行</b>流程

    MCS-51单片机外部中断详解

    CPU执行的过程中,一般来说都是在执行主程序(main函数里面的代码)。如果希望处理其他的功能,可以通过查询的方式进行,判断
    的头像 发表于 11-01 17:48 876次阅读
    MCS-51单片机外部<b class='flag-5'>中断</b>详解

    单片机外部中断的好处

    外部中断是单片机实时地处理外部事件的一种内部机制。当外部事件发生时,单片机的中断系统将迫使CPU暂停正在执行的程序,转而去进行
    的头像 发表于 10-31 15:58 1049次阅读
    单片机外部<b class='flag-5'>中断</b>的好处

    单重中断与多重中断介绍

    单重中断与多重中断 •单重中断CPU执行中断服务程序的过程中不能被打断。当有新的更高优先级的
    的头像 发表于 10-30 16:46 1628次阅读
    单重<b class='flag-5'>中断</b>与多重<b class='flag-5'>中断</b>介绍

    中断是什么意思

    中断是什么? 中断是指计算机在执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前
    的头像 发表于 10-30 16:40 1366次阅读
    <b class='flag-5'>中断</b>是什么意思

    中断是什么意思 中断源的优先级判断 中断控制寄存器有哪些

    中断,是指当计算机执行正常程序时,系统中出现某些急需处理的异常情况和特殊请求,CPU暂时中止正在运行的程序,转去对随机发生的更为紧迫的事件进行处理,处理完毕后,
    的头像 发表于 07-28 15:32 5318次阅读
    <b class='flag-5'>中断</b>是什么意思 <b class='flag-5'>中断</b>源的优先级<b class='flag-5'>判断</b> <b class='flag-5'>中断</b>控制寄存器有哪些

    怎么判断单片机是否起振 如何判断晶振好坏

    该怎么判断单片机是否起振?如何判断晶振好坏?
    发表于 07-21 09:15 1128次阅读
    怎么<b class='flag-5'>判断</b>单片机<b class='flag-5'>是否</b>起振 如何<b class='flag-5'>判断</b>晶振好坏

    Linux Kernel的中断处理函数是否会被其它程序(中断/异常)打断?

    当一个irq/fiq正在执行时 ,是否可能会其它的irq/fiq打断呢?
    的头像 发表于 06-07 17:27 750次阅读
    Linux Kernel的<b class='flag-5'>中断</b>处理<b class='flag-5'>函数</b>中<b class='flag-5'>是否</b>会被其它程序(<b class='flag-5'>中断</b>/异常)打断?

    怎么解决PM退出时中断函数执行顺序的问题呢?

    我的程序中,PM组件没有启动低功耗定时器,完全由RTC闹钟唤醒,RTC闹钟设置有闹钟中断回调函数,目的是闹钟到时候唤醒系统并且执行闹钟中断回调函数
    发表于 05-17 11:43

    单片机中断程序是如何被中断的?

    中断一般是由硬件(例如外设、外部引脚)产生,当某种内部或外部事件发生时,MCU的中断系统将迫使 CPU 暂停正在执行的程序,转而去进行
    的头像 发表于 05-16 14:06 909次阅读
    单片机<b class='flag-5'>中断</b>程序是如何被<b class='flag-5'>中断</b>的?