第二章 任务调度API
v开头的任务表示返回值为void,x开头的任务表示返回值是其他非void
2.1 portSWITCH_TO_USER_MODE()
总结:这个函数只有当MCU有MPU(Memory Protection Unit)内存保护单元才能使用,考虑到一般的单片机没有MPU,不进一步翻译
2.2 vTaskAllocateMPURegions()
总结:略
2.3 xTaskAbortDelay()
函数形式: BaseType_t xTaskAbortDelay( TaskHandle_t xTask);
总结:有一些带延时参数的API函数的调用会使得任务进入阻塞状态,这会让任务等待这个延时结束或者有其他事件触发时,才能让该任务离开阻塞状态,进入就绪状态,例如:
*在任务中调用 vTaskDelay( ) 会让任务进入阻塞状态一段事件,等到延时参数结束后该任务就自动进入就 绪状态
*在任务中调用 ulTaskNotifyTake() 如果notification value为0,则该任务会执行完该函数的延时参数就进 入阻塞状态,直到其他地方give ctification才能让任务进入就绪状态
在这些情况下可以使用 xTaskAbortDelay() 让指定任务马上离开阻塞状态而进入就绪状态
参数:xTask: 该任务的任务句柄
返回值:如果xTask从阻塞状态离开进入就绪状态,则返回pdPASS,如果该任务本来就不处于阻塞状态则返回 pdFALL
注意:需要在FreeRTOSConfig.h文件中启动INCLUDE_xTaskAbortDelay的使用
2.4 xTaskCallApplicationTaskHook()
总结:该函数是给高级用户使用的,略
2.5 xTaskCheckForTimeOut()
总结:同上,略
2.6 xTaskCreate()
函数原型:BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,
const char * const pcName,
unsigned short usStackDepth,
void *pvParameters,
UBaseType_t uxPriority,
TaskHandle_t *pxCreatedTask );
总结:创建OS任务。每个任务在创建的时候都会耗费一定的RAM用来保存任务的状态等(称为 task control block,也就是TCB),也些RAM也是被任务中stack所使用的地方。任务的TCB空间是从FreeRTOS 的堆空间中分配的。如果使用xTaskCreateStatic()创建一个静态任务,则RAM的分配在编译的时候就分配好了。
新建的任务初始状态是就绪状态,如果没有比它优先级更高的任务则会进入到运行状态
任务在内核启动前或者内核运行的时候创建均可
参数: pvTaskCode 任务的函数指针,任务里一般要有一个循环
pcName: 任务名称
usStackDepth: 分配给任务的栈空间大小,注意是以字为单位分配的
pvParameters: 传递到任务函数的参数指针,不需要传参可以填NULL
uxPriority: 任务优先级数,值越大逻辑优先级越高
pxCreatedTask: 任务句柄指针,可以利用句柄这个对任务进行其他操作
返回值:pdPASS: 任务成功创建
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY 堆空间有限导致任务创建失败
注意:要将 configSUPPORT_DYNAMIC_ALLPCATION定义1,或者干脆不定义这个宏效果也一样
2.7 xTaskCreateStatic()
总结:创建静态任务。与普通任务创建有区别,静态任务的任务堆栈空间是由用户自己定义的,而不是由内核动态分配,静态任务不会因为由于内核控制的堆空间有限而创建失败,但是这个内存空间会一直存在,不会被内核回收利用
2.8 xTaskCreateRestricted()
总结: 高级用法,有MPU才能使用,略
2.9 vTaskDelay()
函数原型:void vTaskDelay( TickType_t xTicksToDelay);
总结:让任务自动阻塞一段时间,如果参数为0且有同优先级的任务处于就绪状态,则内核会调用另一个任务,让该任务处于就绪状态。调用vTaskDelay(0)等同于使用taskYIELD()
参数:xTicksToDelay: 进入阻塞状态的os滴答时间数,具体的时间长度与os滴答时间的长度有关。可以使用宏定义 pdMS_TO_TICKS() 将毫秒转化成滴答时间数,这样就可以比较精确控制任务阻塞的时间
注意:需要将INCLUE_vTaskDelay()设置为1才能使用该函数
2.10 vTaskDelayUntil()
函数原型:vTaskDelayUntial( TickType_t *pxPreviousWakeTime, TickType_t xTimeIncrement);
总结:该API可以精确的控制一个任务的执行频率。与vTaskDelay()不同,普通延时是该函数可以让任务阻塞一定的时长,但是由于其他语句的执行时长不确定和其他任务的抢占等原因,并不能让该任务精确地按照vTaskDelay()函数里面的时间间隔执行。例如,vTaskDelay(pdMS_TO_TICKS(100)),但实际上该任务的执行频率可能是102ms或