单片机通信数据延迟问题排查

2023-11-17

1、问题说明

笔者在最近的项目中,发现系统的响应延迟较高。经过排查,排除了单片机运行卡死的问题。

2、原因分析

具体排查过程这里就不细致说明了,直接给出排查后原因。任务执行周期规划不合理,导致freertos队列发送接收到的命令有延迟。

为了便于理解,这里就不展示代码,直接展示一段简单的示例代码会更清晰。先看下代码的框图
在这里插入图片描述
上图较为清晰的说明了两个任务的功能及执行周期。下面看下具体实现的代码

void task1(void *pvParameters)
{

	uint8_t data = 1;
	uint16_t count = 0;
	while (1)
	{
		if(count==0)
		{
			printf("task1 data: %d \r\n",data);		
		}

		xQueueSend(txque,&data,0);
		count++;
		if(count>=100)
		{
			data++;		
			count = 0;
		}
		vTaskDelay(10);
	}
}
void task2(void *pvParameters)
{
	uint8_t data = 0;
	static uint8_t data_old = 0;
	uint32_t err =0 ;
	while (1)
	{
		err = xQueueReceive(txque,&data,0);
		if(err == pdPASS)
		{
			if(data!=data_old)
			{
				printf("task2 data: %d \r\n",data);	
			}
			data_old = data;
		}
		vTaskDelay(100);
	}
}

为了便于方便观察,任务1的data值,每个1s变化一次。queue长度为20。
编译运行,结果如图
在这里插入图片描述
处理第一次发送的1延迟了100ms左右,其他每个数据都延迟了将近2s中。这就造成了发送与接收的延迟。上文遇到的就是这个现象。原因就是发送与接收不同步,再看看下整个过程中队列内数据的变化。
在这里插入图片描述
第0ms,task1个空队列发送了一个1,但是此时由于task2需要延时100ms,所以等到第100ms,task2才收到task1第0ms发送的数据1.task1打印数据1

第100ms,由于task1是每隔10ms給队列发送一个1,所以此时队列中有10个1,刚好此时,任务2完成100ms延时,开始接收队列数据,就收到了第一个数据1。task2打印出数据1.

第200ms,此时task1以及向队列发送了20个1,由于在第100ms任务2接收了一个第一个数据1,所以此时队列中一共有19个1。此时task2接收到了第二个数据1. 由于值没有变化,task2不打印数据。

第220ms-999ms,此时队列中的数据全部是1,由于队列长度是20.所以第230ms的数据1实际上没有发送出去,因为队列满了。

第1000ms,此时由于task2接收到了一个数据1,队列中空出来1个位置。同时,task1中值变化为2,由于队列中空出来一位,所有任务1将数据2发送到了队列的末尾的位置。 task1打印数据2

由于队列长度为20,任务2运行周期为100ms,所以任务2要将队列中数据全部接收完毕,需要2000ms。也就是说第1000ms任务1发送的数据2,任务2在第3000ms的时候才能接收到。

通过上面的分析,可以得知,由于任务1执行的速度是任务2的10倍,所以任务2接收数据的最大延迟为20*100ms为2000ms,基本与上面的运行结果的截图一致。

3、问题解决

经过上面的分析后,问题的根本原因是,任务1和2执行的周期不协调造成。所以修改方式也比较简单,只需要将任务1的执行周期同样改为100ms,此时最大延迟也就是100ms。相当于任务1发送数据的时候,任务2刚好完成接收进入了睡眠,只有等100ms延时之后,任务2才能接收到刚刚任务1发送的数据。

最好的解决办法是,去掉任务2的运行周期延迟,改为任务2接收队列是无限等待,任务1保持不变。只要队列中有数据,立刻接收。更改后的任务2如下:

void task2(void *pvParameters)
{
	uint8_t data = 0;
	static uint8_t data_old = 0;
	uint32_t err =0 ;
	while (1)
	{
		err = xQueueReceive(txque,&data,portMAX_DELAY );
		if(err == pdPASS)
		{
			if(data!=data_old)
			{
				printf("task2 data: %d \r\n",data);	
			}
			data_old = data;
		}
//		vTaskDelay(100);
	}
}

更改后的运行结果如下图:
在这里插入图片描述
发送与接收实现了同步,基本没有延迟。

注意:采用队列接收无限等待的方式,会造成任务2只有在接收到了数据的时候才会运行,没有收到数据就一直睡眠。如果任务2中有其他需要定期执行的事情的时候,该方法就不合适,只能将任务的运行周期改为100ms。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单片机通信数据延迟问题排查 的相关文章

  • VS Code 有没有办法导入 Makefile 项目?

    正如标题所说 我可以从现有的 Makefile 自动填充 c cpp properties json 吗 Edit 对于其他尝试导入 makefile 的人 我找到了一组脚本 它们完全可以实现我想要实现的目标 即通过 VS Code 管理
  • 华为OD机试真题-部门人力分配-2023年OD统一考试(C卷)

    题目描述 部门在进行需求开发时需要进行人力安排 当前部门需要完成N个需求 需求用requirements 表示 requirements i 表示第i个需求的工作量大小 单位 人月 这部分需求需要在M个月内完成开发 进行人力安排后每个月的人
  • 华为OD机试真题-部门人力分配-2023年OD统一考试(C卷)

    题目描述 部门在进行需求开发时需要进行人力安排 当前部门需要完成N个需求 需求用requirements 表示 requirements i 表示第i个需求的工作量大小 单位 人月 这部分需求需要在M个月内完成开发 进行人力安排后每个月的人
  • 《妙趣横生的算法》(C语言实现)- 第6章 数学趣题(二)

    6 1 连续整数固定和问题 找出任意输入的整数n的全部的连续整数固定和 题目分析 至少要找出两个连续整数的固定和 一个整数的话就是本身了呢 那如何确定这些连续整数呢 想明白了 第一个整数设为a 第二个整数是a 1 假设有m个连续整数 那么第
  • 最终启动顺序错误 - STM32L476 的 Eclipse System Workbench 调试

    我正在尝试调试和运行 STM32L476 的简单汇编代码 我已经设置了 Eclipse Oxygen 在 Eclipse 中安装了最新版本的 System Workbench 插件并安装了 ST Link 驱动程序 IDE 成功构建了程序
  • BMS开发之面向对象思想(adbms1818)

    借鉴adbms1818的底层驱动代码 前言 adbms1818的主要用途就是不同种类的寄存器里面存储不同的数据 程序员需要通过特定的协议往寄存器里面写入或者读出数据 1 定义一个结构体 里面存储了adbms1818的所有寄存器的信息 然后我
  • STM32 暂停调试器时冻结外设

    当到达断点或用户暂停代码执行时 调试器可以停止 Cortex 中代码的执行 但是 当皮质停止在暂停状态下执行代码时 调试器是否会冻结其他外设 例如 DMA UART 和定时器 您只能保留时间 r 取决于外围设备 我在进入主函数时调用以下代码
  • 无法使用 OpenOCD 找到脚本文件

    我正在尝试按照本教程将 OpenOCD 与我的 ST 发现板一起使用 https japaric github io discovery README html https japaric github io discovery READM
  • Freertos低功耗管理

    空闲任务中的低功耗Tickless处理 在整个系统运行得过程中 其中大部分时间都是在执行空闲任务的 空闲任务之所以执行 因为在系统中的其他任务处于阻塞或者被挂起时才会执行 因此可以将空闲任务的执行时间转换成低功耗模式 在其他任务解除阻塞而准
  • CMSIS & STM32,如何开始? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想在 STM32 上使用 CMSIS 启动项目 网上一搜 没找到具体的教程 有些使用 SPL 开始项
  • Arm:objcopy 如何知道 elf 中的哪些部分要包含在二进制或 ihex 中?

    我正在开发一个项目 其中涉及解析arm elf 文件并从中提取部分 显然 elf 文件中有很多部分没有加载到闪存中 但我想知道 objcopy 到底如何知道要在二进制文件中包含哪些部分以直接闪存到闪存中 以arm elf文件的以下reade
  • 库函数点亮Led

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 例如 随着人工智能的不断发展 机器学习这门
  • STM32H5 Nucleo-144 board开箱

    文章目录 开发板资料下载 目标 点亮LD1 绿 LD2 黄 和LD3 红 三个LED灯 开箱过程 博主使用的是STM32CubeMX配置生成代码 具体操作如下 打开STM32CubeMX File gt New project 选择开发板型
  • 特殊寄存器

    特殊寄存器 文章目录 前言 一 背景 二 2 1 2 2 总结 前言 前期疑问 STM32特殊寄存器到底是什么 特殊寄存器怎么查看和调试代码 本文目标 记录和理解特殊寄存器 一 背景 最近在看ucosIII文章是 里面提到特殊寄存器 这就进
  • Cortex-M3与M4权威指南

    处理器类型 所有的ARM Cortex M 处理器是32位的精简指令集处理器 它们有 32位寄存器 32位内部数据路径 32位总线接口 除了32位数据 Cortex M处理器也可以有效地处理器8位和16位数据以及支持许多涉及64位数据的操作
  • 有可用的 FreeRTOS 解释语言库吗?

    我在一家公司工作 该公司使用 FreeRTOS 为多个设备创建固件 最近 我们对新功能的要求已经超出了我们固件工程师的工作能力 但我们现在也无力雇用任何新人 即使进行微小的更改 也需要固件人员在非常低的级别上进行修改 我一直在为 FreeR
  • STM32 上的位置无关代码 - 指针

    我已成功在 STM32 上构建并运行位置无关的代码 向量表和 GOT 已修补 一切正常 但我对这样的代码有问题 double myAdd double x return x 0 1 double ptrmyAdd double myAdd
  • 在 Contiki 程序中使用 malloc

    考虑以下 Contiki 程序 include
  • GNU Arm Cortex m4 上的 C++ 异常处理程序与 freertos

    2016 年 12 月更新现在还有一个关于此行为的最小示例 https community nxp com message 862676 https community nxp com message 862676 我正在使用带有 free
  • 当端点和 PMA 地址均更改时,CubeMX 生成的 USB HID 设备发送错误数据

    我正在调试我正在创建的复合设备的问题 并在新生成的仅 CubeMX 代码中重新创建了该问题 以使其更容易解决 我添加了少量代码main 让我发送 USB HID 鼠标点击 并在按下蓝色按钮时使 LED 闪烁 uint8 t click re

随机推荐

  • Android 首次开机进入 Launcher3 前黑屏几秒的情况问题的总结

    Android 首次开机进入 Launcher3 前黑屏几秒的情况问题的总结 首先 让我们来探讨一下 Android 系统在首次开机时为何会出现黑屏几秒的情况 在 Android 系统启动过程中 首先会加载 Linux 内核 然后启动 An
  • 关于生成图片

    数组生成图片 image Image fromarray np uint8 arr arr的shape必须是3在后面 比如 375 500 3 tensor生成图片 trans transforms ToPILImage image tra
  • 华为OD机试 - 代表团坐车(Java)

    题目描述 某组织举行会议 来了多个代表团同时到达 接待处只有一辆汽车 可以同时接待多个代表团 为了提高车辆利用率 请帮接待员计算可以坐满车的接待方案 输出方案数量 约束 一个团只能上一辆车 并且代表团人数 代表团数量小于30 每个代表团人数
  • c++栈的练习题

    1 Problem Detail 入门 火车编组 追梦算法网 栈的练习题 include
  • System.UnauthorizedAccessException: Access to the path is denied

    这个异常一般是操作文件读写时发生 一般有以下四个原因 调用方没有所需的权限 该文件是一个正在使用的可执行文件 路径是一个目录 该文件只读
  • javascript中的数字校验

    javascript限制输入的只能是数字 判断event keyCode的值 并将它限定只能为数字 如果不是数字 则返回错误 如果是数字 则继续 我先介绍验证javascript是否是数字另一种方式 通过下面的函数来实现 function
  • Unity3D之MonoBehaviour

    Unity3D中的MonoBehaviour是一种基于组件的编程架构 用于开发游戏和应用程序 它是Unity引擎中用于创建行为的基类之一 并且可以让你通过重写其方法来定义对象在游戏运行时的行为 首先 在Unity中创建一个游戏对象并向其添加
  • 使用vue+echarts世界地图航线路线

    这是一个vue结合echarts做的船舶轨迹运行线路图 一 安装echarts npm install echarts 二 全局引入 在全局引入 需要在main js文件中 引入echarts import echarts from ech
  • Unity3D模型

    SolidWorks建模导入Unity 前言 使用的版本 SolidWorks导入3DMax 3DMax导入Unity 结尾 前言 本篇主要作为个人经验记录 因项目需要将SW的模型导入Unity中使用 但SW中建模为实体而Unity多为面
  • Java中创建对象时内存中的情况

    public class Phone public String brand public double price public String color public void call String name System out p
  • conda 国内源配置

    修改 condarc show channel urls true channels https mirrors tuna tsinghua edu cn anaconda cloud conda forge https mirrors t
  • Unity中的异步编程【1】—— Unity与async 、 await

    新手在Unity里写东西 一个方法的内容如果写复杂了 容易把Uinty写死 就会卡帧 用流行的话来总结就是 在Update里面活生生把天聊死了 此外 如果新手才入门 不擅长使用消息 事件来进行异步的统筹 一门心思在Update里面实现各种有
  • USB PHY

    USB PHY负责最底层的信号转换 作用类似于网口的PHY 有两种接口 一种是ULPI 一种是UTMI 前者PIN少 后者PIN多 所以如果用ULPI PHY一般外部另接 用UTMI PIN多 一般内置 PHY内置或者外置要看芯片资料 PO
  • 搭建区块链底层网络Fisco-Bcos+WeBase+Ubuntu(保姆级别)

    目录 一 前言 1 所需要准备的环境 Ubuntu20 04 2 具体虚拟机教程请参考手把手教会你安装Ubuntu虚拟机 保姆级教程 pjlpjlpjl的博客 CSDN博客 2 本文章主要讲解 3 所需文件 build chain sh c
  • 2022年数维杯数学建模C题 电动汽车充电站的部署优化策略求解全过程文档及程序

    2022年数维杯数学建模 C题 电动汽车充电站的部署优化策略 原题再现 近年来 随着化石能源的逐渐枯竭和环境污染的不断加剧 电动汽车 EV 作为传统燃油车的主要替代品之一 得到了快速的发展 据国际能源署统计 2019年全球电动私家车已达 7
  • 【Python时间复杂度和空间复杂度】

    时间复杂度和空间复杂度 1 测试运行时间示例 2 时间复杂度 2 1列表数据结构时间复杂度计算 2 2 字典数据结构时间复杂度计算 3 空间复杂度 4 参考链接 算法分析是基于每种算法使用的计算资源量来比较算法 我们比较两个算法 说一个比另
  • 解决阿里推送sdk 3.0以上初始化报“init cloudchannel failed -- errorcode:10212 -- errorMessage:静默连接进程未初始化”的问题

    解决方案如下 Override public void onCreate super onCreate 注意 这句要放到最前面执行 必须是 在 android process channel initCloudChannel this 我的
  • 顺序查找(C语言)

    include
  • 一道面试题就能测出你的JavaScript水平

    function Parent this a 1 this b 1 2 this a this c demo 5 this show function console log this a this b this c demo functi
  • 单片机通信数据延迟问题排查

    1 问题说明 笔者在最近的项目中 发现系统的响应延迟较高 经过排查 排除了单片机运行卡死的问题 2 原因分析 具体排查过程这里就不细致说明了 直接给出排查后原因 任务执行周期规划不合理 导致freertos队列发送接收到的命令有延迟 为了便