void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建LED0任务
xTaskCreate((TaskFunction_t )led0_task,
(const char* )"led0_task",
(uint16_t )LED0_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED0_TASK_PRIO,
(TaskHandle_t* )&LED0Task_Handler);
//创建LED1任务
xTaskCreate((TaskFunction_t )led1_task,
(const char* )"led1_task",
(uint16_t )LED1_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED1_TASK_PRIO,
(TaskHandle_t* )&LED1Task_Handler);
//浮点测试任务
xTaskCreate((TaskFunction_t )float_task,
(const char* )"float_task",
(uint16_t )FLOAT_STK_SIZE,
(void* )NULL,
(UBaseType_t )FLOAT_TASK_PRIO,
(TaskHandle_t* )&FLOATTask_Handler);
vTaskDelete(StartTask_Handler); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
参数 1 执行的函数
函数格式
例如 void my_thread(void* param)
参数 2 任务名字
参数 3 任务使用的空间 以 32位为标准
参数 4 传递给参数1 的值,没见过使用的
参数 5 返回一个 handle 方便以后进行调用
2 用xTaskCreate 创建一个任务就会有一个控制块。
TCB_t *pxNewTCB;//控制块
3 xTaskCreate 设置栈的数值
,追码追下去会发现申请的大小是 数字*4 (4是一个类型的大小)
4 xTaskCreate 使用动态的方法创建一个任务
xTaskCreateStatic 使用静态的方法创建一个任务
vTaskDelete 删除一个任务
notice:
xTaskCreate 里面参数 pcName任务名字。任务名字不能超过这个宏定义
参数 pxCreatedTask(xTaskHandle) 任务句柄
创建成功后,返回这个参数,其他函数多用这个函数
freertos 系统所有的总堆的大小 : 以字节为单位
#define configTOTAL_HEAP_SIZE ((size_t)(20*1024)) //系统所有总的堆大小 如图就是设置大小为 20*1024个字节
5 vTaskDelete 参数就是
pxCreatedTask(xTaskHandle) 任务句柄 这个东西
vTaskDelete 多次释放已经释放的句柄,会出现问题,可能因为重复释放内存
6 vTaskSuspend() 在任务里面挂起一个任务
vTaskResume() 在任务里面恢复一个任务的运行
vTaskResumeISR() 在中断服务函数 里面恢复一个任务的运行
vTaskResumeISR()要根据返回值判断是否立刻执行还是就绪状态等待,如果是立刻执行那么就要运行任务切换函数
7 freertos 开关中断
protenable_interrupts()
protdisable_interrupts()
可以根据宏定义,管理大于宏定义优先级标号的中断(stm32优先级标号越小中断优先级越高)
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 //中断最低优先级
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 //系统可管理的最高中断优先级
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
中断要全部设置为抢占式中断分组
官方延时函数可能会执行打开中断服务
vTaskPrioritySet() API 函数可以用于在调度器启动后改变任何任务的优先级。
uxTaskGetSystemState:此函数用于获取系统中所有的任务状态,每个任务的状态信息保存在一个TaskStatus_t类型的结构体里面
使用方法
configUSE_TRACE_FACILITY 设置为1
vTaskGetInfo 获得单个任务的数据
void heap_stack_test(void* param)
{
TaskStatus_t *StatusArray;
UBaseType_t task_num;
int TotalRunTime;
int x;
while(1)
{
task_num=uxTaskGetNumberOfTasks(); //获取系统任务数量
printf("uxTaskGetNumberOfTasks %d\r\n", task_num);
StatusArray=pvPortMalloc(task_num*sizeof(TaskStatus_t));//申请内存
if(StatusArray!=NULL) //内存申请成功
{
uxTaskGetSystemState((TaskStatus_t* )StatusArray, //任务信息存储数组
(UBaseType_t )task_num, //任务信息存储数组大小
(uint32_t* )&TotalRunTime);//保存系统总的运行时间
printf("TaskName\t\tPriority\t\tTaskNumber\t\t\rletf_stack\n");
for(x=0;x<task_num;x++)
{
printf("%s\t\t%d\t\t\t%d\t\t\t%d\t\t\r\n",
StatusArray[x].pcTaskName, //任务名称
(int)StatusArray[x].uxCurrentPriority, //任务优先级
(int)StatusArray[x].xTaskNumber,//任务编号
StatusArray[x].usStackHighWaterMark); //剩余的空间大小=值 * 4
}
}
vTaskDelay(10000);
}
}
注意 vTaskGetInfo 跟 uxTaskGetSystemState 的参数都有TaskHandle_t,
uxTaskGetSystemState也可以得到任务编号,任务当前优先级,任务堆栈历史剩余最小值
要说明 任务编号 可以说明任务创建的顺序
#define INCLUDE_uxTaskGetStackHighWaterMark 1
才能使用
uxTaskGetStackHighWaterMark(任务句柄)//检查剩余任务的栈空间
空间字节大小=返回值*4;
vTaskList 函数太贴心,创建体格表格描述每个任务详细信息
首先
如何使用
char InfoBuffer[1000]; //保存信息的数组 尽量大些
vTaskList(InfoBuffer); //获取所有任务的信息
printf("%s\r\n",InfoBuffer); //通过串口打印所有任务的信息
计算时间
获取当前未分配的堆的大小,和堆剩余的历史最小值 返回值为字节
printf(“xPortGetFreeHeapSize is %d\n”,xPortGetFreeHeapSize()) printf(“xPortGetMinimumEverFreeHeapSize is %d\n”,xPortGetMinimumEverFreeHeapSize());
同时上面两个函数 返回的空间的大小 不包括任务中剩余的空间(栈)
如果一个任务申请 512word ,任务中有 100 字节未使用,不会包括到 上面 两个函数返回值的