文章目录
- 09. FreeRTOS时间片调度与任务相关函数
- 1. FreeRTOS时间片调度
- 2. 任务状态查询API函数
- 3. 任务时间统计API函数
09. FreeRTOS时间片调度与任务相关函数
1. FreeRTOS时间片调度
时间片调度简介:
时间片调度实验流程:
核心代码:
开始任务函数:
void start_task(void* pvParamter)
{
taskENTER_CRITICAL(); // 进入临界区
xTaskCreate((TaskFunction_t ) task1, //指向任务函数的指针
(char * ) "task1", //任务名称
(configSTACK_DEPTH_TYPE) TASK1_TASK_STACK_SIZE, //任务堆栈大小,字节为单位
(void * ) NULL, //传递给任务函数的参数
(UBaseType_t ) TASK1_TASK_PRIO, //任务优先级
(TaskHandle_t * ) &task1_task_handler //任务句柄:任务控制块
);
xTaskCreate((TaskFunction_t ) task2, //指向任务函数的指针
(char * ) "task2", //任务名称
(configSTACK_DEPTH_TYPE) TASK2_TASK_STACK_SIZE, //任务堆栈大小,字节为单位
(void * ) NULL, //传递给任务函数的参数
(UBaseType_t ) TASK2_TASK_PRIO, //任务优先级
(TaskHandle_t * ) &task2_task_handler //任务句柄:任务控制块
);
vTaskDelete(NULL);
taskEXIT_CRITICAL(); // 退出临界区
}
任务1函数:
void task1(void* pvParamter)
{
uint32_t task1_num = 0;
while(1)
{
taskENTER_CRITICAL();
printf("task1正在运行!!!%d\r\n",++task1_num);
taskEXIT_CRITICAL();
delay_ms(10);
}
}
任务2函数:
void task2(void* pvParamter)
{
uint32_t task2_num = 0;
while(1)
{
taskENTER_CRITICAL();
printf("task2正在运行!!!%d\r\n",++task2_num);
taskEXIT_CRITICAL();
delay_ms(10);
}
}
实验结果:
2. 任务状态查询API函数
函数 | 描述 |
---|---|
uxTaskPriorityGet() | 获取任务优先级 |
vTaskPrioritySet() | 设置任务优先级 |
uxTaskGetNumberOfTasks() | 获取系统中任务的数量 |
uxTaskGetSystemState() | 获取所有任务状态信息 |
vTaskGetInfo() | 获取指定单个的任务信息 |
xTaskGetCurrentTaskHandle() | 获取当前任务的任务句柄 |
xTaskGetHandle() | 根据任务名获取该任务的任务句柄 |
uxTaskGetStackHighWaterMark() | 获取任务的任务栈历史剩余最小值 |
eTaskGetState() | 获取任务状态 |
vTaskList() | 以“表格”形式获取所有任务的信息 |
vTaskGetRunTimeStats() | 获取任务的运行时间 |
-
uxTaskPriorityGet()函数
函数解释:
代码实现:
//1.查询任务的优先级 UBaseType_t priority_num = 0; priority_num = uxTaskPriorityGet(task1_task_handler); printf("1.任务1的任务优先级为:%ld\r\n\n", priority_num);
实验结果:
-
vTaskPrioritySet()函数
函数解释:
代码实现:
//2.设置任务的优先级 vTaskPrioritySet(task2_task_handler,30); priority_num = uxTaskPriorityGet(task2_task_handler); printf("2.任务2的任务优先级为:%ld\r\n\n", priority_num);
实验结果:
-
uxTaskGetNumberOfTasks() 函数
函数解释:
代码实现:
//3.获取任务的数量 UBaseType_t task_num = 0; task_num = uxTaskGetNumberOfTasks(); printf("3.当前的任务数量为:%ld\r\n\n", task_num);
实验结果:
-
uxTaskGetSystemState()函数
函数解释:
代码实现:
//4.获取所有任务的状态信息 UBaseType_t task_num2 = 0; TaskStatus_t * status_array = 0; uint8_t i = 0; status_array = mymalloc(SRAMIN,sizeof(TaskStatus_t *) * task_num); task_num2 = uxTaskGetSystemState( status_array,task_num, NULL); for(i = 0;i < task_num2; i++) { printf("4.%d 任务名:%s \r\n", i+1, status_array[i].pcTaskName); printf("4.%d 当前任务优先级:%ld \r\n", i+1, status_array[i].uxCurrentPriority); printf("4.%d 任务编号:%ld \r\n", i+1, status_array[i].xTaskNumber); } printf("\n");
实验结果:
-
vTaskGetInfo()函数
函数解释:
代码实现:
//5.获取单个任务的状态信息 TaskStatus_t * status_array2 = 0; status_array2 = mymalloc(SRAMIN,sizeof(TaskStatus_t *)); vTaskGetInfo(task2_task_handler, status_array2, pdTRUE, eInvalid); printf("5.任务名:%s\r\n", status_array2->pcTaskName); printf("5.当前任务优先级:%ld\r\n", status_array2->uxCurrentPriority); printf("5.任务编号:%ld\r\n", status_array2->xTaskNumber); printf("5.任务状态:%d\r\n\n", status_array2->eCurrentState);
实验结果:
-
xTaskGetCurrentTaskHandle()函数
函数解释:
代码实现:
实验结果:
-
xTaskGetHandle()函数
函数解释:
代码实现:
//6.获取任务句柄 TaskHandle_t task_handle = 0; task_handle = xTaskGetHandle("task1"); printf("6.任务句柄:%#x\r\n", (int)task_handle); printf("6.task的任务句柄:%#x\r\n\n", (int)task1_task_handler);
实验结果:
-
uxTaskGetStackHighWaterMark()函数
函数解释:
代码实现:
//7.获取指定任务的任务栈历史最小剩余堆栈 UBaseType_t task_stack_min = 0; task_stack_min = uxTaskGetStackHighWaterMark(task2_task_handler); printf("7.task2历史剩余最小堆栈为:%ld\r\n\n", task_stack_min);
实验结果:
-
eTaskGetState()函数
函数解释:
代码实现:
//8.查询任务的运行状态 eTaskState task_status = 0; task_status = eTaskGetState(task2_task_handler); printf("8.当前task2的运行状态为:%d\r\n\n", task_status);
实验结果:
-
vTaskList()函数
函数解释:
代码实现:
//9.以表格形式获取系统中任务的信息 char task_buff[300]; vTaskList(task_buff); printf("9.\r\n"); printf("%s\r\n\n", task_buff);
实验结果:
3. 任务时间统计API函数
- vTaskGetRunTimeStats()函数
函数解释:
代码实现:
任务中实现:
while(1)
{
key = key_scan(0);
if(key == KEY0)
{
vTaskGetRunTimeStats(task_buff);
printf("%s\r\n", task_buff);
}
vTaskDelay(10);
}
FreeRTOSConfig.h
文件:
/* 运行时间和任务状态统计相关定义 */
#define configGENERATE_RUN_TIME_STATS 1 // 1: 使能任务运行时间统计功能, 默认: 0
#if configGENERATE_RUN_TIME_STATS
#include "./BSP/TIMER/btim.h"
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() ConfigureTimeForRunTimeStats()
extern uint32_t FreeRTOSRunTimeTicks;
#define portGET_RUN_TIME_COUNTER_VALUE() FreeRTOSRunTimeTicks
#endif
#define configUSE_TRACE_FACILITY 1 // 1: 使能可视化跟踪调试, 默认: 0
#define configUSE_STATS_FORMATTING_FUNCTIONS 1 // 1: configUSE_TRACE_FACILITY为1时,会编译vTaskList()和vTaskGetRunTimeStats()函数, 默认: 0
btim.c
文件:
//定义变量FreeRTOSRunTimeTicks
uint32_t FreeRTOSRunTimeTicks;
/*时基定时器初始化*/
void ConfigureTimeForRunTimeStats()
{
btim_tim6_int_init(10-1, 720-1); //10us中断一次
FreeRTOSRunTimeTicks = 0;
}
/*定时器6中断初始化*/
void btim_tim6_int_init(uint16_t psc, uint16_t per)
{
g_tim6_handle.Instance = TIM6;
g_tim6_handle.Init.Prescaler = psc;
g_tim6_handle.Init.Period = per;
HAL_TIM_Base_Init(&g_tim6_handle);
//使能更新中断,并启动计数器
HAL_TIM_Base_Start_IT(&g_tim6_handle);
}
/*定时器6中断服务函数*/
void TIM6_IRQHandler()
{
//处理基本定时器中断事件
HAL_TIM_IRQHandler(&g_tim6_handle);
}
/*定时器溢出中断回调函数*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM6)
{
FreeRTOSRunTimeTicks++;
}
}
定时器程序运行流程:
实验结果: