当前位置:   article > 正文

FreeRTOS任务启动流程实践_freertos启动流程

freertos启动流程


前言

最近熟悉一款基于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);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

2.创建任务

2.1 定义任务栈

2.1.1定义静态任务栈

则需要优先定义Stack,栈空间从SRAM分配,地址由编译器决定。
代码如下(示例):

//main.c
static StackType_t CreateAppTask_Stack[128]; //定义任务栈
  • 1
  • 2
//FreeRTOSConfig.h
/* Memory allocation related definitions. */
//1: 内存静态分配
#define configSUPPORT_STATIC_ALLOCATION         0
  • 1
  • 2
  • 3
  • 4
2.1.2定义动态任务堆

则需定义Heap内存,从SRAM划分一块连续内存,于 heap_x.c 中实现。

代码如下(示例):

//FreeRTOSConfig.h
//1: 内存动态分配,没有配置此选项时系统默认使用动态分配方式
#define configSUPPORT_DYNAMIC_ALLOCATION        1
//堆大小
#define configTOTAL_HEAP_SIZE		            ( ( size_t ) ( 15 * 1024 ) )
//1: 允许应用程序将堆放在内存中的任意位置
#define configAPPLICATION_ALLOCATED_HEAP        0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
//heap_4.c
/* Allocate the memory for the heap. */
#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
	/* The application writer has already defined the array used for the RTOS
	heap - probably so it can be placed in a special segment or address. */
	extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#else
	static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#endif /* configAPPLICATION_ALLOCATED_HEAP */


void *pvPortMalloc( size_t xWantedSize )
{
	//...
	if( pxEnd == NULL )
	{
		prvHeapInit(); //调用 ucHeap[]
	}
	//...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
//tasks.c
void xTaskCreate()
{
	//...
	pvPortMalloc();
	//...
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.2.定义任务控制块TCB

2.2.1 静态任务TCB

实例化TCB空间

//main.c
//CreateAppTask任务控制块
static StaticTask_t CreateAppTask_TCB; 
static TaskHandle_t AppTaskCreate_Handle = NULL;  
  • 1
  • 2
  • 3
  • 4
2.2.2 动态任务TCB

异于静态创建,无需预先定义TCB空间,但需定义一个TCB指针,即Task_handle

//main.c
//创建任务句柄
static TaskHandle_t AppTaskCreate_Handle = NULL;  
  • 1
  • 2
  • 3

2.3创建任务

2.3.1静态创建
//main.c
//空闲任务
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);

//任务1变量声明
#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);

//任务2声明变量
#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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
2.3.2 动态创建
//main.c
//创建 AppTaskCreate 任务
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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
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); 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
2.3.3 整体代码
/************************************
*	Create task, prime conditions are concrete objects, defination of TCB, also the task of creation.
*	
*/
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/dynamic task
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
//idle
static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
static StaticTask_t IdleTaskTCB;

//timer
static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH];
static StaticTask_t TimerTaskTCB;

//start
#define START_TASK_PRIO		1
#define START_STK_SIZE 		128  
StackType_t StartTaskStack[START_STK_SIZE];
StaticTask_t StartTaskTCB;
TaskHandle_t StartTask_Handler;

//1
#define TASK1_TASK_PRIO		2
#define TASK1_STK_SIZE 		128  
StackType_t Task1TaskStack[TASK1_STK_SIZE];
StaticTask_t Task1TaskTCB;
TaskHandle_t Task1Task_Handler;


//2
#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();         
    //1
	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);	
   //2
	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); //del start
    taskEXIT_CRITICAL();          
}

//idle
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, 
								   StackType_t **ppxIdleTaskStackBuffer, 
								   uint32_t *pulIdleTaskStackSize)
{
	*ppxIdleTaskTCBBuffer=&IdleTaskTCB;
	*ppxIdleTaskStackBuffer=IdleTaskStack;
	*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
}
//timer
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();
//	App_Demo();
#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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157

2.4启动现象

在这里插入图片描述


参考

  1. 启动流程-孤情剑客
  2. 静态任务-匿名
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/677264
推荐阅读