uCOS-II中断嵌套问题
有一个问题需要大侠指导下;假设
某MCU具有中断嵌套功能,在进入中断后可以立即开中断。
已经知道ucos支持中断嵌套,实质是通过OSIntNesting累加来跟踪中断。
现在的问题是:
若
1.cpu在任务1执行。。。。
2.中断1发生,程序进入中断1,还没有来得及做OSIntNesting++;更高优先级的中断2发生了,
3.中断2开始执行,这时OSIntNesting++;并在本中断2中让更高优先级的任务2就绪。
3.中断2执行末尾,此时OSIntNesting==0,执行任务切换,,,,
问题发生在这里,由于ucos在中断1发生时,没有来得及让OSIntNesting++中断2就发生了;从而导致中断2执行末尾发生了任务切换,这是不允许的,因为中断1还在被中断中。。。。
请问这种一进入中断就允许中断嵌套的CPU,中断程序怎么写呢?琢磨很久,还是不大明白。。 CPU_CRITICAL_ENTER(); /* 关全局中断*/
OSIntNesting++; /* Tell uC/OS-II that we are starting an ISR */
CPU_CRITICAL_EXIT(); /* 开全局中断*/
保证了OSIntNesting++; 操作的原子性。 goink 小桂
你好!
如果中断2在 执行 CPU_CRITICAL_ENTER(); 而还没有进入OSIntNesting++; 就发生呢? 比如在STM32下
#defineOS_ENTER_CRITICAL(){cpu_sr = OS_CPU_SR_Save();}
#defineOS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);}
又
CPU_SR_Save
MRS R0, PRIMASK ; set prio int mask to mask all (except faults)
CPSID I ;除能PRIMASK(CPSID i)——置位相应的位(就是关中断)
BX LR
CPU_SR_Restore
MSR PRIMASK, R0
BX LR
注:
PRIMASK 这是个只有单一比特的寄存器。在它被置1后,就关掉所有可屏蔽的异常,
只剩下NMI和硬fault可以响应。它的缺省值是0,表示没有关中断。
这就保证了执行 CPU_CRITICAL_ENTER() 时不会有中断发生了呀。
引例:
void SysTickHandler(void)
{
OS_CPU_SRcpu_sr;
OS_ENTER_CRITICAL();//保存全局中断标志,关总中断/* Tell uC/OS-II that we are starting an ISR*/
OSIntNesting++;
OS_EXIT_CRITICAL(); //恢复全局中断标志
OSTimeTick(); /* Call uC/OS-II's OSTimeTick(),在os_core.c文件里定义,主要判断延时的任务是否计时到*/
OSIntExit();//在os_core.c文件里定义,如果有更高优先级的任务就绪了,则执行一次任务切换
} MRS R0, PRIMASK ; set prio int mask to mask all (except faults)
------>中断好像可以在这里发生-------------------------->进入更高级中断------->
CPSID I ;除能PRIMASK(CPSID i)——置位相应的位(就是关中断) 是的,有这种可能,所以我感觉上面两句调换一下顺序会好一点。 回复【楼主位】jishanlaike阿弱
-----------------------------------------------------------------------
对于Cortex-M3,uCOS的任务切换是由pendsv中断实现的,而pendsv中断的优先级最低,
所以即使”中断2执行末尾发生了任务切换“,真正的任务切换也不会发生,只是触发了pendsv中断了而已,
只有中断1执行完后,pendsv中断才会执行,因为pendsv的中断优先级最低。
下面是uCOS,Cortex-M3任务切换的代码:
OSCtxSw
LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch)
LDR R1, =NVIC_PENDSVSET
STR R1,
BX LR
OSCtxSw只是触发pendsv中断而已,真正的任务切换在pendsv中断服务程序中,而且pendsv中断的优先级在OSStartHighRdy中被设置为
最低,如OSStartHighRdy:
OSStartHighRdy
LDR R0, =NVIC_SYSPRI14 ; Set the PendSV exception priority
LDR R1, =NVIC_PENDSV_PRI
STRB R1, 【6楼】 feng200808 :
你好!
是的对于CM3而言,确实是这样,还有晚来中断也会出现这种情况,例如:中断1没有执行任何一条指令,中断2就执行了(中断2是晚到的高优先级任务)
但是:uCOS-II不是专门针对CM3设计的,CM3不会出现这种问题
而有很多的MCU都有中断嵌套功能,只要是中断嵌套的MCU,感觉就会出现这种情况,关键是这些MCU并没有CM3的PendSV这种先进功能啊,这些MCU怎么办呢?? 这个命题没有解答么?嘎嘎。。。。。。 回复【7楼】jishanlaike阿弱
-----------------------------------------------------------------------
如果是这样的话,
(1)在中断1和中断2的末尾可以不进行任务切换的,即OSIntExit()可以不执行,只进行
OS_ENTER_CRITICAL();
OSIntNesting--;
OS_EXIT_CRITICAL();即可,(只在节拍器的中断程序末尾执行OSIntExit())。
(2)节拍器的中断优先级设置到最低。
(3)其实中断1和中断2的服务程序只要不用到和OSIntNesting相关的函数,
OSIntNesting++;和OSIntNesting--;也可以不要,中断程序会更加简洁。
ISR程序中是否处理OSIntNesting,以及在ISR程序末尾是否进行任务切换,可以根据应用而定,并不是非得要处理不可的;
个人之见,欢迎拍砖。。。 feng200808:你的想法很有启发性!
假设有10个中断优先级,有10个中断服务程序与之对应,其中有9个不进行任务切换,那么这9个的优先级必须高于所有另外1个的中断优先级了。。。。
即:不包换任务切换的必须高于有任务切换的,以防止被嵌套,好像只有一个优先级可以进行任务切换。。。。。。。
难道需要建立一个最高优先级的专门用于任务切换的任务?。。。。。。。 回复【10楼】jishanlaike阿弱
-----------------------------------------------------------------------
“好像只有一个优先级可以进行任务切换。。。。。。。”
恩,的确会是这样,这么做还是有一定的局限性 mark 就我所知,arm7/arm9进入中断后其它中断都是被屏蔽的吧,除非清除psr中的中断屏蔽位。
想要中断嵌套的话得手动清除中断屏蔽位,而程序员得负责在这之前做好上下文环境的保护。 uCOS的设计思想就是如果产生中断嵌套,就等到所有的中断处理程序都结束,嵌套层数为1时才进行任务调度。只要按照规则编写中断处理程序就没有问题。 对于Cortex-M3,uCOS的任务切换是由pendsv中断实现的,而pendsv中断的优先级最低,
所以即使”中断2执行末尾发生了任务切换“,真正的任务切换也不会发生,只是触发了pendsv中断了而已,
只有中断1执行完后,pendsv中断才会执行,因为pendsv的中断优先级最低。
下面是uCOS,Cortex-M3任务切换的代码:
OSCtxSw
LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch)
LDR R1, =NVIC_PENDSVSET
STR R1,
BX LR
OSCtxSw只是触发pendsv中断而已,真正的任务切换在pendsv中断服务程序中,而且pendsv中断的优先级在OSStartHighRdy中被设置为
最低,如OSStartHighRdy:
OSStartHighRdy
LDR R0, =NVIC_SYSPRI14 ; Set the PendSV exception priority
LDR R1, =NVIC_PENDSV_PRI
STRB R1,
feng200808 分析得比较透彻,即使嵌套由于有PENDSV这种保护机制,也不会出问题,其实发生任务切换是在最后一个中断执行完后,并且中断打开的情况下才发生的 其实这个问题跟ucos并没有关系,是所有RTOS都会面对的问题。
解决问题的方法是依赖CPU移植代码的,对于Cortex-M3,上面分析过没有问题,因为它是有PendSV和NVIC的。
对于ARM7,ARM9,由于进入IRQ和FIQ硬件会关闭相应的中断,你只要在中断环境里做好现场保护之后,重新打开中断之前,把OSIntNesting用汇编语言加1就可以了。
以我多年经验来断言,ucos系统的不稳定大多是开发者移植的问题、上层应用的设计问题导致的,ucos本身并没有过错,是经得起考验的。 回复【14楼】micheal_rz
ucos的设计思想就是如果产生中断嵌套,就等到所有的中断处理程序都结束,嵌套层数为1时才进行任务调度。只要按照规则编写中断处理程序就没有问题。
-----------------------------------------------------------------------
对的,CPU移植代码就是要按照这样的设计思想来移植才争正确。
页:
[1]