FreeRTOS的任务创建和删除
创建动态任务
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, //任务函数
const char * const pcName, //任务名字
const uint16_t usStackDepth, //栈的大小
void * const pvParameters, //任务函数所要传入的参数
UBaseType_t uxPriority, //优先级0~(configMAX_PRIORITIES – 1),数值越小优先级越低
TaskHandle_t * const pxCreatedTask //任务句柄,后续需要操作任务,任务句柄作为参数传入
)
样例如下
#include "FreeRTOS.h"
#include "UART.h"
#include "Task.h"
void TaskFuntion(void* param);
int main(void)
{
TaskHandle_t xHandleTask;
xTaskCreate(Task1Funtion,"Task1", 100, NULL, 1, &xHandleTask1);
vTaskStartScheduler(); //任务启动调度
return 0;
}
void TaskFuntion(void* param)
{
while(1)
{
printf("Task is running");
}
}
创建静态任务和空闲任务
打开task.c
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, //任务函数
const char * const pcName, //任务名字
const uint32_t ulStackDepth, //栈的大小
void * const pvParameters, //任务函数所要传入的参数
UBaseType_t uxPriority, //优先级
StackType_t * const puxStackBuffer, //任务堆栈
StaticTask_t * const pxTaskBuffer ) //任务控制块
在task.c中有对静态任务的描述,使用xTaskCreateStatic()函数进行创建,需要注意到前面有#if( configSUPPORT_STATIC_ALLOCATION == 1 )的判断,打开FreeRTOSConfig.h文件
FreeRTOSConfig.h
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include "stm32f10x.h"
#include "UART.h"
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 17 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configSUPPORT_STATIC_ALLOCATION 1
将 #define configSUPPORT_STATIC_ALLOCATION 1添加进去
同时需要注意到task.c中有这么一段
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
extern void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );
#endif
我们需要实现vApplicationGetIdleTaskMemory()函数,这函数用于设置空闲任务的堆栈大小,若使用静态任务创建而不实现这个函数,系统会报这个函数未实现的错误。
vApplicationGetIdleTaskMemory()函数实现
StackType_t xIdleTaskStack[100];
StaticTask_t xIdleTaskTCB;
void vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskSize)
{
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
*ppxIdleTaskStackBuffer = xIdleTaskStack;
*pulIdleTaskSize = 100;//设置空闲任务的栈大小,可根据需要设置,这里我设置100
}
样例
#include "FreeRTOS.h"
#include "UART.h"
#include "Task.h"
void TaskStaticFuntion(void* param);
StackType_t xTaskStaticStack[100];
StaticTask_t xTaskStaticTCB;
StackType_t xIdleTaskStack[100];
StaticTask_t xIdleTaskTCB;
int main(void)
{
xTaskCreateStatic(TaskStaticFuntion,
"TaskStatic",
100 ,
NULL,
1,
xTask3Stack,
&xTask3TCB);
vTaskStartScheduler();
return 0;
}
void TaskStaticFuntion(void* param)
{
while(1)
{
printf("TaskStatic is running");
}
}
void vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskSize)
{
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
*ppxIdleTaskStackBuffer = xIdleTaskStack;
*pulIdleTaskSize = 100;
}
FreeRTOS的任务删除
void vTaskDelete( TaskHandle_t xTaskToDelete );
使用vTaskDelete()函数进行任务的删除,参数xTaskToDelete表示要删除的任务句柄,当传入NULL则是删除自己
FreeRTOS中的任务状态
这是FreeRTOS的任务状态转换图,Ready(就绪),Running(运行),Blocked(阻塞),Suspended(挂起),类似进程状态图。
常用函数
void vTaskSuspend( TaskHandle_t xTaskToSuspend );
void vTaskResume( TaskHandle_t xTaskToResume );
void vTaskSuspendAll( void );
vTaskSuspend()函数的作用是时任务进入挂起状态
vTaskResume()函数则是将挂起的任务恢复到就绪状态
这两个函数都是将任务句柄作为参数传入,当参数为NULL时,则表示是自己。
vTaskSuspendAll()函数可以将所有任务挂起
FreeRTOS的延时函数
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
在FreeRTOSConfig.h中可以找到该宏定义,该宏定义设置了一个Tick所延时的时间
void vTaskDelay( const TickType_t xTicksToDelay )
vTaskDelay()延时函数,参数xTicksToDelay表示,延时xTicksToDelay*Tick的时间,填入1表示延时1个Tick的时间
void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement )
vTaskDelayUntil()函数,参数pxPreviousWakeTime是一个起始的Tick时间,xTimeIncrement是填入所需要延时的时间。当需要我们的任务在精确时间开始执行时可以使用该函数达到准确延时。