初中生
最后登录1970-1-1
在线时间 小时
注册时间2014-5-23
|
举一个三层嵌套的实例说明问题:
#include "FreeRTOS.h"
#include "task.h"
void ThirdLayer_ISR(void) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
BaseType_t xSavedStatus1, xSavedStatus2, xSavedStatus3;
// 第一层临界区进入
xSavedStatus1 = taskENTER_CRITICAL_FROM_ISR();
/* 第一层临界区操作 */
volatile uint32_t sharedVar1 = 0;
sharedVar1++;
// 第二层临界区进入
xSavedStatus2 = taskENTER_CRITICAL_FROM_ISR();
/* 第二层临界区操作 */
volatile uint32_t sharedVar2 = 0;
sharedVar2++;
// 第三层临界区进入
xSavedStatus3 = taskENTER_CRITICAL_FROM_ISR();
/* 第三层临界区操作 */
volatile uint32_t sharedVar3 = 0;
sharedVar3++;
// 必须按相反顺序退出
taskEXIT_CRITICAL_FROM_ISR(xSavedStatus3);
taskEXIT_CRITICAL_FROM_ISR(xSavedStatus2);
taskEXIT_CRITICAL_FROM_ISR(xSavedStatus1);
// 必要时触发上下文切换
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
因为系统设定的configMAX_SYSCALL_INTERRUPT_PRIORITY值是确定的,假设为11,其中三次调用taskENTER_CRITICAL_FROM_ISR()都是用的一样的屏蔽值11,
那么三次使用taskEXIT_CRITICAL_FROM_ISR()退出时,xSavedStatus3,xSavedStatus2的值其实是一样的,只有xSavedStatus1不一样,也就是说所有三层调用后中断屏蔽环境是一样的,直到最后一层打开所有中断。
如果使用taskENTER_CRITICAL()跟taskEXIT_CRITICAL(),因为这两个函数最终实现使用了uxCriticalNesting--;如下
void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
if( uxCriticalNesting == 1 )
{
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
}
}
void vPortExitCritical( void )
{
configASSERT( uxCriticalNesting );
uxCriticalNesting--;
if( uxCriticalNesting == 0 )
{
portENABLE_INTERRUPTS();
}
}
也只有最后一次退出时才会真正执行portENABLE_INTERRUPTS()打开所有中断,
也就是说如果中断中如果也同样使用taskENTER_CRITICAL()跟taskEXIT_CRITICAL()不是也能跟taskENTER_CRITICAL_FROM_ISR(),taskEXIT_CRITICAL_FROM_ISR一样的效果?
那使用带ISR的屏蔽函数优有何意义?
|
|