说明:本文翻译自Erich Styger的文章《Implementing FreeRTOS Performance Counters on ARM Cortex-M》,文章的权属属于原作者。

当使用像FreeRTOS这样的RTOS时,迟早要问一个问题:每个任务花费多少时间?基于Eclipse的MCUXpresso IDE具有很好的视图,准确显示了此类信息:

FreeRTOS运行时信息

为了使FreeRTOS(或“任务列表”视图)显示非常有用的信息,开发人员必须提供帮助,以便RTOS可以收集此信息。本文说明如何在ARM Cortex-M上完成此操作。

1、概述

不久前,我从处理器专家的角度讨论了FreeRTOS的性能和运行时分析中的该主题。这次是关于使用“本机” FreeRTOS和使用NXP MCUXpresso SDK,但是相同的原理将适用于Cortex-M处理器和微控制器的所有其他环境。至于FreeRTOS端口,我正在使用https://github.com/ErichStyger/McuOnEclipseLibrary中的端口,因为该端口已经存在所有需要的钩子。GitHub上提供了本文中使用的所有文件和源。

2、如何工作

操作系统使用计数器来衡量任务执行时间。因此,在任务上下文切换时间,此计数器用于确定该任务使用的时间。重要的一点是,该时间不是绝对的(例如37毫秒),而是一些“滴答声”(例如241个滴答声)。RTOS知道总体上使用了多少“滴答声”。RTOS知道系统中有多少个任务,因此它可以显示每个任务花费了总时间的百分比。另一个要注意的是,时间*包括*在中断中花费的时间。

这是一种非常简单但功能强大的估算任务执行时间的方法,通常就是您所需要的。它可以通过一种非常简单的方式来实现:使用一个使计数器递增的计时器和一个用于读取计数器值的函数。

要打开性能测量,我必须启用两个FreeRTOS配置设置:

#define configUSE_TRACE_FACILITY 1 /* 1: include additional structure members and functions to assist with execution visualization and tracing, 0: no runtime stats/trace */#define configGENERATE_RUN_TIME_STATS 1 /* 1: generate runtime statistics; 0: no runtime statistics */

要配置计时器并读取计数器,我必须使用两个宏来告诉函数名称:

#define configGET_RUNTIMER_COUNTER_VALUE_FROM_ISR   AppGetRuntimeCounterValueFromISR#define configCONFIGURE_TIMER_FOR_RUNTIME_STATS     AppConfigureTimerForRuntimeStats

3、使用滴答计数器

一种非常简单的衡量任务执行情况的方法是使用FreeRTOS滴答计数器本身。可以通过以下方式启用

#define configGENERATE_RUN_TIME_STATS_USE_TICKS     (1)

但是,这仅在任务执行时间超过RTOS滴答周期时才能测量任务执行时间。对于更快的任务,此方法没有用。根据Nyquist-Shannon采样定理,我最好使用2倍(更好:10倍)的测量频率。

4、使用Cortex-M周期计数器

实现该计数器的另一种方法是使用Cortex-M周期计数器,该计数器已在许多设备上实现,并给出了很好的结果。最好的是:无需中断或额外的计时器。可能的实现如下所示:

static uint32_t prevCycleCounter, cycleCntCounter = 0;void AppConfigureTimerForRuntimeStats(void) {cycleCntCounter = 0;McuArmTools_InitCycleCounter();prevCycleCounter = McuArmTools_GetCycleCounter();
}uint32_t AppGetRuntimeCounterValueFromISR(void) {uint32_t newCntr, diff;newCntr = McuArmTools_GetCycleCounter();diff = newCntr-prevCycleCounter;prevCycleCounter = newCntr;cycleCntCounter += diff>>12; /* scale down the counter */return cycleCntCounter;
}

5、使用定期定时器中断

标准方法是使用定期中断计时器,该计时器增加计数器。对于1 kHz滴答计时器,推荐的频率是FreeRTOS滴答计时器频率的10倍,在这种情况下为10 kHz(100 us):

static uint32_t perfCounter = 0;#define PIT_BASEADDR       PIT
#define PIT_SOURCE_CLOCK   CLOCK_GetFreq(kCLOCK_BusClk)
#define PIT_CHANNEL        kPIT_Chnl_0
#define PIT_HANDLER        PIT0_IRQHandler
#define PIT_IRQ_ID         PIT0_IRQnvoid PIT_HANDLER(void) {PIT_ClearStatusFlags(PIT_BASEADDR, PIT_CHANNEL, kPIT_TimerFlag);perfCounter++;__DSB();
}void AppConfigureTimerForRuntimeStats(void) {pit_config_t config;PIT_GetDefaultConfig(&config);config.enableRunInDebug = false;PIT_Init(PIT_BASEADDR, &config);PIT_SetTimerPeriod(PIT_BASEADDR, PIT_CHANNEL, USEC_TO_COUNT(100U, PIT_SOURCE_CLOCK));PIT_EnableInterrupts(PIT_BASEADDR, PIT_CHANNEL, kPIT_TimerInterruptEnable);NVIC_SetPriority(PIT_IRQ_ID, 0);EnableIRQ(PIT_IRQ_ID);PIT_StartTimer(PIT_BASEADDR, PIT_CHANNEL);
}uint32_t AppGetRuntimeCounterValueFromISR(void) {return perfCounter;
}

6、摘要

FreeRTOS包含一项功能,可以测量相对于系统中其他任务的任务执行时间。我需要提供的是计时器或某种计数器的初始化例程,以及获取计数器值的方法。如果您对检查FreeRTOS计时的其他方式感兴趣,请查看Percepio Tracealyzer或Segger SystemView。如果您希望应用程序本身显示性能数据,请查看“ 使用FreeRTOS进行性能和运行时分析”中介绍的Shell / Commandline实现。

7、链接

  • GitHub上的项目:https : //github.com/ErichStyger/mcuoneclipse/tree/master/Examples/MCUXpresso/tinyK22/tinyK22_FreeRTOS
  • FreeRTOS的性能和运行时分析
  • 在Eclipse中更好的FreeRTOS调试
  • ARM SWO性能计数器
  • GitHub上的McuLib:https : //github.com/ErichStyger/McuOnEclipseLibrary
  • MCUXpresso IDE和SDK:https ://mcuxpresso.nxp.com

欢迎关注:

在ARM Cortex-M上实现FreeRTOS性能计数器相关推荐

  1. ARM® Cortex®-M上的Trace跟踪方案

    ARM® Cortex®-M上的Trace跟踪方案 本文介绍Coresight™在Cortex®-M上的一些常用的Trace模块以及劳特巴赫TRACE32如何抓取并分析这些模块产生的Trace数据. ...

  2. MSP430 与 ARM Cortex系列在电池供电应用上的比较

    这是原文地址:http://www.embedded.com/electronics-blogs/industry-comment/4026838/TI-s-MSP430-vs-ST-Microele ...

  3. ARM Cortex-M3M4 处理器上的嵌入式系统编程

    ARM Cortex-M3/M4 处理器上的嵌入式系统编程 在基于 ARM Cortex M 处理器的微控制器上使用 C 编程和汇编进行动手编码 课程英文名:Embedded Systems Prog ...

  4. 【arduino】在Arduino上运行FreeRTOS操作系统,freeRTOS入门教程helloword

    关注.星标公众号,不错过精彩内容 编辑:Tony 来源:公众号TonyCode 我们从一开始接触Arduino编程就知道,Arduino程序结构由setup()和loop()两部分组成,我们需要反复执 ...

  5. ​ ARM Cortex系列那么多处理器,该怎么区分?

    关注.星标公众号,直达精彩内容 来源:嵌入式资讯精选 最近因为要为芯片选定核,所以就在了解哪些核合适且性价比好,这是一个需要结合产品各类技术.市场分析的活,看似简单却还是需要一些储备的,今天选了一篇A ...

  6. linux 返回非法指令,linux – ARM Cortex A7在内核模式下返回PMCCNTR = 0,在用户模式下返回非法指令(即使在PMUSERENR = 1之后)...

    我想在Raspberry Pi 2上读取循环计数寄存器(PMCCNTR),它有一个ARM Cortex A7内核.我为它编译了一个内核模块,如下所示: #include #include int in ...

  7. STM32MP157C-DK2->Develop on Arm® Cortex®-A7之 C语言开发uart例程

    编写C代码开启STM32MP157C-DK2开发板上的uart7的接收功能,并将收到的数据打印到控制台,并通过uart7发送出"uart"字符串. STM32MP157C-DK2的 ...

  8. 2021-07-13 ARM cortex三个版本A、R、M简单介绍

    ARM cortex三个版本A.R.M简单介绍 一.Cortex系列组合大体上分为三种类别.        1. Cortex-A 面向性能密集型系统的应用处理器内核 Application Proc ...

  9. 如何使用FT2232H适配器和开源调式工具OpenOCD对ARM Cortex M7系列MCU进行SWD接口调试

    该篇幅介绍如何使用FT2232H适配器和开源调式工具OpenOCD对ARM Cortex M系列MCU进行SWD接口调试? 如何连接FT2232HL Debuger Adapter和目标板的的SWD调 ...

最新文章

  1. 【Android 逆向】Android 逆向通用工具开发 ( Android 端远程命令工具 | Android 端可执行程序的 main 函数操作 | TCP 协议服务器建立 | 接收客户端数据 )
  2. python aes padding_使用PKCS7Padding在python和Node.js之间进行AES加密
  3. 发工资条软件如何使用?
  4. 【ZZULIOJ】1047: 对数表
  5. 保利威视云直播的python API
  6. Xmind 8 pro 软件破解版
  7. 指甲半月痕 血象和微量元素检查分析是否有贫血
  8. 3. lambda 方法引用
  9. appium startActivity使用方法
  10. 算法---斐波那契思想
  11. IDEA常用快捷键(四)--查找文件、查找类
  12. av_opt_set函数族详解
  13. vrchat新手教程_VRChat入门指南| 最新电脑资讯
  14. 哲理故事与管理之道 20 -用危机激励下属
  15. We Can't Subsidize The Banks Forever
  16. react 断网提示
  17. 计算机视觉:支持M:N匹配与活体检测的百度人脸Api调用典例
  18. QT-按下按钮实现页面跳转
  19. 芝加哥大学计算机专业排名,芝加哥大学计算机排名
  20. 利用SQL语句计算库存

热门文章

  1. #35 string(缩点+动态规划)
  2. ZeroMQ全面介绍
  3. 【数据采集】将16进制字符串转化为Double类型输出(依照IEEE754标准)
  4. iisapp 查看PID所对应的IIS应用程序池及详细介绍
  5. SQL的经典语句(太全了)
  6. synchronized与volatile
  7. 思科nat配置实例_Cisco ASA 5520(8.2.4)配置企业内网案例
  8. c++查找pair,使用map,unordered_map,vector
  9. equals null报错吗_轻轻松松教你搞定Java中的==和equals
  10. dir结构体 linux_Linux下DIR,dirent,stat等结构体详解