
Debug手段:使用I/O测量代码执行时间
嵌入式开发中,Debug是我们工程师解决Bug的必备技能,每个人都有自己擅长的调试方法和习惯,没有优劣之分,能解决问题就是最好的方法。本文和大家聊聊如何使用I/O( Input/Output port)测量代码执行时间。为什么要讨论这个主题呢?工程中,大家是否遇到如下一些场景:
场景一:网络唤醒,第一帧报文的外发时间超过需求时间(eg:100ms),这种场景,就需要定位启动代码中,哪些函数执行的时间过长,进而优化;
场景二:确认Bootloader程序进入Application程序消耗的时间有多少;
......
如上两个时间的测试,定位消耗时间的位置是关键点。对于场景一,STM(System Timer)/GTM(Generic Timer Module)也可以,但是,需要确保STM/GTM优先于其他模块完成初始化,否则,使用STM/GTM则无法有效测量代码的执行时间;对于场景二,程序由Bootloader进入Application,STM需要重新初始化,无法有效的测量代码在Bootloader执行时间。此时,使用I/O+示波器测量就是一种不错的选择。就我个人而言,我很喜欢这种方式。
1、I/O测量代码执行时间原理
适用I/O测量代码执行时间的原理如下所示:
首先,需要完成时钟的初始化。
其次,需要完成使用Pin #n脚本的配置工作,eg:Pin需要配置为输出模式。
再次,开始测量,具体测量步骤如下:
1. 测量之前,记录Pin #n的初始状态,eg:设置为低电平;
2. 在被动代码之前反转Pin #n电平,eg:高电平,同时记录测量起始时间T0;
3. 在被动代码之后反转Pin #n电平,eg:低电平,同时记录测量结束时间T1;
4. 通过T1 - T0即可算出被测代码的执行时间▲T。
2、端口设置
使用示波器测量时间,一般是通过测量输出Pin脚的边沿变化计算代码执行时间。所以,PORTn_PINm应设为输出模式,改变输出Pin脚的高低电平即可。
(一)对目标端口进行输出设置
本例,将Port 23的Pin 0设置为推挽输出,如下所示:
IfxPort_setPinModeOutput(&MODULE_P23, OPT_PIN_NUM, IfxPort_Mode_outputPushPullGeneral, IfxPort_OutputIdx_general);
3、代码执行时间测试示例
如下所示:在5ms的中断函数中反转Port23 Pin0的电平。
void STM_5ms_ISR(void)
{
/* Configure STM to generate an interrupt in 1 ms */
IfxStm_increaseCompare(&MODULE_STM0, IfxStm_Comparator_0, IFX_CFG_STM_TICKS_PER_MS);
if(Timer5ms == 5)
{
IfxPort_togglePin(&MODULE_P23, OPT_PIN_NUM);
Timer5ms = 0;
}
}
示波器采样结果如下所示:
如上图,可以看出I/O两次反转,测出代码运行时间为5ms,可以调整示波器的放大比例(本文放到到200us/div),更精确的知道代码运行时间。工程中,我们碰到耗时的量级多数是ms级,而示波器的采样精度一般都达到ns级别,测量精度足够。因此,可以通过这种方式精确的知道代码运行时间。
文章转载自公众号:开心果 Need Car
