FreeRTOS创建动态任务(SRAM动态内存)

本文详细介绍了在FreeRTOS中如何进行动态内存管理,通过在SRAM中定义堆内存,并利用FreeRTOS的内存管理函数进行初始化。同时,展示了如何创建和管理多个任务,包括任务栈的动态分配,任务的创建、删除和优先级设置。通过示例代码,演示了如何创建两个不同频率闪烁的LED任务,实现了多任务并行执行。
摘要由CSDN通过智能技术生成

动态内存的管理方法:在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();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值