目录
一 创建静态任务
使用静态任务的几点必要条件
- 在FreeRTOSConfig.h文件中配置configSUPPORT_STATIC_ALLOCATION 宏定义为 1
- 实现函数vApplicationGetIdleTaskMemory()与 vApplicationGetTimerTaskMemory()
static StackType_t Idle_Task_Stack[configMINIMAL_STACK_SIZE];/* 空闲任务任务堆栈 */
static StackType_t Timer_Task_Stack[configTIMER_TASK_STACK_DEPTH];/* 定时器任务堆栈 */
static StaticTask_t Idle_Task_TCB;/* 空闲任务控制块 */
static StaticTask_t Timer_Task_TCB;/* 定时器任务控制块 */
/**
*******************************************************************
* @brief 获取空闲任务的任务堆栈和任务控制块内存
**********************************************************************
*/
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer,
uint32_t *pulIdleTaskStackSize)
{
*ppxIdleTaskTCBBuffer = &Idle_Task_TCB; /* 任务控制块内存 */
*ppxIdleTaskStackBuffer = Idle_Task_Stack;
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* 任务堆栈大小 */
}
/**
*********************************************************************
* @brief 获取定时器任务的任务堆栈和任务控制块内存
**********************************************************************
*/
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize)
{
*ppxTimerTaskTCBBuffer = &Timer_Task_TCB; /* 任务控制块内存 */
*ppxTimerTaskStackBuffer = Timer_Task_Stack; /* 任务堆栈内存 */
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* 任务堆栈大小 */
}
- 调用xTaskCreateStatic函数创建任务
static StackType_t AppTaskCreate_Stack[128];/* AppTaskCreate任务任务堆栈 */
static StaticTask_t AppTaskCreate_TCB;/* AppTaskCreate 任务控制块 */
static TaskHandle_t AppTaskCreate_Handle; /* 创建任务句柄 */
/* 创建 AppTaskCreate 任务 */
AppTaskCreate_Handle = xTaskCreateStatic((TaskFunction_t)AppTaskCreate, //任务函数
(const char* )"AppTaskCreate",//任务名称
(uint32_t )128, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )3, //任务优先级
(StackType_t* )AppTaskCreate_Stack,//任务堆栈
(StaticTask_t*)&AppTaskCreate_TCB);//任务控制块
if(NULL != AppTaskCreate_Handle)/* 创建成功 */
vTaskStartScheduler(); /* 启动任务,开启调度 */
二 创建动态任务
static TaskHandle_t LED1_Task_Handle = NULL;/* LED1 任务句柄 */
void led0_task(void* arg)
{
while(1)
{
vTaskDelay(500); /* 延时 500 个 tick */
}
}
/* 创建 LED_Task 任务 */
xTaskCreate((TaskFunction_t )led0_task, /* 任务入口函数 */
(const char* )"LED1_Task",/* 任务名字 */
(uint16_t )128, /* 任务栈大小 */
(void* )NULL, /* 任务入口函数参数 */
(UBaseType_t )4, /* 任务的优先级 */
(TaskHandle_t* )&LED1_Task_Handle);/* 任务控制块指针 */
三 常用函数接口
创建动态任务 | BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,const char * const pcName,unsigned short usStackDepth,void *pvParameters,UBaseType_t uxPriority,TaskHandle_t *pxCreatedTask ); |
创建静态任务 | TaskHandle_t xTaskCreateStatic( TaskFunction_t pvTaskCode,const char * const pcName, uint32_t ulStackDepth,void *pvParameters,UBaseType_t uxPriority, StackType_t * const puxStackBuffer,StaticTask_t * const pxTaskBuffer ); |
任务删除 | void vTaskDelete( TaskHandle_t pxTask ); |
任务延时 | void vTaskDelay( TickType_t xTicksToDelay ); |
绝对延时 | void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, TickType_t xTimeIncrement ); |
任务延时终止 | BaseType_t xTaskAbortDelay( TaskHandle_t xTask ); |
设置超时时间 | vTaskSetTimeOutState( &xTimeOut ); |
检测是否超时 | BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,TickType_t * const pxTicksToWait ); |
禁止中断 | void taskDISABLE_INTERRUPTS( void ); |
使能中断 | void taskENABLE_INTERRUPTS( void ); |
进入临界态 | void taskENTER_CRITICAL( void ); |
退出临界态 | void taskEXIT_CRITICAL( void ); |
在中断中进入临界 | UBaseType_t taskENTER_CRITICAL_FROM_ISR( void ); |
在中断中退出临界 | void taskENTER_CRITICAL_FROM_ISR( UBaseType_t uxSavedInterruptStatus ); |
获取当前任务 | TaskHandle_t xTaskGetCurrentTaskHandle( void ); |
获取任务总个数 | UBaseType_t uxTaskGetNumberOfTasks( void ); |
获取滴答计数器 | TickType_t xTaskGetTickCount( void ); |
获取滴答计数器 | TickType_t xTaskGetTickCountFromISR( void ); |
获取任务优先级 | UBaseType_t uxTaskPriorityGet( TaskHandle_t pxTask ); |
设置任务优先级 | void vTaskPrioritySet( TaskHandle_t pxTask, UBaseType_t uxNewPriority ); |
任务挂起 | void vTaskSuspend( TaskHandle_t pxTaskToSuspend ); |
任务恢复 | void vTaskResume( TaskHandle_t pxTaskToResume ); |
挂起所有任务 | void vTaskSuspendAll( void ); |
恢复所有任务 | BaseType_t xTaskResumeAll( void ); |
开启任务调度 | void vTaskStartScheduler( void ); |
任务放弃所有权 | void taskYIELD( void ); |
四 使用软件定时器
使用软件定时需要知道以下知识点
- 配置configUSE_TIMERS宏为1
- 通过配置宏configTIMER_TASK_PRIORITY可以设置软件定时任务优先级,默认为2
- 软件定时器不适合精度要求高的场合。
创建一个动态软件定时器:
TimerHandle_t SoftTmr = NULL; /* 软件定时器句柄 */
void SoftTmr_Callback(void* parameter)
{
//定时处理函数
}
SoftTmr = xTimerCreate((const char*)"AutoReloadTimer",
(TickType_t)1000, /* 定时器周期 1000(tick) */
(UBaseType_t)pdTRUE,/* 周期模式 */
(void*)1, /* 为每个计时器分配一个索引的唯一 ID */
(TimerCallbackFunction_t)SoftTmr_Callback);
if (SoftTmr != NULL) {
xTimerStart(SoftTmr, 0); // 开启周期定时器
}
创建一个静态软件定时器:
TimerHandle_t SoftTmrStatic = NULL;//静态软件定时器
StaticTimer_t xTimerBuffers; //定义一个静态定时器结构体
void SoftTmr_Callback(TimerHandle_t xTimer)
{
}
SoftTmrStatic = xTimerCreateStatic("Timer",//名称
1000, //定时时间
pdTRUE,//周期性定时器
( void * )2,//id
SoftTmr_Callback,//回调函数
&xTimerBuffers); //定时器结构体
五 软件定时器常用接口
创建定时器 | TimerHandle_t xTimerCreate( const char *pcTimerName, const TickType_t xTimerPeriod, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ); |
创建静态定时器 | TimerHandle_t xTimerCreateStatic( const char *pcTimerName, const TickType_t xTimerPeriod, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ); |
删除定时器 | BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ); |
启动定时器 | BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait ); |
中断中启动定时器 | BaseType_t xTimerStartFromISR( TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken ); |
停止定时器 | BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait ); |
中断中停止定时器 | BaseType_t xTimerStopFromISR( TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken ); |
复位定时器 | BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); |
中断中复位定时器 | BaseType_t xTimerResetFromISR( TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken ); |
改变定时器周期 | BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, TickType_t xNewPeriod, TickType_t xTicksToWait ); |
中断中改变定时器周期 | BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer, TickType_t xNewPeriod, BaseType_t *pxHigherPriorityTaskWoken ); |
获取定时器周期 | TickType_t xTimerGetPeriod( TimerHandle_t xTimer ); |