查看: 323|回复: 0

[原创] 【LPC860-max板卡试用】基于rt-thread perf_counter软件包的使用

[复制链接]
  • TA的每日心情
    无聊
    7 小时前
  • 签到天数: 598 天

    [LV.9]以坛为家II

    51

    主题

    2232

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    7113
    最后登录
    2024-5-6
    发表于 2024-1-24 12:45:24 | 显示全部楼层 |阅读模式
    本帖最后由 andeyqi 于 2024-1-24 12:45 编辑

    RT-thread 的在线软件包里支持perf_counter,对该工具的具体描述可以从此链接获取(perf_counter),也可以从github介绍了解perf_counter(https://github.com/GorgonMeducer/perf_counter.git),perf_counter 是基于cortex-m 架构的systick,扩展出延时相关的能力,可以获取某段代码前后的时间差来用于某段代码性能测试,该功能在系统性能优化时会有很大作用。

    • 添加perf_counter 软件包
    我们之前已经基于lpc860 适配了 RT-thread 系统(【LPC860-max板卡试用】rt-thread 最小系统适配) ,在此基础上添加perf_counter 软件包,我们基于以下操作既可把软件包加入到IAR 工程中了。
    20240121-231237.gif


    按照上述的操作我们就已经把perf_counter 软件包加载到 IAR 工程使用了,添加好perf_counter 代码后我们来验证下perf_counter 功能。

    • delay ms 延时接口试验
    添加如下测试代码验证delay_ms函数,示波器抓取GPIO 脉冲宽度,ms 延时精度还是可以的。
    1. #include <stdio.h>
    2. #include <rtthread.h>
    3. #include <rtdevice.h>
    4. #include <board.h>
    5. #include <drivers/pin.h>

    6. int perf_test(int argc, char **argv)
    7. {
    8.     int cmd = 0;
    9.     int data = 0;
    10.    
    11.     rt_base_t pin = rt_pin_get("P1.12");
    12.     rt_pin_mode(pin,PIN_MODE_OUTPUT);   
    13.    
    14.     if(argc == 1 )
    15.         return 0;

    16.     cmd = atoi(argv[1]);
    17.     switch(cmd)
    18.     {
    19.     case 0:
    20.         rt_pin_write(pin,1);
    21.         delay_ms(10);
    22.         rt_pin_write(pin,0);
    23.         delay_ms(10);
    24.         rt_pin_write(pin,1);
    25.         delay_ms(1);
    26.         rt_pin_write(pin,0);
    27.         delay_ms(1);
    28.         rt_pin_write(pin,1);
    29.         delay_ms(1);
    30.         rt_pin_write(pin,0);
    31.       break;
    32.     return 0;
    33. }
    34. MSH_CMD_EXPORT_ALIAS(perf_test, perf, perf test command.);
    复制代码
    10ms 的delay 波形:
    10ms.jpg

    1ms 的delay 测试波形:
    1ms.jpg

    • Cpu cycle 测试
    上述的示波器抓取10ms delay 接口发现ms级别的精度还是可以的,perf counter 还提供了基于CPU cycle 的性能计算的功能,在10ms delay 接口前后计算cpu cycle 打印测试,对应测试代码如下,因为stop_cycle_counter 返回值时int64,RT-thread 打印64bit 数据要打开此宏定义(RT_KPRINTF_USING_LONGLONG):
    1.         start_cycle_counter();
    2.         delay_ms(10);
    3.         counter = stop_cycle_counter();
    4.         rt_kprintf("10ms cpu counter %llu\n",counter);
    复制代码
    执行结果如下:
    微信截图_20240124120500.png


    对应的CPU cycle 为480075 我们的代码CPU 频率配置的为48M,计算对应的时间为480075*(1000/48000000)ms = 10.001ms 和示波器抓取的波形时间是吻合的,我们可以基于此方法验证某段代码的执行时间,用于评估性能指标的需求。

    • delay us 延时接口试验
    除了上述的delay ms 的接口,还提供了us 秒级别的测试,因为本的时钟频率为48M,us的接口相对有误差需要修改这个对应误差补偿的定义,PERF_CNT_DELAY_US_COMPENSATION,以下是本地测试波形。

    delay 50us:
    50us.jpg

    delay 5us:
    5us.jpg

    从波形上看是又8us的误差,这个已通过修改上面PERF_CNT_DELAY_US_COMPENSATION 宏定义补偿掉这个误差,理论上10us以上的延时都是可以被补偿掉

    • PS 输出栈最大使用深度问题修改
    加入perf_counter 软件包后,会发现ps命令打印的栈深度会很大接近100%,输出如下:

    ps.png
    这时因为perf 保存任务统计信息的时候使用了任务栈的末端地址,ps 计算栈深度的时候是从最末端开始查找水印字符‘#’,因为最末端的字符已经被使用所以输出的栈深度会变得很大,list_thread 函数我们做如下修改跳过对应的管理结构体:
    ps_modify.png


    修改后输入ps 命令输出的信息恢复正常了.

    ps_1.png



    该会员没有填写今日想说内容.
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-5-6 21:35 , Processed in 0.110202 second(s), 20 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表