目錄
一 創建靜態任務
使用靜態任務的幾點必要條件
- 在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 ); |