在看apollo3 代码时发现下面这个函数
void WsfSetOsSpecificEvent(void)
{
if(xRadioTaskEventObject != NULL)
{
BaseType_t xHigherPriorityTaskWoken, xResult;
if(xPortIsInsideInterrupt() == pdTRUE) {
//
// Send an event to the main radio task
//
xHigherPriorityTaskWoken = pdFALSE;
xResult = xEventGroupSetBitsFromISR(xRadioTaskEventObject, 1,
&xHigherPriorityTaskWoken);
//
// If the radio task is higher-priority than the context we're currently
// running from, we should yield now and run the radio task.
//
if ( xResult != pdFAIL )
{
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
else {
xResult = xEventGroupSetBits(xRadioTaskEventObject, 1);
//
// If the radio task is higher priority than the context we're currently
// running from, we should yield now and run the radio task.
//
if ( xResult != pdFAIL )
{
portYIELD();
}
}
}
}
这是FreeRTOS发送一个事件标志组,xPortIsInsideInterrupt
这个函数判断是否在中断中,进而调用判断是否调用FromISR结尾的api,下面看下原理
static portFORCE_INLINE BaseType_t xPortIsInsideInterrupt( void )
{
uint32_t ulCurrentInterrupt;
BaseType_t xReturn;
/* Obtain the number of the currently executing interrupt. */
__asm
{
mrs ulCurrentInterrupt, ipsr
}
if( ulCurrentInterrupt == 0 )
{
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
return xReturn;
}
读IPSR寄存器,0表示当前没有中断在运行,非0表示正在运行的中断号,即处于中断中,所以要用FromISR结尾的api