rtthread开关中断
1 rtthread開關中斷函數(cortex-m)
/** rt_base_t rt_hw_interrupt_disable();*/ .global rt_hw_interrupt_disable .type rt_hw_interrupt_disable, %function rt_hw_interrupt_disable:MRS r0, PRIMASKCPSID IBX LR/** void rt_hw_interrupt_enable(rt_base_t level);*/ .global rt_hw_interrupt_enable .type rt_hw_interrupt_enable, %function rt_hw_interrupt_enable:MSR PRIMASK, r0BX LR2 中斷嵌套
我能看到rtthread中很多地方都會使用,開關中斷。但是開關中斷是否支持嵌套呢?
int global1; int global2; void foo(void) {rt_base_t level = rt_hw_interrupt_disable();global1++;rt_hw_interrupt_enable(level); //在這個地方開中斷,調用后中斷一定打開嗎? }void bar(void) {rt_base_t level = rt_hw_interrupt_disable();foo(); //執行后中斷會被打開嗎?global2++; //這段代碼安全嗎?rt_hw_interrupt_enable(level); }2.1 rt_hw_interrupt_disable
rt_hw_interrupt_disable:MRS r0, PRIMASK ;保存PRIMASK到r0中CPSID I ;關閉中斷BX LR ;返回調用rt_hw_interrupt_disable()是通過匯編語言實現的。首先將PRIMASK值保存到r0中,然后是關閉中斷。最后執行調用返回。根據ARM的調用規范,函數返回后,返回值保存在r0寄存器中。所以rt_hw_interrupt_disable()的返回值就是當前函數調用前的PRIMASK值。那么PRIMASK值跟什么有關系呢?下面是Arm?v7-M Architecture Reference Manual的描述:
也就是說PRIMASK代表著可屏蔽中斷的狀態。如果是1代表當前中斷禁止,如果是0代表當前中斷使能。由此可以看出,rt_hw_interrupt_disable()的返回值代表當前的函數調用前的中斷狀態。之后調用CPSID I來關閉中斷,所以rt_hw_interrupt_disable()調用后當前中斷一定是關閉的,同時PRIMASK的值也一定是1。接下來繼續分析rt_hw_interrupt_enable()函數。
2.2 rt_hw_interrupt_enable
//void rt_hw_interrupt_enable(rt_base_t level); rt_hw_interrupt_enable:MSR PRIMASK, r0 ;將level的值保存到PRIMASK寄存器BX LR ;調用返回根據ARM調用規范, 函數的第一個參數由r0寄存器傳遞,所以r0中保存的是level的值,rt_hw_interrupt_enable()的功能就是將level值寫入到PRIMASK寄存器中。所以rt_hw_interrupt_enable()執行后,開不開中斷取決于level的值,開關中斷是成對使用的,因為level是rt_hw_interrupt_disable()的返回值。所以這樣就實現了中斷的嵌套。繼續閱讀下面示例,來理解嵌套。
3 示例
3.1 test()調用前中斷狀態是使能的情況
int global_level1; int global_level2; int global_level3;void test(void) {rt_base_t level1 = rt_hw_interrupt_disable(); //此函數執行前中斷為使能,所以level1 = 0rt_base_t level2 = rt_hw_interrupt_disable(); //此函數執行前中斷已經被關閉了,所以level2 = 1rt_base_t level3 = rt_hw_interrupt_disable(); //此函數執行前中斷已經被關閉了,所以level3 = 1global_level3++;rt_hw_interrupt_enable(level3);//把level3賦值給PRIMASK后,PRIMASK=1,中斷仍然關閉global_level2++;rt_hw_interrupt_enable(level2);//把level2賦值給PRIMASK后,PRIMASK=1,中斷仍然關閉global_level1++;rt_hw_interrupt_enable(level1);//把level1賦值給PRIMASK后,PRIMASK=0,中斷打開 }3.2 test()調用前中斷狀態是關閉的情況
int global_level1; int global_level2; int global_level3;void test(void) {rt_base_t level1 = rt_hw_interrupt_disable(); //此函數執行前中斷已經被關閉了,所以level1 = 1rt_base_t level2 = rt_hw_interrupt_disable(); //此函數執行前中斷已經被關閉了,所以level2 = 1rt_base_t level3 = rt_hw_interrupt_disable(); //此函數執行前中斷已經被關閉了,所以level3 = 1global_level3++;rt_hw_interrupt_enable(level3);//把level3賦值給PRIMASK后,PRIMASK=1,中斷仍然關閉global_level2++;rt_hw_interrupt_enable(level2);//把level2賦值給PRIMASK后,PRIMASK=1,中斷仍然關閉global_level1++;rt_hw_interrupt_enable(level1);//把level1賦值給PRIMASK后,PRIMASK=1,中斷仍然關閉 }以上就把rtthread中斷嵌套分析清楚了。
總結
以上是生活随笔為你收集整理的rtthread开关中断的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 考研数学笔记11~15
- 下一篇: Python事件调度器定时任务sched