系列文章
FreeRTOS实时操作系统(二)任务创建与任务删除(HAL库)
FreeRTOS实时操作系统(五)进入临界区、任务调度器挂起与恢复
FreeRTOS实时操作系统(七)时间片调度及RTOS的滴答定时器
FreeRTOS实时操作系统(八)任务状态查询及时间统计函数
FreeRTOS实时操作系统(十五)Tickless低功耗模式
文章目录
C语言中,printf的时候:%#x:以0x的格式输出,%#b:以0b的格式输出
任务相关的API函数
uxTaskPriorityGet()
UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask )
前提:宏 INCLUDE_uxTaskPriorityGet 置 1
作用:获取任务的优先级
形参:要查找的任务句柄/NULL(代表任务本身)
返回值:整型
实验结果:
void task1( void * pvParameters )
{
uint32_t task1_num = 0;
UBaseType_t num=uxTaskPriorityGet(task1_handler);
printf("num:%ld",num);
while(1)
{
}
}
vTaskPrioritySet()
void vTaskPrioritySet( TaskHandle_t xTask , UBaseType_t uxNewPriority )
前提:宏 INCLUDE_vTaskPrioritySet 置 1
作用:改变任务的优先级
形参:任务句柄/NULL(代表任务本身),需要设置的优先级。
typedef unsigned long UBaseType_t;
实验结果:
uint32_t task1_num = 0;
vTaskPrioritySet(task1_handler,3);
UBaseType_t num=uxTaskPriorityGet(task1_handler);
printf("num:%ld",num);
uxTaskGetNumberOfTasks()
UBaseType_t uxTaskGetNumberOfTasks( void )
作用:获取系统的任务数量
返回值:整型
实验结果:
UBaseType_t num = 0;
num=uxTaskGetNumberOfTasks();
printf("num:%ld\r\n",num);
首先我自己创建了3个,其次在任务调度开始的时候会再创建两个:
uxTaskGetSystemState()
UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
const UBaseType_t uxArraySize,
configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime )
前提:宏 configUSE_TRACE_FACILITY 置 1
作用:获取系统中所有任务的任务状态信息
形参:
1.pxTaskStatusArray:指向TaskStatus_t 结构体数组首地址
2.uxArraySize:接收信息的数组大小
3.pulTotalRunTime:系统总运行时间,为NULL 则省略总运行时间值
返回值:整型(获取信息的任务数量)
任务信息有:
typedef struct xTASK_STATUS
{
TaskHandle_t xHandle; //任务句柄
const char *pcTaskName; //任务名
UBaseType_t xTaskNumber; //任务编号(任务创建的顺序)
eTaskState eCurrentState; //任务状态
UBaseType_t uxCurrentPriority; //任务现在优先级
UBaseType_t uxBasePriority; //任务原始优先级
uint32_t ulRunTimeCounter; //任务运行时间
StackType_t *pxStackBase; //任务栈基地址
uint16_t usStackHighWaterMark; //任务栈历史剩余最小值
} TaskStatus_t;
实验结果:
正点原子利用自己分配内存的函数实现的,我参考官网的代码:
void task1( void * pvParameters )
{
UBaseType_t num1 = 0;
UBaseType_t num2 = 0;
TaskStatus_t * array;
num2=uxTaskGetNumberOfTasks();
array = pvPortMalloc( num2* sizeof( TaskStatus_t ) );
num2=uxTaskGetSystemState(array,num2,NULL);
printf("num:%ld\r\n",array[1].uxCurrentPriority);
printf("tasknum:%ld\r\n",num2);
printf("taskname:%s\r\n",array[1].pcTaskName);
while(1)
{
vTaskDelay(1000);
}
}
这个动态分配内存应该相当于定义了五个指向TaskStatus_t的指针(C++没学好)
xTaskGetCurrentTaskHandle()
TaskHandle_t xTaskGetCurrentTaskHandle( void )
前提:宏 INCLUDE_xTaskGetCurrentTaskHandle 置 1
作用:获取当前任务的任务句柄
返回值:当前任务的任务句柄
实验结果:
void task1( void * pvParameters )
{
TaskHandle_t num1 ;
num1=xTaskGetCurrentTaskHandle();
printf("num:%#x\r\n",(int)num1);
while(1)
{
vTaskDelay(1000);
}
}
xTaskGetHandle()
TaskHandle_t xTaskGetHandle(const char * pcNameToQuery);
前提:宏 INCLUDE_xTaskGetHandle 置 1
作用:通过任务名获取任务句柄
形参:任务名
返回值:该任务的任务句柄
实验结果:(HAL生成的默认这个宏是关闭的)
void task1( void * pvParameters )
{
TaskHandle_t num1 ;
num1=xTaskGetHandle("task1");
printf("num:%#x\r\n",(int)num1);
while(1)
{
vTaskDelay(1000);
}
}
uxTaskGetStackHighWaterMark()
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask )
前提:宏 INCLUDE_uxTaskGetStackHighWaterMark 置 1
作用:获取指定任务的任务栈历史最小剩余堆栈
形参:任务句柄
返回值:任务栈的历史剩余最小值(UBaseType_t )
实验结果:
这个值*4就是字节.
void task1( void * pvParameters )
{
UBaseType_t num1 ;
num1=uxTaskGetStackHighWaterMark(task1_handler);
printf("num:%d\r\n",num1);
while(1)
{
vTaskDelay(1000);
}
}
eTaskGetState()
eTaskState eTaskGetState(TaskHandle_t xTask)
前提:宏 INCLUDE_eTaskGetState 置 1
作用:查询某个任务的运行状态
形参:待获取状态任务的任务句柄
返回值:任务状态
下图是枚举的用法,这样编写代替了#define,从0-5赋值给下面的成员。
实验结果:0代表运行态
void task1( void * pvParameters )
{
eTaskState state ;
state=eTaskGetState(task1_handler);
printf("state:%d\r\n",state);
while(1)
{
vTaskDelay(1000);
}
}
vTaskList()
void vTaskList(char * pcWriteBuffer)
前提:宏 configUSE_TRACE_FACILITY 和configUSE_STATS_FORMATTING_FUNCTIONS 置 1
作用:用于以“表格”的形式获取系统中任务的信息
形参:接收任务信息的缓存指针
State: 任务的壮态信息, X运行态,B 是阻塞态, R 是就绪态, S 是挂起态, D 是删除态
Priority :任务优先级。
Stack : 任务堆栈的“高水位线”,就是堆栈历史最小剩余大小。
Num : 任务编号,这个编号是唯一的,当多个任务使用同一个任务名的时候可以通过此编号来做区分
实验结果:
void task1( void * pvParameters )
{
char task_buff[300];
vTaskList(task_buff);
printf("%s\t\t\r\n",task_buff);
while(1)
{
vTaskDelay(1000);
}
}
这里没必要加\t及\r\n,全部都是自动的缩进换行。
时间统计API函数
一般我们在调试阶段要使用,正式阶段就去掉,把一些占用时间大的任务拆分。
void vTaskGetRunTimeStats( char * pcWriteBuffer )
形参是用来接收任务运行时间信息的缓存指针
打印出任务名、绝对时间、占总处理时间的百分比
条件:
1.将宏 configGENERATE_RUN_TIME_STATS 置1
2.将宏 configUSE_STATS_FORMATTING_FUNCTIONS 置1
4.portCONFIGURE_TIMER_FOR_RUNTIME_STATE() :用于初始化用于配置任务运行时间统计的时基定时器;这个时基定时器的计时精度需高于系统时钟节拍精度的10至100倍!
5.portGET_RUN_TIME_COUNTER_VALUE():用于获取该功能时基硬件定时器计数的计数值 。
但这里有个问题,这个定时器不是我们在Stm32CubeMX里面设置的那个:
我们需要另外配置一个时钟:配置一个100kHz的信号:
很怪,这部分没有实现
参考:vTaskGetRunTimeStats()