2.1调度方式
两种方式:抢占式、时间片式。
抢占式:每个任务都有不同的优先级。任务一直运行直到被高优先级打断或者处于阻塞状态才会进行任务切换。类似于裸机中的中断。任务优先级与中断优先级相似。
时间片式:每个任务都有相同的优先级。任务执行固定的时间片个数或者遇到阻塞才会进行任务切换。
配置方式:
//在FreeRTOSConfig.h
#define configUSE_PREEMPTION 1 //1为抢占式
//FreeRTOS.h
#ifndef configUSE_TIME_SLICING
#define configUSE_TIME_SLICING 1 //1 开启时间片;0关闭时间片
#endif
时间片调度和抢占式调度我们一般都是开启了的,这样优先级相同时,使用时间片调度,优先级不同时,使用抢占式调度。
2.2 临界段
2.2.1 临界段基本概念
什么是临界段?一句话,不允许任何中断打断或任务切换的代码段。
为何要有临界段?
1,任务间通信全局变量的读取或修改变量。例如:内存操作、校验码等。
2,调用不可重入函数。
缺点:
影响操作系统的实时性。如果在临界代码段有中断发生,中断不会立即执行,对于某些系统可能会引起严重后果。
临界段:
少用。如果一定要用这段代码一定要执行时间短,更不能有引发死循环的逻辑操作。
2.2.2重点API介绍
//不带中断保护版本,不可嵌套
taskENTER_CRITICAL();//进入临界段
taskEXIT_CRITICAL();//退出临界段
//带中断保护版本 ,可嵌套
taskENTER_CRITICAL_FROM_ISR(); //进入临界段
taskEXIT_CRITICAL_FROM_ISR(x);//退出临界段
2.2.3 如何使用
任务代码进入临界段可以调用以下API:
taskENTER_CRITICAL();//进入临界段
taskEXIT_CRITICAL();//退出临界段
//示例代码
void task_test(void* pvParameters)
{
taskENTER_CRITICAL();
printf("临界代码段\r\n");
taskEXIT_CRITICAL();
vTaskDelay(100);
}
中断服务程序临界段可以调用一下API
taskENTER_CRITICAL_FROM_ISR(); //进入临界段
taskEXIT_CRITICAL_FROM_ISR();//退出临界段
//示例代码
void xxx_IRQHandler()
{
UBaseType_t status;
status= taskENTER_CRITICAL_FROM_ISR(); //进入临界段
printf("临界代码段\r\n");
taskENTER_CRITICAL_FROM_ISR(status); //退出临界段 必须成对存在
}