用了好久的FreeRTOS以前只是知道,如果在中断服务程序中调用某一些FreeRTOS的API函数时需要注意,如果有ISR版本的一定要调用,末尾带ISR的函数,并且要调用系统的API函数,中断服务程序的中断优先级不能高于配置宏(configMAX_SYSCALL_INTERRUPT_PRIORITY)的值这是为什么呢。刚好今天受台风影响只能在家里窝着,所以就想着趁有时间看看这一部分的内容,研究一下为什么,那么废话不多说开干。
找了几个函数简化一些安全检查的内容再把一些宏函数替换后对比观察了下内容如下:
TickType_t xTaskGetTickCount( void ) { TickType_t xTicks; { xTicks = xTickCount; } return xTicks; } /*-----------------------------------------------------------*/ TickType_t xTaskGetTickCountFromISR( void ) { TickType_t xReturn; UBaseType_t uxSavedInterruptStatus; portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); uxSavedInterruptStatus = portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR(); { xReturn = xTickCount; } portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); return xReturn; }
其中的函数
分别解析下
- portASSERT_IF_INTERRUPT_PRIORITY_INVALID这是一个宏对应的真实函数为vPortValidateInterruptPriority,具体内容如下,这个函数解释了为什么不能在优先级高于configMAX_SYSCALL_INTERRUPT_PRIORITY配置宏的中端中调用系统API函数了。
void vPortValidateInterruptPriority( void ) { uint32_t ulCurrentInterrupt; uint8_t ucCurrentPriority; //参考内核指南,这个命令是获取当前的中断号 ulCurrentInterrupt = vPortGetIPSR(); /*portFIRST_USER_INTERRUPT_NUMBER 是一个和芯片相关的用户中断号 在M3、M4的芯片上就是15以后是外部中断的中断号所以这里配置成16 判断是不是在外部中断中调用的API函数,如果是执行if里的内容*/ if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) { /*根据中断服务函数的中断号获取当前中断的优先级设置*/ ucCurrentPriorit