前言
最近熟悉一款基于M4内核的国产芯片,移植FreeRTOS v10.3.1,学习并实践任务启动的流程,做如下实践笔记。
一、移植FreeRTOS框架
系统的移植部分不做详细说明,移植完成后如下图所示。
二、任务创建步骤
1.定义任务实体函数
代码如下(示例):
static void Task1_Crt(void)
{
printf("create task1.\n");
while(1)
{
printf("task1.\n");
vTaskDelay(500);
}
}
static void Task2_Crt(void)
{
printf("create task2.\n");
while(1)
{
printf("task2.\n");
vTaskDelay(1000);
}
}
2.创建任务
2.1 定义任务栈
2.1.1定义静态任务栈
则需要优先定义Stack,栈空间从SRAM分配,地址由编译器决定。 代码如下(示例):
static StackType_t CreateAppTask_Stack[128];
#define configSUPPORT_STATIC_ALLOCATION 0
2.1.2定义动态任务堆
则需定义Heap内存,从SRAM划分一块连续内存,于 heap_x.c 中实现。
代码如下(示例):
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 15 * 1024 ) )
#define configAPPLICATION_ALLOCATED_HEAP 0
#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#else
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#endif
void *pvPortMalloc( size_t xWantedSize )
{
if( pxEnd == NULL )
{
prvHeapInit();
}
}
void xTaskCreate()
{
pvPortMalloc();
}
2.2.定义任务控制块TCB
2.2.1 静态任务TCB
实例化TCB空间
static StaticTask_t CreateAppTask_TCB;
static TaskHandle_t AppTaskCreate_Handle = NULL;
2.2.2 动态任务TCB
异于静态创建,无需预先定义TCB空间,但需定义一个TCB指针,即Task_handle
static TaskHandle_t AppTaskCreate_Handle = NULL;
2.3创建任务
2.3.1静态创建
static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
static StaticTask_t IdleTaskTCB;
static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH];
static StaticTask_t TimerTaskTCB;
#define START_TASK_PRIO 1
#define START_STK_SIZE 128
StackType_t StartTaskStack[START_STK_SIZE];
StaticTask_t StartTaskTCB;
TaskHandle_t StartTask_Handler;
void start_task(void *pvParameters);
#define TASK1_TASK_PRIO 2
#define TASK1_STK_SIZE 128
StackType_t Task1TaskStack[TASK1_STK_SIZE];
StaticTask_t Task1TaskTCB;
TaskHandle_t Task1Task_Handler;
void task1_task(void *pvParameters);
#define TASK2_TASK_PRIO 3
#define TASK2_STK_SIZE 128
StackType_t Task2TaskStack[TASK2_STK_SIZE];
StaticTask_t Task2TaskTCB;
TaskHandle_t Task2Task_Handler;
void task2_task(void *pvParameters);
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer,
uint32_t *pulIdleTaskStackSize)
{
*ppxIdleTaskTCBBuffer=&IdleTaskTCB;
*ppxIdleTaskStackBuffer=IdleTaskStack;
*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
}
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize)
{
*ppxTimerTaskTCBBuffer=&TimerTaskTCB;
*ppxTimerTaskStackBuffer=TimerTaskStack;
*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;
}
2.3.2 动态创建
xReturn = xTaskCreate( (TaskFunction_t )AppTaskCreate,
(const char* )"AppTaskCreate",
(uint16_t )512,
(void* )NULL,
(UBaseType_t )1,
(TaskHandle_t* )&AppTaskCreate_Handle);
if (pdPASS == xReturn)
vTaskStartScheduler();
else
return -1;
static TaskHandle_t Task1Create_Handle = NULL;
static TaskHandle_t Task2Create_Handle = NULL;
TaskFunction_t AppTaskCreate()
{
BaseType_t xReturn = pdPASS;
xReturn = xTaskCreate( (TaskFunction_t )Task1_Crt,
(const char* )"Taks1",
(uint16_t )512,
(void* )NULL,
(UBaseType_t )2,
(TaskHandle_t* )&Task1Create_Handle);
if(1){};
printf("Re1:%d\n", (int)xReturn);
xReturn = xTaskCreate( (TaskFunction_t )Task2_Crt,
(const char* )"Task2",
(uint16_t )512,
(void* )NULL,
(UBaseType_t )3,
(TaskHandle_t* )&Task2Create_Handle);
if(1){};
printf("Re2:%d\n", (int)xReturn);
vTaskDelete(AppTaskCreate_Handle);
}
2.3.3 整体代码
static void Task1_Crt(void)
{
printf("create task1.\n");
while(1)
{
printf("task1.\n");
vTaskDelay(500);
}
}
static void Task2_Crt(void)
{
printf("create task2.\n");
while(1)
{
printf("task2.\n");
vTaskDelay(1000);
}
}
#if !(configSUPPORT_DYNAMIC_ALLOCATION & configSUPPORT_STATIC_ALLOCATION)
static TaskHandle_t StartTaskCreate_Handle = NULL;
static TaskHandle_t Task1Create_Handle = NULL;
static TaskHandle_t Task2Create_Handle = NULL;
TaskFunction_t StartTaskCreate(void)
{
BaseType_t xReturn = pdPASS;
taskENTER_CRITICAL();
xReturn = xTaskCreate( (TaskFunction_t )Task1_Crt,
(const char* )"Taks1",
(uint16_t )512,
(void* )NULL,
(UBaseType_t )2,
(TaskHandle_t* )&Task1Create_Handle);
if(1){};
printf("Re1:%d\n", (int)xReturn);
xReturn = xTaskCreate( (TaskFunction_t )Task2_Crt,
(const char* )"Task2",
(uint16_t )512,
(void* )NULL,
(UBaseType_t )3,
(TaskHandle_t* )&Task2Create_Handle);
if(1){};
printf("Re2:%d\n", (int)xReturn);
vTaskDelete(AppTaskCreate_Handle);
taskEXIT_CRITICAL();
}
#else
static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
static StaticTask_t IdleTaskTCB;
static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH];
static StaticTask_t TimerTaskTCB;
#define START_TASK_PRIO 1
#define START_STK_SIZE 128
StackType_t StartTaskStack[START_STK_SIZE];
StaticTask_t StartTaskTCB;
TaskHandle_t StartTask_Handler;
#define TASK1_TASK_PRIO 2
#define TASK1_STK_SIZE 128
StackType_t Task1TaskStack[TASK1_STK_SIZE];
StaticTask_t Task1TaskTCB;
TaskHandle_t Task1Task_Handler;
#define TASK2_TASK_PRIO 3
#define TASK2_STK_SIZE 128
StackType_t Task2TaskStack[TASK2_STK_SIZE];
StaticTask_t Task2TaskTCB;
TaskHandle_t Task2Task_Handler;
TaskFunction_t StartTaskCreate(void)
{
taskENTER_CRITICAL();
Task1Task_Handler=xTaskCreateStatic((TaskFunction_t )Task1_Crt,
(const char* )"task1_task",
(uint32_t )TASK1_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_TASK_PRIO,
(StackType_t* )Task1TaskStack,
(StaticTask_t* )&Task1TaskTCB);
Task2Task_Handler=xTaskCreateStatic((TaskFunction_t )Task2_Crt,
(const char* )"task2_task",
(uint32_t )TASK2_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_TASK_PRIO,
(StackType_t* )Task2TaskStack,
(StaticTask_t* )&Task2TaskTCB);
vTaskDelete(StartTask_Handler);
taskEXIT_CRITICAL();
}
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer,
uint32_t *pulIdleTaskStackSize)
{
*ppxIdleTaskTCBBuffer=&IdleTaskTCB;
*ppxIdleTaskStackBuffer=IdleTaskStack;
*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
}
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize)
{
*ppxTimerTaskTCBBuffer=&TimerTaskTCB;
*ppxTimerTaskStackBuffer=TimerTaskStack;
*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;
}
#endif
int main()
{
BaseType_t xReturn = pdPASS;
Sys_Init();
Reback_Boot();
UART_Debug_Init(SCI1,g_ips_clk, 115200);
Printf_Version();
#if !(configSUPPORT_DYNAMIC_ALLOCATION & configSUPPORT_STATIC_ALLOCATION)
xReturn = xTaskCreate( (TaskFunction_t )StartTaskCreate,
(const char* )"StartTaskCreate",
(uint16_t )512,
(void* )NULL,
(UBaseType_t )1,
(TaskHandle_t* )&AppTaskCreate_Handle);
#else
StartTask_Handler = xTaskCreateStatic((TaskFunction_t )StartTaskCreate,
(const char* )"StartTaskCreate",
(uint32_t )START_STK_SIZE,
(void* )NULL,
(UBaseType_t )START_TASK_PRIO,
(StackType_t* )StartTaskStack,
(StaticTask_t* )&StartTaskTCB);
#endif
if (pdPASS == xReturn)
vTaskStartScheduler();
else
return -1;
}
2.4启动现象
参考
- 启动流程-孤情剑客
- 静态任务-匿名
|