1. 硬件初始化
为了方便以后统一管理板级外设的初始化,我们在main.c文件中创建一个BSP_Init()函数,专门用于存放板级外设初始化函数。
整个系统的运作流程
BSP_Init()
创建任务
启动调度器
····
注意:#include "FreeRTOS.h"和#include "task.h"需要包含在stm32f10x_it.c中
2. 创建单任务-SRAM静态内存
2.1 定义任务函数
static void AppTaskCreate(void) //启动任务函数:
static void BSP_Init(void) //初始化外设函数
static void LED_Task(void* parameter) //任务主体函数
{
while (1)
{
LED1_ON;
vTaskDelay(500); /* 延时500个tick */
printf("LED_Task Running,LED1_ON\r\n");
LED1_OFF;
vTaskDelay(500); /* 延时500个tick */
printf("LED_Task Running,LED1_OFF\r\n");
}
}
注意:需要去FreeRTOSConfig.h中把config_STATIC_ALLOCATION(支持静态内存)的值改为1
2.2 空闲任务与定时器任务堆栈函数实现
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; /* 定时器任务控制块 */
/*获取空闲任务的任务堆栈和任务控制块内存函数*/
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer,
uint32_t *pulIdleTaskStackSize)
{
*ppxIdleTaskTCBBuffer=&Idle_Task_TCB;/* 任务控制块内存 */
*ppxIdleTaskStackBuffer=Idle_Task_Stack;/* 任务堆栈内存 */
*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;/* 任务堆栈大小 */
}
/*获取定时器任务的任务堆栈和任务控制块内存函数*/
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize)
{
*ppxTimerTaskTCBBuffer=&Timer_Task_TCB;/* 任务控制块内存 */
*ppxTimerTaskStackBuffer=Timer_Task_Stack;/* 任务堆栈内存 */
*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;/* 任务堆栈大小 */
}
2.3定义任务栈
static StackType_t Idle_Task_Stack[configMINIMAL_STACK_SIZE]; /* 空闲任务任务堆栈 */
static StackType_t Timer_Task_Stack[configTIMER_TASK_STACK_DEPTH]; /* 定时器任务堆栈 */
2.4 定义任务控制块
static StaticTask_t LED_Task_TCB;
static StaticTask_t AppTaskCreate_TCB;
2.5 静态创建任务
/* 创建 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); //任务控制块
2.6 启动任务
/* 启动任务,开启调度 */
1 vTaskStartScheduler();
3. 创建单任务-SRAM动态内存
- 动态内存空间的堆从哪里来?
在创建单任务—SRAM静态内存的例程中,任务控制块和任务栈的内存空间都是从内部的SRAM里面分配的,具体分配到哪个地址由编译器决定。
现在我们开始使用动态内存,即堆内存,也属于SRAM。FreeRTOS做法是在SRAM里面定义一个大数组作为堆内存空间,供FreeRTOS的动态内存分配函数使用。
堆内存的大小为configTOTAL_HEAP_SIZE,在FreeRTOSConfig.h中由我们自己定义,configSUPPORT_DYNAMIC_ALLOCATION 这个宏定义在使用FreeRTOS操作系统的时候必须开启。
注意:定义的堆大小不能超过内部SRAM的总大小。
3.1 定义任务函数
static void AppTaskCreate(void) //启动任务函数:
static void BSP_Init(void) //初始化外设函数
static void LED_Task(void* parameter) //任务主体函数
{
while (1)
{
LED1_ON;
vTaskDelay(500); /* 延时500个tick */
printf("LED_Task Running,LED1_ON\r\n");
LED1_OFF;
vTaskDelay(500); /* 延时500个tick */
printf("LED_Task Running,LED1_OFF\r\n");
}
}
3.2 定义任务控制块指针
static TaskHandle_t AppTaskCreate_Handle; /* 创建任务句柄 */
static TaskHandle_t LED_Task_Handle; /* LED任务句柄 */
3.3 动态任务创建
/* 创建AppTaskCreate任务 */
xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate, /* 任务入口函数 */
(const char* )"AppTaskCreate",/* 任务名字 */
(uint16_t )512, /* 任务栈大小 */
(void* )NULL,/* 任务入口函数参数 */
(UBaseType_t )1, /* 任务的优先级 */
(TaskHandle_t* )&AppTaskCreate_Handle);/* 任务控制块指针(任务句柄) */
3.4 启动任务
if(pdPASS == xReturn)
{
printf("创建LED_Task任务成功!\r\n");
vTaskStartScheduler(); //启动任务,开启调度
}
else
return -1;
while(1);
4. 创建多任务-SRAM动态内存
步骤基本与创建单任务-SRAM动态内存一致
- 定义任务函数
注意:比单任务多x个任务函数
- 定义任务控制块指针
注意:每个任务都要一个任务句柄
static TaskHandle_t LED_Task_Handle = NULL; /* LED任务句柄 */
static TaskHandle_t LED2_Task_Handle = NULL; /* LED2任务句柄 */
-
动态创建多个任务
-
启动任务