在使用FreeRTOS的过程中,我们会发现一个函数分为带FromISR和不带FromISR的。这也是FreeRTOS中一再强调的!!在中断中必须调用函数名以FromISR结尾的函数。
具体了解请看FreeRTOS学习笔记——中断与任务切换:https://www.sohu.com/a/253256697_774177,我就不复制转载了。
因此在我编写的代码中我会读取IPSR(中断程序状态寄存器)的值来判断当前是否处理中断状态。
/* read out IPSR register*/
register uint32_t __regIPSR __ASM("ipsr");
例如:
xTaskGetTickCount (FromISR)用于获取系统当前运行的时钟节拍数。
/*
*********************************************************************************************************
* 函 数 名: OS_getOSSysTick
* 功能说明: returns OS based system tick value.
* 形 参: 无
* 返 回 值: time stamp in ms, based on the OS time
*********************************************************************************************************
*/
uint32_t OS_getOSSysTick(void)
{
/* read out IPSR register*/
register uint32_t __regIPSR __ASM("ipsr");
/* regIPSR == 0 if controller is in thread mode */
if (__regIPSR != 0) {
return xTaskGetTickCountFromISR();
} else {
return xTaskGetTickCount();
}
}
vTaskDelayUntil()指定希望解除阻止的绝对(确切)时间。
应当注意,如果vTaskDelayUntil()用于指定过去的唤醒时间,它将立即返回(无阻塞)。因此,如果使用vTaskDelayUntil()定期执行的任务由于某种原因(例如,该任务暂时置于Suspended状态)而导致中止执行,则该任务必须重新计算其所需的唤醒时间。
static void OS_TaskCyclic500ms(void)
{
while(1)
{
uint32_t ulCurrentTime = OS_getOSSysTick();
bsp_LedToggle(LED_Run); /* 运行指示灯 */
vTaskDelayUntil(&ulCurrentTime, os_tskdef_cyclic_500ms.ulCycleTime);
}
}