zl程序教程

您现在的位置是:首页 >  其它

当前栏目

FreeRTOS - 中断使用注意

注意 中断 freeRTOS 使用
2023-09-11 14:19:53 时间

原文地址:http://www.cnblogs.com/god-of-death/p/6886823.html

 

 

注意点:
1、首先要将中断的嵌套全部设置为抢占优先级。


2、将freertos系统内核中断(configKERNEL_INTERRUPT_PRIORITY)的优先级设置成最低。


3、将freertos的最大系统调用中断优先级(configMAX_SYSCALL_INTERRUPT_PRIORITY)设置为合适的优先级,比如11。


4、如果有用户中断函数调用到freertos提供的系统函数,一定要使用带FromISR的freertos提供的系统函数,并且这个用户中断的优先级一定要在configKERNEL_INTERRUPT_PRIORITY和configMAX_SYSCALL_INTERRUPT_PRIORITY的优先级之间,一般configKERNEL_INTERRUPT_PRIORITY设置为单片机最低优先级,configMAX_SYSCALL_INTERRUPT_PRIORITY是FreeRTOS系统能够屏蔽的最高优先级,规定中断优先级比configMAX_SYSCALL_INTERRUPT_PRIORITY高不能调用FreeRTOS API(如此高的中断优先级,已经不在FreeRTOS系统控制范围内)。

 

5、最低优先级的中断可以中断最高优先级的任务,所有任务不能抢占任何中断函数

 

6、pxHigherPriorityTaskWoken 为了保证总是最高优先级的任务被执行,如果中断函数使比被中断打断的任务的优先级更高任务退出阻塞,在中断函数结束之前进行一次上下文切换,退出中断后执行这个更高优先级的任务,否则这个高优先级任务在CPU回到被打断任务后的下一个tick执行(有时候可以感到明显的延时,不一定是一个tick)。

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    if(GPIO_Pin == GPIO_PIN_1)
    {
        debug("2W5500 interup.................");
        xTaskNotifyFromISR( xTaskhandle2W5500, 0x01, eSetBits, &xHigherPriorityTaskWoken );
    }
    if(GPIO_Pin == GPIO_PIN_2)
    {
        debug("1W5500 interup.................");
        xTaskNotifyFromISR( xTaskhandle1W5500, 0x01, eSetBits, &xHigherPriorityTaskWoken );
    }
    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );  //没有这句,上面两句的事件响应速度慢
}

 

 

为什么要有FromISR:

1、中断函数里面不允许任务切换等待,比如在任务中调用xTimerStart(XXXtimerHandle,pdMS_TO_TICKS( 100 )),可能使任务阻塞100ms,但是中断中不会阻塞100ms。所以xSemaphoreGiveFromISR()最好不要在中断函数中调用,因为不会阻塞,直接返回结果。

2、中断里面不能自动进行上下文切换,所以FromISR函数里面不能自动进行上下文切换(“161204_Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide”文档186页有介绍,主要原因是高效、避免不确定性、FreeRTOS移植简单),而在任务中调用的没有FromISR的函数是要自动进行上下文切换(保证最高优先级任务被执行)