freeRTOS任务函数的基本原型:
void ATaskFunction( void *pvParameters );
FreeRTOS的任务是不能返回的,除非在返回之前将任务销毁,销毁任务一般通过vTaskDelete实现,另外每个任务都有自己的栈空间和自己的自动变量(函数本身定义的变量)。一般的任务定义如下:
void ATaskFunctrion(void *pvParameters){
int iVariableExample = 0;
while(1){
/* task code */
}
/* delete task before return */
vTaskDelete(NULL); // use NULL to delete current task
}
任务的创建是通过xTaskCreate实现的,这个函数的原型如下:
protBASE_TYPE xTaskCreate (
pdTASK_CODE pvTaskCode, // target task function pointer
const signed portCHAR * const pcName, // task name string, used in debug
unsigned portSHORT usStackDepth, // stack size in word
void *pvParameters, // task function parameter pointer
unsigned portBASE_TYPE uxPriority, // task priority
xTaskHandle *pxCreatedTask // task handler for task created
);
这个函数的返回值可能有两个:
-
pdTRUE
任务成功创建; -
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY
内存空间不足,无法创建新的任务。
应用程序可以包含多个任务,不过同一时间只能有一个任务处于运行状态,也就是任务有两个基本状态:运行状态和非运行状态,其中非运行状态又可以划分成几种不同的子状态。
任务优先级
FreeRTOS支持设置不同优先级设置,优先级数目通过configMAX_PRIORITIES,不过过多的优先级设置会占用大量的内存,所以需要依据项目程序的需要设置合适的优先级数目。有效的优先级是0到configMAX_PRIORITIES-1, 0代表最低优先级。
一般的任务都不会一直占用CPU时间运行,所以都会有一个将任务挂起的点,从而让出CPU运行其它任务,以避免其它任务被饿死。常用的简单的挂起就是延时,FreeRTOS里面的延时是通过vTaskDelay(参数是延时多少个时间片)或者vTaskDealyUntil实现的,这两个函数还是有一些不同的,vTaskDelay是从函数调用的时刻开始计算延时,而vTaskDelayUntil是从函数唤醒的时候就开始计算延时,所以vTaskDelayUntil周期性计时会更加的准确。
任务的子状态
阻塞状态: 如果一个任务正在等待某个事件,称为这个任务处于阻塞状态,等待的事件一般有两种:
- 定时相关的事件:比如延时到期或者绝对的一个时间点,比如一个任务进入阻塞状态延时10ms;
- 同步事件:等待其它任务事件,比如等待一个队列中有数据到来。FreeRTOS中,队列,二值信号,计数信号量,互斥信号量和互斥量都可以产生同步事件。
挂起状态:处于挂起状态的任务对于调度器是不可见的,程序通过vTaskSuspend()使一个任务处于挂起状态,并通过vTaskResume()或者vTaskResumeFromISR()退出挂起状态。
就绪状态:等待运行的状态,只是准备运行而尚未真正运行。
网友评论