好的公司网站有什么用百度网址安全检测
FreeRTOS 提供了一些用于控制内核的 API 函数,这些 API 函数主要包含了进出临界区、开关中断、启停任务调度器等一系列用于控制内核的 API 函数。本章就来学习 FreeRTOS 的内
核控制函数。
内核控制函数
1. 函数 taskYIELD()
此函数用于请求切换任务, 调用后会触发任务切换。
2. 函数 taskENTER_CRITICAL()
此函数用于在任务中进入临界区。
3. 函数 taskEXIT_CRITICAL()
此函数用于在任务中退出临界区。
4. 函数 taskENTER_CRITICAL_FROM_ISR()
此函数用于在中断服务函数中进入临界区。
5. 函数 taskEXIT_CRITICAL_FROM_ISR()
此函数用于在中断服务函数中退出临界区。
6. 函数 taskDISABLE_INTERRUPTS()
此函数用于关闭受 FreeRTOS 管理的中断。
7. 函数 taskENABLE_INTERRUPTS()
此函数用于开启所有中断。
8. 函数 vTaskStartScheduler()
此函数用于开启任务调度器。
9. 函数 vTaskEndScheduler()
此函数用于关闭任务调度器。
10. 函数 vTaskSuspendAll()
此函数用于挂起任务调度器,当任务调度器被挂起后,就不能进行任务切换,直到任务调度器恢复运行。
11. 函数 xTaskResumeAll()
此函数用于恢复任务调度器运行,要注意的是,任务调度器的挂起是可递归的,因此需要使用此函数恢复任务调度器与任务调度器被挂起相同的次数,才能恢复任务调度器运行。
12. 函数 vTaskStepTick()
此函数用于设置系统时钟节拍计数器的值,可以设置系统时钟节拍计数器的值为当前值加上指定值,不过要注意的值,更新后系统时钟节拍计数器的值,不能超过下一个任务阻塞超时时间。
13. 函数 xTaskCatchUpTicks()
此函数用于修正中断后的系统时钟节拍,主要是用过更新全局变量 xPendedTicks 实现的,全局变量 xPendedTicks 用于计数系统使用节拍在任务调度器挂起时被忽略处理的次数。
其他任务相关 API
函数 uxTaskPriorityGet()
此函数用于获取指定任务的任务优先级, 若使用此函数, 需在 FreeRTOSConfig.h 文件中设置配置项 INCLUDE_uxTaskPriorityGet 为 1,此函数的函数原型如下所示:
UBaseType_t uxTaskPriorityGet(const TaskHandle_t xTask);
形参 | 描述 |
xTask | 待获取优先级的任务 |
函数 uxTaskPriorityGet()的返回值,如下表所示:
返回值 | 描述 |
整数 | 指定任务的优先级 |
函数 vTaskPrioritySet()
此函数用于设置指定任务的优先级, 若使用此函数, 需在 FreeRTOSConfig.h 文件中设置配置项 INCLUDE_vTaskPrioritySet 为 1,此函数的函数原型如下所示:
void vTaskPrioritySet(TaskHandle_t xTask, UBaseType_t uxNewPriority);
形参 | 描述 |
xTask | 待设置优先级的任务 |
uxNewPriority | 任务优先级 |
函数 vTaskPrioritySet()无返回值。
函数 uxTaskGetSystemState()
此函数用于获取所有任务的状态信息, 若使用此函数, 需在 FreeRTOSConfig.h 文件中设置配置项 configUSE_TRACE_FACILITY 为 1,此函数的函数原型如下所示:
UBaseType_t uxTaskGetSystemState(TaskStatus_t * const pxTaskStatusArray,const UBaseType_t uxArraySize,configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime);
形参 | 描述 |
pxTaskStstusArray | 接收信息变量数组的首地址 |
uxArraySize | 接收信息变量数组的大小 |
pilTotalRunTime | 系统总运行时间 |
函数 uxTaskGetSystemState()的返回值,如下表所示:
返回值 | 描述 |
整型 | 获取信息的任务数量 |
函数 uxTaskGetSystemState()的形参 pxTaskStatusArray 指向变量类型为 TaskStatus_t 的变量的首地址,可以是一个数组,用来存放多个TaskStatus_t 类型的变量,函数 uxTaskGetSystemState()使用任务的状态信息,写入到该数组中,形参 uxArraySize 指示该数组的大小,其中变量类型TaskStatus_t 的定义如下所示:
typedef struct xTASK_STATUS
{TaskHandle_t xHandle; /* 任务句柄 */const char * pcTaskName; /* 任务名 */UBaseType_t xTaskNumber; /* 任务编号 */eTaskState eCurrentState; /* 任务状态 */UBaseType_t uxCurrentPriority; /* 任务优先级 */UBaseType_t uxBasePriority; /* 任务原始优先级 */configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /* 任务被分配的运行时间 */StackType_t * pxStackBase; /* 任务栈的基地址 */configSTACK_DEPTH_TYPE usStackHighWaterMark; /* 任务栈历史剩余最小值 */
} TaskStatus_t;
该结构体变量就包含了任务的一些状态信息,获取到的每个任务都有与之对应的TaskStatus_t 结构体来保存该任务的状态信息。
函数 vTaskGetInfo()
此函数用于获取指定任务的任务信息, 若使用此函数,需在 FreeRTOSConfig.h 文件中设置配置项 configUSE_TRACE_FACILITY 为 1,此函数的函数原型如下所示:
void vTaskGetInfo(TaskHandle_t xTask,TaskStatus_t * pxTaskStatus,BaseType_t xGetFreeStackSpace,eTaskState eState);
形参 | 描述 |
xTask | 指定获取信息的任务 |
pxTaskStatus | 接收任务信息的变量 |
xGetFreeStackSpace | 任务栈历史剩余最小值 |
eState | 任务状态 |
函数 vTaskGetInfo()无返回值。
函数 vTaskGetInfo()的形参 eState 用来表示任务的状态,其变量类型为 eTaskState,变量类型 eTaskState 的定义如下所示:
typedef enum
{eRunning = 0, /* 运行态 */eReady, /* 就绪态 */eBlocked, /* 阻塞态 */eSuspended, /* 挂起态 */eDeleted, /* 任务被删除 */eInvalid /* 非法值 */
} eTaskState;
形参 eState 用于决定形参 pxTaskStatus 结构体中成员变量 eCurrentState 的值,表示任务的状态,如果传入的 eState 为 eInvalid,那么 eCurrentState 为任务当前的状态,否则 eCurrentState
为 eState。
函数 xTaskGetApplicationTaskTag()
此函数用于获取指定任务的 Tag, 若使用此函数,需在 FreeRTOSConfig.h 文件中设置配置项 configUSE_APPLICATION_TASK_TAG 为 1,此函数的函数原型如下所示:
TaskHookFunction_t xTaskGetApplicationTaskTag(TaskHandle_t xTask);
形参 | 描述 |
xTask | 待获取 Tag 的任务 |
函数 xTaskGetApplicationTaskTag()的返回值,如下表所示:
返回值 | 描述 |
函数指针 | Tag |
函数 xTaskGetCurrentHandle()
此函数用于获取当前系统正在运行的任务的任务句柄,若使用此函数,需在FreeRTOSConfig.h 文件中设置配置项 INCLUDE_xTaskGetCurrentTaskHandle 为 1,此函数的函数原型如下所示:
TaskHandle_t xTaskGetCurrentTaskHandle(void);
返回值 | 描述 |
TaskHandle_t | 任务句柄 |
函数 xTaskGetHandle()
此函数用于通过任务名获取任务句柄, 若使用此函数,需在 FreeRTOSConfig.h 文件中设置配置项 INCLUDE_xTaskGetHandle 为 1,此函数的函数原型如下所示:
TaskHandle_t xTaskGetHandle(const char * pcNameToQuery);
形参 | 描述 |
pcNameToQuery | 任务名 |
函数 xTaskGetHandle()的返回值,如下表所示:
返回值 | 描述 |
TaskHandle_t | 任务句柄 |
函数 xTaskGetIdleTaskHandle()
此函数用于获取空闲任务的任务句柄, 若使用此函数,需在 FreeRTOSConfig.h 文件中设置配置项 INCLUDE_xTaskGetIdleTaskHandle 为 1,此函数的函数原型如下所示:
TaskHandle_t xTaskGetIdleTaskHandle(void);
返回值 | 描述 |
TaskHandle_t | 空闲任务的任务句柄 |
函数 uxTaskGetStackHighWaterMark()
此函数用于获取指定任务的任务栈的历史剩余最小值,若使用此函数,需在FreeRTOSConfig.h 文件中设置配置项 INCLUDE_uxTaskGetStackHighWaterMark 为 1,此函数的函数原型如下所示:
UBaseType_t uxTaskGetStackHighWaterMark(TaskHandle_t xTask);
形参 | 描述 |
xTask | 待获取任务栈历史剩余最小值的任务 |
返回值 | 描述 |
整数 | 任务栈的历史剩余最小值 |
函数 eTaskGetState()
此函数用于获取指定任务的状态, 若使用此函数,需在 FreeRTOSConfig.h 文件中设置配置项 INCLUDE_eTaskGetState 为 1,此函数的函数原型如下所示:
eTaskState eTaskGetState(TaskHandle_t xTask);
形参 | 描述 |
xTask | 待获取状态的任务 |
返回值 | 描述 |
eTaskState | 任务状态 |
函数 pcTaskGetName()
此函数用于获取指定任务的任务名,此函数的函数原型如下所示:
char * pcTaskGetName(TaskHandle_t xTaskToQuery);
形参 | 描述 |
xTaskToQuery | 任务句柄 |
返回值 | 描述 |
字符串 | 任务名 |
函数 xTaskGetTickCount()
此函数用于获取系统时钟节拍计数器的值,此函数的函数原型如下所示:
volatile TickType_t xTaskGetTickCount(void);
返回值 | 描述 |
整型 | 系统时钟节拍计数器的值 |
函数 xTaskGetTickCountFromISR()
此函数用于在中断中获取系统时钟节拍计数器的值,此函数的函数原型如下所示:
volatile TickType_t xTaskGetTickCountFromISR(void);
返回值 | 描述 |
整型 | 系统时钟节拍计数器的值 |
函数 xTaskGetSchedulerState()
此函数用于获取任务调度器的运行状态,此函数的函数原型如下所示:
返回值 | 描述 |
整型 | 任务调度器的运行状态 |
函数 uxTaskGetNumberOfTasks()
此函数用于获取系统中任务的数量,此函数的函数原型如下所示:
UBaseType_t uxTaskGetNumberOfTasks(void);
返回值 | 描述 |
整型 | 系统中任务的数量 |
函数 vTaskList()
此函数用于以“表格”的形式获取系统中任务的信息, 若使用此函数,需在 FreeRTOSConfig.h文件中同时设置配置项configUSE_TRACE_FACILITY 和配置项configUSE_STATS_FORMATTING_FUNCTIONS 为 1,此函数的函数原型如下所示:
void vTaskList(char * pcWriteBuffer);
形参 | 描述 |
pcWriteBuffer | 接收任务信息的缓存指针 |
函数 vTaskList()获取到的任务信息示例,如下图所示:
函数 vTaskGetRunTimeStats()
此函数用于获取指定任务的运行时间、 运行状态等信息, 若使用此函数,需在FreeRTOSConfig.h 文 件 中 同 时 设 置 配 置 项 configGENERATE_RUN_TIME_STATS 、
configUSE_STATS_FORMATTING_FUNCTIONS、 configSUPPORT_DYNAMIC_ALLOCATION为 1,此函数的函数原型如下所示:
void vTaskGetRunTimeStats(char * pcWriteBuffer);
形参 | 描述 |
pcWriteBuffer | 接收任务运行时间和状态等信息的缓存指针 |
函数 vTaskSetApplicationTaskTag()
此函数用于设置指定任务的 Tag, 若使用此函数,需在 FreeRTOSConfig.h 文件中设置配置项 configUSE_APPLICATION_TASK_TAG 为 1,此函数的函数原型如下所示:
void vTaskSetApplicationTaskTag(TaskHandle_t xTask, TaskHookFunction_t pxTagValue);
形参 | 描述 |
xTask | 待插入 Tag 的任务 |
pxTagValue | Tag 指针 |
函数 SetThreadLocalStoragePointer()
此函数用于设置指定任务的独有数据数组指针,此函数的函数原型如下所示:
void vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet, BaseType_t xIndex, void * pvValue)
形参 | 描述 |
xTaskToSet | 待设置的任务 |
xIndex | 设置的指针 |
pvValue | 值 |
函数 GetThreadLocalStoragePointer()
此函数用于获取指定任务的独有数据数组指针,此函数的函数原型如下所示:
void *pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery, BaseType_t xIndex);
形参 | 描述 |
xTaskToQuery | 待获取的任务 |
xIndex | 接收的指针 |
返回值 | 描述 |
void* | 指针指向的值 |
任务状态与信息查询实验
TaskHandle_t xTaskHandle_1;
TaskHandle_t xTaskHandle_2;//init
xTaskCreate(vTaskFunction_1, "Task1", 8192, NULL, 1, &xTaskHandle_1 );
xTaskCreate(vTaskFunction_2, "Task2", configMINIMAL_STACK_SIZE, NULL, 1, &xTaskHandle_2 );void vTaskFunction_1(void *pvParameters)
{uint32_t TotalRunTime;UBaseType_t ArraySize,x;TaskStatus_t *StatusArray;//第一步:函数uxTaskGetSystemState()的使用printf("/********第一步:函数uxTaskGetSystemState()的使用**********/\r\n");ArraySize=uxTaskGetNumberOfTasks(); //获取系统任务数量StatusArray=pvPortMalloc(ArraySize*sizeof(TaskStatus_t));//申请内存if(StatusArray!=NULL) //内存申请成功{ArraySize=uxTaskGetSystemState((TaskStatus_t* )StatusArray, //任务信息存储数组(UBaseType_t )ArraySize, //任务信息存储数组大小(uint32_t* )&TotalRunTime);//保存系统总的运行时间printf("TaskName\t\tPriority\t\tTaskNumber\t\t\r\n");for(x=0;x<ArraySize;x++){//通过串口打印出获取到的系统任务的有关信息,比如任务名称、//任务优先级和任务编号。printf("%s\t\t%d\t\t\t%d\t\t\t\r\n", StatusArray[x].pcTaskName,(int)StatusArray[x].uxCurrentPriority,(int)StatusArray[x].xTaskNumber);}}vPortFree(StatusArray); //释放内存printf("/**************************结束***************************/\r\n");//第二步:函数vTaskGetInfo()的使用TaskHandle_t TaskHandle; TaskStatus_t TaskStatus;printf("/************第二步:函数vTaskGetInfo()的使用**************/\r\n");TaskHandle=xTaskGetHandle("Task1"); //根据任务名获取任务句柄。//获取Task1的任务信息vTaskGetInfo((TaskHandle_t )TaskHandle, //任务句柄(TaskStatus_t* )&TaskStatus, //任务信息结构体(BaseType_t )pdTRUE, //允许统计任务堆栈历史最小剩余大小(eTaskState )eInvalid); //函数自己获取任务运行壮态//通过串口打印出指定任务的有关信息。printf("任务名: %s\r\n",TaskStatus.pcTaskName);printf("任务编号: %d\r\n",(int)TaskStatus.xTaskNumber);printf("任务壮态: %d\r\n",TaskStatus.eCurrentState);printf("任务当前优先级: %d\r\n",(int)TaskStatus.uxCurrentPriority);printf("任务基优先级: %d\r\n",(int)TaskStatus.uxBasePriority);printf("任务堆栈基地址: %#x\r\n",(int)TaskStatus.pxStackBase);printf("任务堆栈历史剩余最小值:%d\r\n",TaskStatus.usStackHighWaterMark);printf("/**************************结束***************************/\r\n");//第三步:函数eTaskGetState()的使用 eTaskState TaskState;char TaskInfo[10];printf("/***********第三步:函数eTaskGetState()的使用*************/\r\n");TaskHandle=xTaskGetHandle("Task2"); //根据任务名获取任务句柄。TaskState=eTaskGetState(TaskHandle); //获取Task2任务的任务壮态memset(TaskInfo,0,10); switch((int)TaskState){case 0:sprintf(TaskInfo,"Running");break;case 1:sprintf(TaskInfo,"Ready");break;case 2:sprintf(TaskInfo,"Suspend");break;case 3:sprintf(TaskInfo,"Delete");break;case 4:sprintf(TaskInfo,"Invalid");break;}printf("任务壮态值:%d,对应的壮态为:%s\r\n",TaskState,TaskInfo);printf("/**************************结束**************************/\r\n");char InfoBuffer[1000]; //保存信息的数组//第四步:函数vTaskList()的使用 printf("/*************第三步:函数vTaskList()的使用*************/\r\n");vTaskList(InfoBuffer); //获取所有任务的信息printf("%s\r\n",InfoBuffer); //通过串口打印所有任务的信息printf("/**************************结束**************************/\r\n");while(1) {vTaskDelay(200);}
}void vTaskFunction_2(void *pvParameters)
{ while(1) {vTaskDelay(200);}
}
结果:
/********第一步:函数uxTaskGetSystemState()的使用**********/
TaskName Priority TaskNumber
Task1 1 7
IDLE1 0 5
IDLE0 0 4
main 1 3
Task2 1 8
ipc1 24 2
Tmr Svc 1 6
ipc0 24 1
/**************************结束***************************/
/************第二步:函数vTaskGetInfo()的使用**************/
任务名: Task1
任务编号: 7
任务壮态: 0
任务当前优先级: 1
任务基优先级: 1
任务堆栈基地址: 0x3fca4da4
任务堆栈历史剩余最小值:5244
/**************************结束***************************/
/***********第三步:函数eTaskGetState()的使用*************/
任务壮态值:2,对应的壮态为:Suspend
/**************************结束**************************/
/*************第三步:函数vTaskList()的使用*************/
Task1 X 1 5228 7 -1
IDLE1 R 0 804 5 1
IDLE0 R 0 1008 4 0
Task2 B 1 864 8 -1
main B 1 1916 3 0
Tmr Svc B 1 1320 6 -1
ipc0 S 24 532 1 0
ipc1 S 24 536 2 1/**************************结束**************************/
任务运行时间统计实验
在上一个实验基础上将任务2函数切换为如下代码:
void vTaskFunction_2(void *pvParameters)
{ char RunTimeInfo[400]; //保存任务运行时间信息while(1) {memset(RunTimeInfo,0,400); //信息缓冲区清零vTaskGetRunTimeStats(RunTimeInfo); //获取任务运行时间信息printf("任务名\t\t\t运行时间\t运行所占百分比\r\n");printf("%s\r\n",RunTimeInfo);vTaskDelay(1000);}
}
实验结果:
任务名 运行时间 运行所占百分比
Task2 15759389 1%
IDLE1 1081013560 99%
IDLE0 1065098667 98%
main 45752 <1%
Task1 158987 <1%
ipc1 29938 <1%
Tmr Svc 13 <1%
ipc0 29832 <1%