当前位置: 首页 > news >正文

2.创建你的第一个FreeRTOS任务(动态与静态)

经过上一次的移植后,本次开始创建第一个FreeRTOS任务

1.创建一个动态的任务,动态分配内存

BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, //函数指针 const char * const pcName, //任务名字 const configSTACK_DEPTH_TYPE uxStackDepth, //任务栈大小(深度) void * const pvParameters, //任务参数 UBaseType_t uxPriority, //任务优先级 TaskHandle_t * const pxCreatedTask //任务句柄 ) // 函数名 传入参数 //任务函数typedef void (* TaskFunction_t)( void * arg );

上述包含了创建一个任务所需函数以及内部参数注释

1.1初始化硬件

首先初始化你的基础硬件比如LED_init这种确保led可以正常使用。

void system_init() { delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 LED_Init(); //LED端口初始化 KEY_Init(); //初始化与按键连接的硬件接口 }

1.2创建任务函数

比如想让一个灯循环闪烁可以这样写

void LED0_TASK(void *param) //任务函数 { while (1) { LED0 =!LED0; vTaskDelay(1000); } }

1.3 创建任务

TaskHandle_t xled_task_handle;//首先定义任务句柄(一种结构体)

通过下行命令创建任务

xTaskCreate(LED0_TASK,"open_led",100,NULL,1,&xled_task_handle); //动态分配内存

第一个参数为任务指针,第二个为任务名,第三个为堆栈大小暂时设定为100,传入该任务的参数设为空,最后一个传入刚刚创建的句柄地址。上述就是创建一个动态分配内存任务的过程。

2.创建一个静态分配内存的任务

首先打开FreeRTOSConfig.h,修改如下宏定义

#define configSUPPORT_STATIC_ALLOCATION 1 /* 1: 支持静态申请内存, 默认: 0 */ //此时改为1
//静态分配任务//默认不打开静态分配任务需要去FreeRTOSConfig.h文件中将configSUPPORT_STATIC_ALLOCATION宏定义为1 TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,//函数指针 const char * const pcName,//任务名字 const configSTACK_DEPTH_TYPE uxStackDepth,//任务栈大小(深度) void * const pvParameters,//任务参数 UBaseType_t uxPriority,//任务优先级 StackType_t * const puxStackBuffer,//静态栈分配空间 StaticTask_t * const pxTaskBuffer //分配TCB句柄 )

首先创建一个任务函数

void LED1_TASK(void *param) //任务函数 { while (1) { LED1 =!LED1; vTaskDelay(500); } }

第二步定义一个堆栈数据(一个数组),定义一个任务句柄

StackType_t xTaskLedStack[100] = {0};//注意此时数据堆栈大小需要按照创建的任务堆栈大小的深度一致 StaticTask_t xTaskLedBuffer;

最后创建一个静态任务

xTaskCreateStatic(LED1_TASK,"LED_Flicker",100,NULL,1,xTaskLedStack,&xTaskLedBuffer);

3.解决错误

通常在静态任务中会出现两个错误,如下

只要按照上面创建任务的方式将这两个函数重定义即可

如下:任务参数含义基本一致

// vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &uxIdleTaskStackSize );//参数1:空闲任务的TCB,参数2:空闲任务的栈,参数3:空闲任务栈大小 void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, configSTACK_DEPTH_TYPE * puxIdleTaskStackSize ) { *ppxIdleTaskTCBBuffer = &( xIdleTaskTCBBuffer ); *ppxIdleTaskStackBuffer = &( xIdleTaskStack[ 0 ] ); *puxIdleTaskStackSize = 100; } void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer, configSTACK_DEPTH_TYPE * puxTimerTaskStackSize ) { *ppxTimerTaskTCBBuffer = &( xTimerTaskTCBBuffer ); *ppxTimerTaskStackBuffer = &( xTimerTaskStack[ 0 ] ); *puxTimerTaskStackSize = 100; }

总的代码如下:

#include "led.h" #include "delay.h" #include "key.h" #include "sys.h" #include "FreeRTOS.h" #include "task.h" // BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, //函数指针 // const char * const pcName, //任务名字 // const configSTACK_DEPTH_TYPE uxStackDepth, //任务栈大小(深度) // void * const pvParameters, //任务参数 // UBaseType_t uxPriority, //任务优先级 // TaskHandle_t * const pxCreatedTask //任务句柄 // ) // 函数名 传入参数 //任务函数typedef void (* TaskFunction_t)( void * arg ); void system_init() { delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 LED_Init(); //LED端口初始化 KEY_Init(); //初始化与按键连接的硬件接口 } void LED0_TASK(void *param) //任务函数 { while (1) { LED0 =!LED0; vTaskDelay(1000); } } void LED1_TASK(void *param) //任务函数 { while (1) { LED1 =!LED1; vTaskDelay(500); } } StackType_t xTaskLedStack[100] = {0};//注意此时数据堆栈大小需要按照创建的任务堆栈大小的深度一致 StaticTask_t xTaskLedBuffer; StaticTask_t xIdleTaskTCBBuffer; StackType_t xIdleTaskStack[100] = {0}; StaticTask_t xTimerTaskTCBBuffer; StackType_t xTimerTaskStack[100] = {0}; //如果使用了静态分配内存必须提供如下函数 // vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &uxIdleTaskStackSize );//参数1:空闲任务的TCB,参数2:空闲任务的栈,参数3:空闲任务栈大小 void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, configSTACK_DEPTH_TYPE * puxIdleTaskStackSize ) { *ppxIdleTaskTCBBuffer = &( xIdleTaskTCBBuffer ); *ppxIdleTaskStackBuffer = &( xIdleTaskStack[ 0 ] ); *puxIdleTaskStackSize = 100; } void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer, configSTACK_DEPTH_TYPE * puxTimerTaskStackSize ) { *ppxTimerTaskTCBBuffer = &( xTimerTaskTCBBuffer ); *ppxTimerTaskStackBuffer = &( xTimerTaskStack[ 0 ] ); *puxTimerTaskStackSize = 100; } int main(void) { TaskHandle_t xled_task_handle; system_init(); //创建任务1 xTaskCreate(LED0_TASK,"open_led",100,NULL,1,&xled_task_handle); //动态分配内存 //静态分配任务//默认不打开静态分配任务需要去FreeRTOSConfig.h文件中将configSUPPORT_STATIC_ALLOCATION宏定义为1 // TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,//函数指针 // const char * const pcName,//任务名字 // const configSTACK_DEPTH_TYPE uxStackDepth,//任务栈大小(深度) // void * const pvParameters,//任务参数 // UBaseType_t uxPriority,//任务优先级 // StackType_t * const puxStackBuffer,//静态栈分配空间 // StaticTask_t * const pxTaskBuffer // ) xTaskCreateStatic(LED1_TASK,"LED_Flicker",100,NULL,1,xTaskLedStack,&xTaskLedBuffer); //开启调度器 vTaskStartScheduler(); while (1) { ; } // return 0; }
http://www.jsqmd.com/news/485257/

相关文章:

  • 项目实训开题
  • Three.js制作的3D魔方。
  • 0612-出租车(调价+昼夜)-系统设计(51+SEG+DS1302)
  • TimeLine如何自定义轨道
  • 035-spiderbuf第C12题
  • 嘎嘎降AI和笔灵AI哪个好?花200块实测对比告诉你
  • 手把手教你用嘎嘎降AI处理毕业论文:从上传到下载全流程 - 我要发一区
  • 计算机毕业设计java基于个性化推荐的众筹系统 基于用户画像的智能众筹平台的设计与开发 融合个性化推荐机制的创意项目融资系统的构建与实现
  • 品牌设计集团如何选择?
  • 基于SpringCloud的电子商城系统设计与应用
  • 2026年知网最新AIGC检测算法应对攻略 - 我要发一区
  • InnoDB中的undo日志和历史系统的基础机制
  • 四轮驱动汽车的线控转向系统失效+轨迹跟踪和横摆稳定性、失效容错控制仿真(带复现参考文献)
  • 降AI工具售后对比:退款政策/修改次数/客服响应 - 我要发一区
  • 【无人机通信】考虑Nakagami-m衰落和逆伽马阴影衰落效应的空中智能反射面辅助无线通信系统(无人机群改型)附matlab代码
  • 初创企业数字化基础工具白皮书——中资源企业邮箱解决方案 - 优质品牌商家
  • C++——数组类模板
  • LCM,GCD
  • 5款降AI工具实测对比:价格从4块到10块效果差多少
  • 什么是 SMD 封装?是不是都不带引脚?
  • 宝宝敏感肌安心护肤油
  • Java面试复盘笔记,2026突击必备!
  • Matlab速成笔记七十三:三角函数运算的用法
  • 虚拟机安装流程
  • Docker 核心知识点
  • 国产AI驱动的超自动化巡检“龙虾”来了
  • 基于SpringBoot的中华历史故事展播系统设计与应用
  • 微短剧《嘉庆君游台湾》开机 童星麦片(吴羽朔)助力嘉庆渡台行
  • 古镇文旅旧改活化优质公司推荐:游玩体验提升效果解析
  • 智能体驱动的企业IT架构转型