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

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

3天内不再提示

中断里面这样延时,有点猛~

嵌入式情报局 来源:TopSemic嵌入式 2023-11-12 11:40 次阅读

最近一工程师向我反馈一个问题,Ta说:我程序会死在这一行,大概是什么原因?

828abfec-803f-11ee-939d-92fbcf53809c.png

以下是Ta所说程序会死的地方,

8295b14a-803f-11ee-939d-92fbcf53809c.png

用过HAL库的童鞋应该比较熟悉这个函数,它是延时函数。

82aca7c4-803f-11ee-939d-92fbcf53809c.png

拿到工程代码后我就开始Debug之旅了,现象确实如Ta所说,刚开始Hal_delay函数调用没问题,但是过了几秒之后就卡住了。因为该函数的计时是依赖Systick中断,这个现象说明Systick中断进不去了,通过debug模式下Systick中断服务函数里加断点,可以验证这一点。但是为什么刚开始好好的,后面就进不去中断了呢?最初我想是不是Systick中断被关掉了,通过查看Systick寄存器,发现并没有,Systick依然在计时并且中断使能也没有关。

程序里初始化时开启了RTC中断,周期是1s,Systick中断周期是1ms。刚开始时这两个中断都能进,几秒之后这俩中断就都进不去了。

82b81e9c-803f-11ee-939d-92fbcf53809c.png

这个现象看起来确实挺诡异,因为给我的代码里糅杂了很多业务代码,写的也有点乱,看的我很烦躁,后来还是静下心来仔细的分析,找到了问题所在。

原因是这样:Ta在RTC的中断服务函数里,在某个分支函数里调用了Hal_delay函数。因为RTC的中断优先级和Systick中断优先级一样,所以Systick中断就进不去了,导致Hal_delay函数也就执行不过去了,所以就出现了所谓的卡死现象。之所以刚开始没问题,过了几秒才出问题,是因为刚开始前几秒的RTC中断服务函数里没有进到调用Hal_delay函数的那个分支处理里,Ta是在初始化几秒之后,设置了一个标志位,导致后来RTC中断处理里调用了Hal_delay函数。

问题找到了,如何解决呢?

最简单的方法是,把Systick和RTC的中断优先级设置不一样,让Systick优先级比RTC高一点,这样可以保证Systick中断能够打断RTC中断,从而不会卡死。

ARM Cortex MCU的中断控制器英文名叫做NVIC,Nested Vectored Interrupt Controller,翻译过来就是嵌套向量中断控制器,所谓中断嵌套是指当正在执行一个中断服务程序时,这时如果来了优先级更高的中断,新来的中断会打断原来还没有处理完的中断服务程序,等新中断处理完毕之后再回到原中断服务继续处理。

Cortex-M0/M0+中断优先级设置非常简单,只需要通过CMSIS标准接口函数__NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)即可完成,优先级只有4个,分别为0、1、2、3,数字越小优先级越高。

问题解决了,总结不能少:

1)我当时找这个问题花了较长时间,反思一下,其实是可以更快的定位问题的。当卡死在Hal_delay函数时,首先应该去分析是哪里调用这个函数导致卡死的,因为工程里调用的地方有好多处,可以通过在可能出现问题的调用前给一个全局变量赋不同的值,卡住时看全局变量,就可以定位到是从哪里进去的。这样倒着往前推,可以更快的定位问题。

2)通常情况下中断服务函数应该尽可能的短,最好不要在中断里做延时之类的占用CPU时间长的工作。

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

    关注

    31

    文章

    5386

    浏览量

    121519
  • 函数
    +关注

    关注

    3

    文章

    4350

    浏览量

    63128
  • Systick
    +关注

    关注

    0

    文章

    62

    浏览量

    13197

原文标题:中断里面这样延时,有点猛~

文章出处:【微信号:嵌入式情报局,微信公众号:嵌入式情报局】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    相关推荐

    力源电池-纽扣电池系列:CR系列锂扣式产品介绍

    深圳鸿合智远|力源电池-纽扣电池系列:CR系列锂扣式产品介绍
    的头像 发表于 12-02 11:03 347次阅读
    力源电池-纽扣电池系列:CR系列锂<b class='flag-5'>猛</b>扣式产品介绍

    延时开关怎么调时间长短

    延时开关是一种常见的电子控制设备,广泛应用于各种场合,如照明、空调、风扇等。它可以根据用户的需求,设定一定的延时时间,实现自动控制。 一、延时开关的工作原理 延时开关的基本组成
    的头像 发表于 08-19 15:46 2341次阅读

    延时开关上l和a是什么意思

    延时开关是一种常见的电子控制元件,广泛应用于各种电子设备和系统中。它可以实现对电路的自动控制,使电路在一定的延时后自动接通或断开。在延时开关的标识中,L和A通常代表不同的意义。 一、延时
    的头像 发表于 08-19 15:45 6984次阅读

    2024这款AIPC迷你主机有点

    。未来,随着AI技术的不断发展和普及,我们有理由相信,像华硕PN65这样的高性能迷你主机将会更加普及,成为更多用户的心仪之选。 不管你是玩游戏,直播,视频剪辑还是正常办公或者你正在寻找一款既小巧又强大的电脑主机,那么华硕PN65绝对值得你深入了解和考虑。
    的头像 发表于 07-30 17:35 654次阅读
    2024这款AIPC迷你主机<b class='flag-5'>有点</b><b class='flag-5'>猛</b>

    实现一个ns级的延时函数,延时时间不可控的原因?

    现在要实现一个ns级的延时函数,用nop指令已经调试完成,然而问题在于这个延时函数经常被中断,导致延时时间不可控,我在延时函数前后加了 p
    发表于 06-26 06:50

    esp32s3在中断里面printf会重启,怎么才能在中断里面printf?

    我在定时中断里面 想打印信息,发现printf 会导致重启 应该是 中断堆栈 和 任务堆栈 冲突的问题把 我想实时获取 中断的打印信息,不想通过 消息队列 在任务级别打印 应该怎么处理
    发表于 06-12 06:30

    FreeRtos能否直接读取Rtos的系统时钟计数器来实现延时统计,改如何读取呢?

    关于200~300uS的延时 1 能否直接读取Rtos的 系统时钟计数器来 实现延时统计,改如何读取呢? 2 通过独立的定时器中断来实现,这样感觉
    发表于 04-29 08:40

    在stm32使用freertos时首先要移植startup.s文件将里面中断函数名对接一下,为什么我找不到?

    问题是这样的,我看了别人的教程在stm32使用freertos时首先要移植startup.s文件将里面中断函数名对接一下。 但是我在FreeRTOS官网下载的源码里面的demo历程,
    发表于 04-29 07:32

    请问ucos-III中断保护放在中断回调函数还是中断里面?

    请教下ucos-III 中断保护放在中断回调函数还是中断里面? 1. 中断函数 void DMA2_Stream6_IRQHandler(
    发表于 04-23 07:44

    新火种AI|如何看待AI蹭热点,合成假新闻?官方:治疗AI乱象,务必下

    针对AI造谣乱象,官媒明确发声:欲去“沉疴”还需“药”。
    的头像 发表于 04-19 21:59 310次阅读
    新火种AI|如何看待AI蹭热点,合成假新闻?官方:治疗AI乱象,务必下<b class='flag-5'>猛</b>药

    STM8 PWM溢出中断或比较中断执行中断程序有延时是怎么回事?

    在PWM溢出或是比较中断时,进中断将一个IO口翻转,然后执行中断程序(用延时3us测试),屏蔽中断程序,可以看IO翻转边沿与PWM翻转边沿对
    发表于 04-11 07:54

    请问使能TIM的中断能放在IRQHandler里面吗?

    RT, 比如运行完这次中断就要disable这个TIM的中断,能在IRQHandler里面直接用HAL设置Disable吗? 还是说要在IRQHandler和Callback函数之外才能关闭?
    发表于 04-09 07:21

    Systick到底是用作延时好还是用作定时好?都有什么优缺点?

    功能,作基础定时用,而不建议用作延时功能,方便后面程序移植. 最好有个定论,方便后面程序的移植,不能各自玩各自的,一个公司里面写程序的风格和标准需要统一。 想问下各位,Systick到底是用作延时好?还是用作定时好,都有什么
    发表于 04-08 07:37

    信号通过ADC DMA DAC进行转换,非空状态下触发定时器中断进行延时中断结束还会继续DMA转换吗?

    信号通过ADC DMA DAC进行转换,其中需要延时 我的想法是 把ADC数据存入FIFO,然后根据DMA_GetFIFOStatus()函数判断FIFO状态,非空状态下触发定时器中断进行延时
    发表于 04-03 08:06

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

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