嵌入式软件调试:任务执行时间与负载率
嵌入式软件调试:任务执行时间与负载率
- 1 基本概念及原理
- 1.1 负载率概念
- 1.2 时间统计方式
- 1.3 任务占用统计方式
- 2 功能函数执行时间测试
- 2.1 绝对执行时
- 2.2 相对执行时间(任务负载率贡献)
- 2.3 中断对执行时间影响
- 3 执行周期测试
- 4 负载率测试
- 4.1 负载率计算方式
- 4.2 任务/函数负载率评估
在条件有限的情况下,如何采用通过现有的调试工具获取函数执行时间、任务执行周期以及负载率的测试等。
#在条件宽裕的情况下,购买第三方工具自然对于测试执行时间以及负载率等极为方便,建议采用此种方式
1 基本概念及原理
1.1 负载率概念
负载率 = 占用时间 /(占用时间 + 空闲时间)
#简单来说,就是工作时间占用总时间的比例,比如说你需要工作12小时,就可以说你负载率为50%。这可量化反映当前使用情况
从上面可以看出来计算负载率,需要解决两个问题:
1)、必须可量化得获取占用时间
2)、得存在可靠的计时方式
1.2 时间统计方式
时间统计要求准确,因此对于我们来说,比较合适的就是硬件定时器里面计数(如英飞凌中的STM、ATOM等)。
简单示例(以TC397为例):
1)、存在6核,每个核心存在各自定时器;
2)、建议和系统使用的定时器使用同一个;
3)、同时也可使用其他配置的定时器
#如下,调用时可采用此类方式,“Count = *AppLoad_Timer[Index]
”
const uint32 *AppLoad_Timer[APPLOAD_CORENUMBER] =
{(uint32 *)&STM0_TIM0.U, /*Core0定时寄存器相应地址*/(uint32 *)&STM1_TIM0.U,(uint32 *)&STM2_TIM0.U,(uint32 *)&STM3_TIM0.U,(uint32 *)&STM4_TIM0.U,(uint32 *)&STM5_TIM0.U
};
#建议直接从相关定时器计数的寄存器地址获取,切记不可使用软件定时器(其所在任务存在偏移的情况,因此会导致计时不准确)
1.3 任务占用统计方式
在任务执行过程中,会存在任务切换(中断打断任务等),因此直接在任务开始处与结束的位置来表示开始与结束会造成实际执行时间大于任务实际执行时间。
可以参考下“AutosarOS:错误处理、跟踪与调试(博文)”定义,在任务切换(上下文切换)时,可以进入PreTaskHook、PostTaskHook,因此在此Hook函数中进行处理,可以通过处理得到准确的Task执行时间。
简单示例:
1)、通过在"PostTaskHook"中获取时间计数,可知相应的退出任务的时间点
2)、类似于步骤1),通过在"PreTaskHook"中获取时间计数,可知相应的进入任务的时间点
3)、根据进入任务的时间点、退出任务的时间点,可以计算出任务的运行时间、被打断时间等
void AppLoad_PostTaskHook(void) /*此函数须在"PostTaskHook"中进行调用*/
{uint8 CoreId;uint16 TaskId;CoreId = AppLoad_GetCoreId(); /*获取当前运行此Hook函数的内核ID: 函数名经过封装(可自己查找相应的API)*/AppLoad_GetTaskId(&TaskId); /*获取退出的函数任务ID*/switch (CoreId){case COREID_CORE0:{/*此处可以获取相应任务的退出时间,用于计算运行时间*/}break;....../*可能存在多核的情况,可根据实际情况进行扩展*/default:break;}
}
2 功能函数执行时间测试
对于具体的功能执行时间存在以下几方面问题:
1)、无法找到进入或者退出时间点(中断对其时间测量不可忽视)
2)、需要评估执行时间相对于所在任务可用的时间片的占比(调度表形式调用极为重要,决定了会不会影响任务偏移以及偏移后会不会跳过执行等)
#以时间片形式进行处理时,需要保障该任务存在偏移在一定范围内(确保不会触发时间保护),因此也需要确保单个任务的负载率控制在一定范围
2.1 绝对执行时
绝对执行时间 = 执行结束时间 - 执行开始时间
该参数反映了该功能函数的绝对执行时间,可用于该函数在进行任务分配时的依据。
简单示例
结合"PreTaskHook"以及"PostTaskHook"说明通过Hook函数进行时间计算的过程:
1)、如图可知,可在"PreTaskHook"中获取进入任务时间点,可在"PostTaskHook"获取退出任务时间点
2)、因此需要知道该任务的执行时间只需要将图中绿色的双箭头部分时间计算出来即可
#注意定时器位数,溢出时需要特殊处理(切记计数时需要处理此类情况)
static void AppLoad_CalcPostUserTaskTime(uint8 CoreId, uint16 TaskId)/*需要传入内核ID(哪个定时器时间)、任务ID(是否是测试的任务触发)*/
{/*记录相应的任务退出时间节点*/
}
static void AppLoad_CalcPreUserTaskTime(uint8 CoreId, uint16 TaskId)/*需要传入内核ID(哪个定时器时间)、任务ID(是否是测试的任务触发)*/
{/*记录相应的任务退出时间节点*/
/*计算在任务中真实运行时间*/
}
#在进行比较小的执行时间计算时,建议禁用中断进行测试(此方式可以更准确判断出代码执行时间,避免其他方式带来的时间开销(任务切换等)),避免中断对测试结果影响
2.2 相对执行时间(任务负载率贡献)
相对执行时间 = 功能函数执行时间 / 任务时间片时间
相对执行时间反映了功能函数执行时间占用任务的可用时间比例,可作为任务执行时间优化的重要依据(以上针对的是调度表存在时间片的情况下),此处不做详细说明(此方式在本人接触的项目中未大量使用)
2.3 中断对执行时间影响
在测试过程中或者真实工况条件下,若直接获取相应函数进入与退出时时间记录,由于通信、ADC采集、定时器等可能产生的中断影响,函数/任务实际执行时间应大于真实执行时间。
函数执行时间 = 中断执行时间 + 函数真实执行时间
#因此为了正确准确评价函数执行时间可在执行过程中屏蔽中断“EnableAllInterrupts/ DisableAllInterrupts”,具体可参考AutosarOS:操作系统基本概念
3 执行周期测试
首先说下周期偏移带来的常见影响:
1)、窗狗喂狗超时或者过早,导致软件复位
2)、通信周期波动较大(如CAN的周期报文)
任务执行时间 = 本次任务执行时间时间计数 - 上次任务执行时间时间计数
简单代码示例:
void AppLoad_Get_Func_Cycle(uint8 AppLoad_Func_Index)
{/*1)、记录当前定时器值*/
/*2)、计算当前任务周期、平均值*/
/*3)、记录最大值、最小值*/
}
typedef struct
{uint32 Period_CycleCnt;/*用于计算平均值*/float Period_CurValue;/*记录实时周期,可反应周期变化细节及趋势等信息*/float Period_MinValue;/*记录最小值,可反应偏移量*/float Period_MaxValue;/*记录最大值,可反应偏移量*/float Period_AverValue;/*记录平均值*/uint64 Period_TotalValue;/*用于计算平均值*/
}st_AppLoad_UserFunc_PeriodDefine;
#须对周期比较敏感的任务进行周期测试,记录周期偏移最大值,评估周期偏移是否在可接受范围内以及是否会带来软件bug(如复位、报文超时、甚至某些逻辑未执行等等)
4 负载率测试
4.1 负载率计算方式
负载率 = 执行任务时间 / (执行任务时间 + 空闲时间)
此处与章节2.1类似,不过需要把计算的对象替换成"IdleTask",只要计算出该任务的执行时间,则可反过来计算出来中断以及其他任务的执行时间
#注意事项:
1)、可选择一段时间为计时周期,如2s或者更高(最好为周期任务最小公倍数的倍数)
2)、执行时间为此段时间内所有任务执行时间的总和
4.2 任务/函数负载率评估
函数负载率贡献 = 函数执行时间 / 函数执行周期
此概念类似于CAN总线上报文负载率,比如10ms(其他周期一样)的标准报文,在知道波特率的情况下,它对于总线负载率的增加是一定的。因此知道每个任务对于负载率的贡献,它们之和就为整体负载率
void AppLoad_CalculateUserTask(void)
{/*通过章节2.1得到的时间,以及相应的任务周期即可计算任务负载率*/
}
#注意事项:
1)、负载率为所有函数负载率贡献之和
2)、注意在函数中存在函数周期倍数的执行方式,周期不应以函数为其为准,应该以里面调用的函数的最大周期作为该函数的周期
之前写的文档丢了,这次凭印象只写了大概,大家见谅。后续想起来了再进行补充,有时间把相关的代码也可以进行补充下
嵌入式软件调试:任务执行时间与负载率相关推荐
- 10kv线路负载率计算_电工必懂计算公式,你若不会,如何立足于电力行业?
一电力变压器额定视在功率Sn=200KVA,空载损耗Po=0.4KW,额定电流时的短路损耗PK=2.2KW,测得该变压器输出有功功率P2=140KW时,二次则功率因数2=0.8.求变压器此时的负载率b ...
- can总线报文是固定的吗_CAN总线负载率的计算方式
今天这篇文章主要是介绍当前汽车中使用的总线的类型及负载率的计算方式,用于汽车电子工程师学习及应用在日常工作中:当前汽车中常见总线类型是CAN,CAN FD, FlexRay及LIN总线:今天我们先介绍 ...
- CAN测量模块总线负载率,你关注了吗?
一 背景 随着新能源汽车的飞速发展,整车系统日趋复杂,整车性能的可靠性也越来越重要.在车辆测试过程中,为应对更加多样的试验需求,传感器的种类和数量会随着测量种类而增加,由此数据量变得越发庞大,使得海量 ...
- 用虹科Pico汽车示波器计算CAN总线负载率
CAN总线负载率是指CAN总线上单位时间内实际传送的位数和可以传送的位数之比,也就是总线实际数据传输速率与理论上能达到的数据传输速率的比值.例如波特率为500kbps的CAN总线理论上每秒钟能够传输5 ...
- 网络带宽负载率怎么计算
网络带宽负载率是衡量网络利用率的重要指标,它可以用以下公式计算: 带宽负载率 = (实际使用带宽 / 总带宽) * 100% 其中,实际使用带宽是指在某一时刻,网络传输的数据量:总带宽是指网络的理论最 ...
- 分享嵌入式软件调试方法和几个工具
关注+星标公众号,不错过精彩内容 作者 | 杂烩君 转自 | 嵌入式大杂烩 我们常常说,软件三分写七分调.实际开发中,确实也是这样子的.我工作这几年了,对这体会也越来越深.每当需求一下来,我代码很快就 ...
- 嵌入式软件调试技术 读书笔记
第一章 软件调试概述 第二章 边界扫描测试技术 (JTAG) 第三章 学习使用GDB调试器 第四章 GDB远程调试技术 第五章 网络应用程序调试 第六章 多进程与多线程调试 第七章 静态库与动态库的调 ...
- 【软考学习5】流水线基本概念、周期执行时间、吞吐率、加速比和效率的计算
一.流水线基本概念 在学习流水线之前,必须掌握 并行 的概念,即明白什么是 并行. 其中,并行和我们常说的并发是不同的,需要理解这两个概念. 并行指的是:两个或两个以上的事件在同一时刻发生. 并发指的 ...
- 嵌入式软件调试之软件断点
关注.星标公众号,直达精彩内容 来源:CSDN | maomao171314 整理:技术让梦想更伟大 | 李肖遥 软件断点 INT 3 指令,即通常所说的"软件断点",一条X86系 ...
最新文章
- 《数据竞赛白皮书》发布:竞赛核心价值及促进人才数字化转型
- scss安装_安装了这9个免费PS插件后,终于能正常时间下班了……
- PyQt5 技术篇-QTableWidget表格组件指定行的隐藏与显示控制实例演示,设置表格指定列的列宽方法
- 《Python核心编程》第二版第36页第二章练习 -Python核心编程答案-自己做的-
- Python入门--元组的创建,(),tuple()
- Python代码加密-PyArmor
- (转载)220v交流接触器自锁接线图另接热继电器
- Oracle、mysql产品性能优化总结
- macbook linux 双系统,MAC Ubuntu双系统方案
- iTechTag:声望创造价值
- 【UOJ#311】【UNR #2】积劳成疾(动态规划)
- 【算法上车③】华为摄像头rpm签名校验并安装调试
- 浅谈欧拉定理及其扩展
- 【Flask】 Not Found: /favicon.ico 项目logo图标加载
- mysql 编程 备份_mysql 容灾备份
- AI量化(代码):深度强化学习DRL应用于金融量化
- Apache URL重定向指南
- CSS 单行/多行文本溢出显示省略号(...)的实现
- 全面解决win10 磁盘占用率100%问题
- 旋风解析磁力php,梦见旋风磁力好不好?