动态内存的管理方法:在SRAM中定义一个大的数组,也就是堆内存,供FreeRTOS的动态内存分配函数使用,在第一次使用的时候,系统会将定义的内存进行初始化,这些代码在FreeRTOS提供的内存管理方案中实现。
//系统所有堆得大小
#define configTOTAL_HEAP_SIZE (size_t)(36*1024))
static uint8_t ucHeap[configTOTAL_HEAP_SIZE ];
if(pxEnd==NULL)
{
prvHeapInit();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
其中堆内存的大小为 configTOTAL_HEAP_SIZE ,定义的堆得大小不能超过内部SRAM的总大小。如果是第一次会调用malloc需要将堆栈初始化,设置空闲块列表 方便以后分配内存,初始化完成后会取得堆的地址。
定义任务函数:任务函数的主体和使用静态偶函数时一样。
static void LED_Task(void * parameter)
{
while(1)
{
LED1_ON;
vTaskDelay(500);
LED1_OFF;
vTaskDelay(500);
}
}
任务必须是一个死循环,我们的AppTaskCreate任务执行一次后就进行删除,不影响系统的运行,所以只执行一次的任务在执行完毕时要记得及时删除。
定义任务栈:不用像使用静态内存一样预先定义全局的静态的栈空间,动态就是按需分配内存,随用随取。
1.定义任务控制块指针
任务句柄:任务句柄是一个指针,用于指向一个任务,当任务创建好之后,它就具有了一个任务句柄,以后我们想要操作这个任务都需要通过这个任务句柄,如果是自身的任务操作自己,那么这个句柄可以NULL
static TaskHandle_t AppTaskCreate_Handle=NULL;
static TaskHandle_t LED_Task_Handle=NULL;
2.动态任务创建
使用xTaskCreate()函数来创建任务
//创建AppTaskCreate任务
xReturn = xTaskCreate((TaskFunction_t)AppTaskCreate,(const char *)"AppTaskCreate",
(unit16_t)512,(void *) NULL,(UBaseType_t )1,
(TaskHandle_t *)&AppTaskCreate_Handle);
//启动任务调度
if(pdPASS=xReturn)
vTaskStartSchedule();//启动任务 开启调度
3.启动任务:任务创建好之后处于就绪状态 就绪任务可以参与操作系统的调度 此时任务只是创建了 还没有开启任务调度器 也没创建空闲任务和定时器任务 启动任务调度器后就不会再返回了 从此任务都由FreeRTOS管理 此时才是进入实时操作系统的第一步
//启动任务调度
if(pdPASS==xReturn)
vTaskStartScheduler();
else
return -1;
下载验证即可
创建多任务(SRAM动态内存):
创建两个任务:任务一 让一个LED灯闪烁 任务2 让另一个LED灯闪烁 两个LED灯闪烁的频率不一样 两个任务的优先级不一样
#include <FreeRTOS.h>
#include "task.h"
#include "LED.h"
#include "usart.h"
//创建任务句柄
static TaskHandle_t AppTaskCreate_Handle=NULL;
//LED1句柄任务
static TaskHandle_t LED1_Task_Handle=NULL;
//LED2任务句柄
static TaskHandle_t LED2_Task_Handle=NULL;
//函数声明
static void AppTaskFCreate(void);
static void LED1_Task(void * pvParameters);
static void LED2_Task(void * pvParameters);
static void Init(void); //用于初始化板载相关资源
int main()
{
BaseType_t xReturn=pdPASS; //定义一个创建信息返回值 默认为pdPASS;
Init();
printf("这是一个多任务创建实验:\n\r");
//创建AppTaskCreate任务
xReturn=xTaskCreate((TaskFunction_t)AppTaskCreate,(const char *)"AppTaskCreate",
(uint16_t)512,(void *)NULL,(UBaseType_t)1,(TaskHandle *)&AppTaskCreate_Handle);
if(pdPASS==xReturn)
vTaskStartSchedule();
else
return -1;
while(1);
}
static void AppTaskCreate(void)
{
BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */
taskENTER_CRITICAL(); //进入临界区
/* 创建 LED_Task 任务 */
xReturn = xTaskCreate((TaskFunction_t )LED1_Task, /* 任务入口函数 */
(const char* )"LED1_Task",/* 任务名字 */
(uint16_t )512, /* 任务栈大小 */
(void* )NULL, /* 任务入口函数参数 */
(UBaseType_t )2, /* 任务的优先级 */
(TaskHandle_t* )&LED1_Task_Handle);/* 任务控制块指针 */
if (pdPASS == xReturn)
printf("创建 LED1_Task 任务成功!\r\n");
/* 创建 LED_Task 任务 */
xReturn = xTaskCreate((TaskFunction_t )LED2_Task, /* 任务入口函数 */
(const char* )"LED2_Task",/* 任务名字 */
(uint16_t )512, /* 任务栈大小 */
(void* )NULL, /* 任务入口函数参数 */
(UBaseType_t )3, /* 任务的优先级 */
(TaskHandle_t* )&LED2_Task_Handle);/* 任务控制块指针 */
if (pdPASS == xReturn)
printf("创建 LED2_Task 任务成功!\r\n");
vTaskDelete(AppTaskCreate_Handle); //删除 AppTaskCreate 任务
taskEXIT_CRITICAL(); //退出临界区
}
static void LED1_Task(void * parameter)
{
while(1)
{
LED1_ON;
vTaskDelay(500);
LED1_OFF;
vTaskDelay(500);
}
}
static void LED2_Task(void * parameter)
{
while(1)
{
LED2_ON;
vTaskDelay(500);
LED2_OFF;
vTaskDelay(500);
}
}
static void Init()
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
LED_GPIO_Config();
USART_Config();
}