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

FreeRTOS静态任务的创建、删除和软件定时器的开启(尚硅谷学习笔记)

按照之前的动态任务进行相应的文件处理(此处就不在介绍)

/* 开启静态分配 */
#define configSUPPORT_STATIC_ALLOCATION 1/* 软件定时器相关定义 */
#define configUSE_TIMERS 1                                          /* 1: 使能软件定时器, 默认: 0 */
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1)        /* 定义软件定时器任务的优先级, 无默认configUSE_TIMERS为1时需定义 */
#define configTIMER_QUEUE_LENGTH 5                                  /* 定义软件定时器命令队列的长度, 无默认configUSE_TIMERS为1时需定义 */
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2) /* 定义软件定时器任务的栈空间大小, 无默认configUSE_TIMERS为1时需定义 */

在FreeRTOSConfig.h中添加开启静态分配和软件定时器相关的定义

相应需要配置的两个函数配置

/* ==================== 静态创建方式,需要手动指定2个特殊任务的资源======================= */
/* 空闲任务的配置 */
StackType_t idle_task_stack[configMINIMAL_STACK_SIZE]; // 静态任务的任务栈,以数组形式存储
StaticTask_t idle_task_tcb;                            // 静态任务的tcb结构体类型/* 软件定时器任务的配置 */
StackType_t timer_task_stack[configTIMER_TASK_STACK_DEPTH]; // 静态任务的任务栈,以数组形式存储
StaticTask_t timer_task_tcb;                                // 静态任务的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;
}

freertos_demo.c文件

/** @Author: random* @Date: 2025-05-10 01:23:40* @Last Modified by: random* @Last Modified time: Do not Edit*/
#include "freertos_demo.h"
/* freertos相关的头文件,必须的 */
#include "FreeRTOS.h"
#include "task.h"
/* 需要用到的其他头文件 */
#include "fun.h"/* 启动任务的配置 */
#define START_TASK_STACK 128
#define START_TASK_PRIORITY 1
TaskHandle_t start_task_handle;
StackType_t start_task_stack[START_TASK_STACK]; // 静态任务的任务栈,以数组形式存储
StaticTask_t start_task_tcb;                    // 静态任务的tcb结构体类型
void start_task(void *pvParameters);/* 任务1的配置 */
#define TASK1_STACK 128
#define TASK1_PRIORITY 2
TaskHandle_t task1_handle;
StackType_t task1_stack[TASK1_STACK]; // 静态任务的任务栈,以数组形式存储
StaticTask_t task1_tcb;               // 静态任务的tcb结构体类型
void task1(void *pvParameters);/* 任务2的配置 */
#define TASK2_STACK 128
#define TASK2_PRIORITY 3
TaskHandle_t task2_handle;
StackType_t task2_stack[TASK2_STACK]; // 静态任务的任务栈,以数组形式存储
StaticTask_t task2_tcb;               // 静态任务的tcb结构体类型
void task2(void *pvParameters);/* 任务3的配置 */
#define TASK3_STACK 128
#define TASK3_PRIORITY 4
TaskHandle_t task3_handle;
StackType_t task3_stack[TASK3_STACK]; // 静态任务的任务栈,以数组形式存储
StaticTask_t task3_tcb;               // 静态任务的tcb结构体类型
void task3(void *pvParameters);/* ==================== 静态创建方式,需要手动指定2个特殊任务的资源======================= */
/* 空闲任务的配置 */
StackType_t idle_task_stack[configMINIMAL_STACK_SIZE]; // 静态任务的任务栈,以数组形式存储
StaticTask_t idle_task_tcb;                            // 静态任务的tcb结构体类型/* 软件定时器任务的配置 */
StackType_t timer_task_stack[configTIMER_TASK_STACK_DEPTH]; // 静态任务的任务栈,以数组形式存储
StaticTask_t timer_task_tcb;                                // 静态任务的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;
}/*** @description: 启动FreeRTOS* @return {*}*/
void freertos_start(void)
{/* 1.创建一个启动任务 */start_task_handle = xTaskCreateStatic((TaskFunction_t)start_task,       // 任务函数的地址(char *)"start_task",             // 任务名字符串(uint32_t)START_TASK_STACK,       // 任务栈大小,默认最小128,单位4字节(void *)NULL,                     // 传递给任务的参数(UBaseType_t)START_TASK_PRIORITY, // 任务的优先级(StackType_t *)start_task_stack,  // 任务栈的地址(StaticTask_t *)&start_task_tcb); // tcb的地址/* 2.启动调度器:会自动创建空闲任务和空闲任务(如果开启),静态创建的方式需要去实现2个分配资源的接口函数 */vTaskStartScheduler();
}/*** @description: 启动任务:用来创建其他Task* @param {void} *pvParameters* @return {*}*/
void start_task(void *pvParameters)
{/* 进入临界区:保护临界区里的代码不会被打断 */taskENTER_CRITICAL();/* 使用静态创建3个任务 */task1_handle = xTaskCreateStatic((TaskFunction_t)task1,(char *)"task1",(configSTACK_DEPTH_TYPE)TASK1_STACK,(void *)NULL,(UBaseType_t)TASK1_PRIORITY,(StackType_t *)task1_stack,  // 任务栈的地址(StaticTask_t *)&task1_tcb); // tcb的地址task2_handle = xTaskCreateStatic((TaskFunction_t)task2,(char *)"task2",(configSTACK_DEPTH_TYPE)TASK2_STACK,(void *)NULL,(UBaseType_t)TASK2_PRIORITY,(StackType_t *)task2_stack,  // 任务栈的地址(StaticTask_t *)&task2_tcb); // tcb的地址task3_handle = xTaskCreateStatic((TaskFunction_t)task3,(char *)"task3",(configSTACK_DEPTH_TYPE)TASK3_STACK,(void *)NULL,(UBaseType_t)TASK3_PRIORITY,(StackType_t *)task3_stack,  // 任务栈的地址(StaticTask_t *)&task3_tcb); // tcb的地址/* 启动任务只需要执行一次即可,用完就删除自己 */vTaskDelete(NULL);/* 退出临界区 */taskEXIT_CRITICAL();
}/*** @description: 任务一:实现LED1每500ms闪烁一次* @param {void} *pvParameters* @return {*}*/
void task1(void *pvParameters)
{while (1){printf("task1 is running\r\n");led_n(1, 1);vTaskDelay(500);led_n(1, 0);vTaskDelay(500);}
}/*** @description: 任务二:实现LED2每500ms闪烁一次* @param {void} *pvParameters* @return {*}*/
void task2(void *pvParameters)
{while (1){printf("task2 is running\r\n");led_n(8, 1);vTaskDelay(500);led_n(8, 0);vTaskDelay(500);}
}/*** @description: 任务三:判断按键KEY1是否按下,按下则删掉task1* @param {void} *pvParameters* @return {*}*/
extern volatile uint8_t j;
extern volatile uint8_t key_number;
void task3(void *pvParameters)
{while (1){printf("task3 is running\r\n");if (key_number == 1){/* 判断是否已经删过,避免重复执行删除 */if (task1_handle != NULL){/* key1按下了,删除task1 */printf("task1 is delete\r\n");vTaskDelete(task1_handle);task1_handle = NULL;}key_number = 0;}vTaskDelay(500);// HAL_Delay(500); //这种delay不会让任务进入阻塞态,不会让出cpu使用权}
}

http://www.xdnf.cn/news/5418.html

相关文章:

  • 监控易一体化运维:任务计划管理的关键作用
  • 王道计算机网络知识点总结
  • 动态路由实现原理及前端控制与后端控制的核心差异
  • Linux:43线程封装与互斥lesson31
  • 前端Web开发HTML5+CSS3+移动web(基础-flex)
  • 基于Python的网络电子书阅读系统
  • 在Python中计算函数耗时并超时自动退出
  • 英语听力口语词汇--2.宣传类
  • 【时时三省】(C语言基础)字符数组
  • 关于TIAV20 PLCSIM仿真错误的原因
  • java中的io流
  • 专题一:汉诺塔问题:递归算法的精妙解析
  • PyGame游戏开发(含源码+演示视频+开结题报告+设计文档)
  • 【LwIP源码学习6】UDP部分源码分析
  • [思维模式-28]:《本质思考力》-8- 两种相反的构建与解构系统的思维模式:①自顶向下的分解、牵引;②自底向上的堆叠、聚合
  • 深入剖析 MyBatis 位运算查询:从原理到最佳实践
  • AI文字识别工具汇总
  • 控制LED灯设备
  • Linux epoll 详解:概念、使用、数据结构、流程及应用
  • C++:友元
  • CSS 基础知识分享:从入门到注意事项
  • 50.辐射抗扰RS和传导抗扰CS测试环境和干扰特征分析
  • Vue:生命周期钩子
  • 海上风电场数字孪生,可视化智慧运维
  • 20242817李臻《Linux⾼级编程实践》第9周
  • 鸿蒙开发RelativeContainer自适应高度
  • HTTP3详解
  • MySQL为什么选择B+树
  • TikTok 互动运营干货:AI 助力提升粘性
  • Next.js框架学习系列之一