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

网站备案如何取消接入黑马程序员培训机构官网

网站备案如何取消接入,黑马程序员培训机构官网,成都网站建设零一,光明随心订网站怎么做FreeRTOS踩坑小记——vTaskList函数的使用前言vTaskList函数的简要介绍**1. 函数原型与作用****2. 输出信息格式**踩坑概述问题及解决问题1:在任务的执行函数中定义了大数组导致栈溢出解决问题问题2:分配给vTaskList函数的参数buffer太小解决问题调用 vT…

FreeRTOS踩坑小记——vTaskList函数的使用

  • 前言
  • vTaskList函数的简要介绍
      • **1. 函数原型与作用**
      • **2. 输出信息格式**
  • 踩坑概述
  • 问题及解决
    • 问题1:在任务的执行函数中定义了大数组导致栈溢出
      • 解决问题
    • 问题2:分配给vTaskList函数的参数buffer太小
      • 解决问题
  • 调用 vTaskList() 导致硬 fault其他错误可能的原因
  • 总结

前言

在 FreeRTOS 中,vTaskList() 是一个用于调试的实用函数,用于输出系统中所有任务的详细状态信息。我在使用中遇到了坑,今天分享出来,希望大家不会踩到。

vTaskList函数的简要介绍

1. 函数原型与作用

void vTaskList( char *pcWriteBuffer );
  • 作用:将系统中所有任务的状态、堆栈使用情况等信息格式化为字符串,存储到 pcWriteBuffer 中。
  • 依赖配置:需在 FreeRTOSConfig.h 中定义:
    #define configUSE_TRACE_FACILITY    1  // 启用追踪功能
    #define configUSE_STATS_FORMATTING_FUNCTIONS 1  // 启用状态格式化
    

2. 输出信息格式

vTaskList() 会生成一个表格,包含以下字段:

Name          State   Priority  Stack    Num
<任务名称>     <状态>    <优先级>   <剩余栈>  <编号>
  • 字段说明
    • Name:任务名称(创建时通过 pcName 参数指定)。
    • State:任务状态缩写:
      • R = 运行态(Running)
      • B = 阻塞态(Blocked)
      • D = 删除态(Deleted,等待清理)
      • S = 挂起态(Suspended)
      • R = 就绪态(Ready)
    • Priority:任务当前优先级。
    • Stack:任务堆栈的剩余空间(字节),反映堆栈使用情况。
    • Num:任务编号(唯一标识符,由内核分配)。

踩坑概述

我在FreeRTOS中创建了2个任务,写队列的任务,比读任务的优先级高。我在写任务的执行函数中调用了 vTaskList(),结果导致HardFault
下面是代码:
这个任务函数做的是在队列里写数据,但两个写队列的任务都会调用它。

static void vSenderTask(void *pvParameters)  // 发送任务
{BaseType_t xStatus = pdFAIL;const TickType_t xTicksToWait = pdMS_TO_TICKS(100UL);char InfoBuffer[100];				//保存信息的数组 vTaskList(InfoBuffer);							            //获取所有任务的信息printf("%s\r\n",InfoBuffer);					//通过串口打印所有任务的信息printf("B 阻塞态\tR 就绪态\tS 挂起态\tD 删除态\tR 也是运行态\r\n");for(;;){if(NULL != xQueue){xStatus = xQueueSendToBack(xQueue, pvParameters, xTicksToWait);}else{printf("NULL == xQueue.\r\n");}if(xStatus != pdPASS){printf("Can not send to the queue.\r\n");}}
}

队列的创建和任务的创建过程如下:

typedef enum
{eMotorSpeed,eSpeedSetPoint
}ID_t;typedef struct Data_Queue
{ID_t ID;uint32_t DataValue;
}Data_t;static const Data_t DataArray[] = 
{{eMotorSpeed, 100},         /*CAN 任务发送的数据*/{eSpeedSetPoint, 200},      /*HMI任务发送的数据*/
};static QueueHandle_t xQueue = NULL;/*队列句柄*/xQueue = xQueueCreate(5, sizeof(Data_t)); xTaskCreate(vSenderTask, "CAN Task Sender", 100, (void *)&(DataArray[0]), 2, CAN_Sender_Handler);              
xTaskCreate(vReceiverTask, "Receiver", 100, NULL, 1, Receive_Handler);

看到这里的童鞋不知道有没有看出来问题?

问题及解决

问题1:在任务的执行函数中定义了大数组导致栈溢出

在这里插入图片描述

在 C 语言中,函数内定义的局部变量(包括数组)存储在栈上。在 FreeRTOS 中,每个任务有独立的栈空间,创建任务时通过 xTaskCreate()usStackDepth 参数指定:

在这里插入图片描述

很明显,栈空间一共才100字节,怎么可以在里面开辟100字节的空间呢?在任务函数中定义大数组,会直接消耗栈空间,可能导致以下问题:

  1. 栈溢出风险

    • 后果:栈溢出会覆盖相邻内存(如任务控制块 TCB),导致 HardFault、任务崩溃或系统不稳定。
    • 调试提示:若任务频繁崩溃或进入 HardFault,可能是栈溢出。
  2. 内存碎片化
    每个任务的栈空间在创建时固定分配。若任务栈过大:

    • 系统总内存消耗增加,可能导致后续任务创建失败。
    • 内存碎片化加剧,影响动态内存分配效率。

解决问题

  1. 方法一:动态内存分配
    使用 pvPortMalloc()上分配内存:
    char * InfoBuffer= (char *)pvPortMalloc(1000 * sizeof(char));if (InfoBuffer != NULL) {vTaskList(InfoBuffer);							            //获取所有任务的信息printf("%s\r\n",InfoBuffer);					//通过串口打印所有任务的信息printf("B 阻塞态\tR 就绪态\tS 挂起态\tD 删除态\tR 也是运行态\r\n");vPortFree(InfoBuffer);  // 使用后释放}
  1. 方法二:增加任务栈深度
    计算数组和局部变量总大小,适当增加 usStackDepth
// 为任务分配更大的栈空间
xTaskCreate(vSenderTask, "CAN Task Sender", 1000, (void *)&(DataArray[0]), 2, CAN_Sender_Handler);
  1. 方法三:使用静态全局数组
    将数组定义为 static 或全局变量,存储在数据段而非栈上:
static char InfoBuffer[1000];  // 全局静态数组,不占用栈空间
static void vSenderTask(void *pvParameters)  // 发送任务
{vTaskList(InfoBuffer);							            //获取所有任务的信息printf("%s\r\n",InfoBuffer);					//通过串口打印所有任务的信息printf("B 阻塞态\tR 就绪态\tS 挂起态\tD 删除态\tR 也是运行态\r\n");
//其他代码
}
  1. 检测栈溢出

FreeRTOSConfig.h 中定义宏:

#define configCHECK_FOR_STACK_OVERFLOW			1                      //大于0时启用堆栈溢出检测功能,如果使用此功能                                                                        

实现钩子函数:

void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) {printf("Stack overflow detected in task: %s\n", pcTaskName);// 处理溢出(如重启系统)
}

问题2:分配给vTaskList函数的参数buffer太小

在这里插入图片描述

解决问题

需要至少分配512字节的空间,如果任务很多的话,需要更多空间。

char InfoBuffer[1000];				//保存信息的数组       

调用 vTaskList() 导致硬 fault其他错误可能的原因

若调用 vTaskList() 导致硬 fault(HardFault),通常是以下原因:

  1. 缓冲区溢出:增大 buffer 大小。
  2. 栈空间不足:增加调用该函数的任务的栈大小。
  3. 未启用追踪功能:检查 FreeRTOSConfig.h 配置。
  4. 中断中调用:确保只在任务上下文中调用。

总结

vTaskList() 是 FreeRTOS 中强大的调试工具,通过输出任务状态和资源使用情况,帮助开发者快速定位系统问题。但需注意需要给调用的任务足够的栈空间,尤其是任务很多的话,需要分配更多字节。另外还需要给vTaskList() 函数准备足够的InfoBuffer
此外,调用 vTaskList() 时会暂停所有任务,可能影响系统实时性,仅用于调试

http://www.dtcms.com/wzjs/328932.html

相关文章:

  • 怎样开发一个管理系统什么是搜索引擎优化seo
  • git怎么做隐私政策网站网推公司干什么的
  • 物业管理系统app宁波seo推广优化怎么做
  • 手机网站建设市场报价网络热词的利弊
  • 网站设计基本流程关键词搜索趋势
  • 网站建设标准流程及外包注意事项打开百度app
  • 做系统网站建设百度开户推广多少钱
  • 湛江做网站seo的公司软文推广
  • 线上设计师网站国内手机怎么上google浏览器
  • 交友网站建设策划方案(2)百度联盟个人怎么接广告
  • 做网站公司-汉狮网络seo外链友情链接
  • 网站开发有什么软件有哪些seo优化网络公司排名
  • 个人个案网站 类型谷歌独立站推广
  • 网站建设冒用身份信息郑州网站运营专业乐云seo
  • 做网站找外包好吗图片优化
  • 东莞网站建设设计公司seo网站关键词优化工具
  • 元典科技网站建设怎么自己做一个网站
  • 衡水制作网站seo专员是指什么意思
  • 在线答题网站怎么做百度推广用户注册
  • 张家港建网站费用网页制作html代码
  • 做网站排名推广效果怎么样百度收录网址提交
  • 无锡专业网站排名推广单词优化和整站优化
  • 如何利用个人nas做网站最新seo视频教程
  • 旅游电商网站有哪些我是站长网
  • 晴天阴天雨天wordpress优化公司治理结构
  • 网站平台建设实训体会品牌推广的渠道有哪些
  • 湖州建设局新网站网站设计公司官网
  • 无锡网站建设公司网站排名优化公司
  • 素材网站哪个最好互联网推广公司排名
  • 天津网站开发tjniu网站手机优化