zoukankan      html  css  js  c++  java
  • 在ARM Cortex-M上实现FreeRTOS性能计数器

      说明:本文翻译自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配置设置:

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

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

    1 #define configGET_RUNTIMER_COUNTER_VALUE_FROM_ISR   AppGetRuntimeCounterValueFromISR
    2 
    3 #define configCONFIGURE_TIMER_FOR_RUNTIME_STATS     AppConfigureTimerForRuntimeStats

    3、使用“滴答”计数器

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

    1 #define configGENERATE_RUN_TIME_STATS_USE_TICKS     (1)

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

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

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

     1 static uint32_t prevCycleCounter, cycleCntCounter = 0;
     2  
     3 void AppConfigureTimerForRuntimeStats(void) {
     4   cycleCntCounter = 0;
     5   McuArmTools_InitCycleCounter();
     6   prevCycleCounter = McuArmTools_GetCycleCounter();
     7 }
     8  
     9 uint32_t AppGetRuntimeCounterValueFromISR(void) {
    10   uint32_t newCntr, diff;
    11  
    12   newCntr = McuArmTools_GetCycleCounter();
    13   diff = newCntr-prevCycleCounter;
    14   prevCycleCounter = newCntr;
    15   cycleCntCounter += diff>>12; /* scale down the counter */
    16   return cycleCntCounter;
    17 }

    5、使用定期定时器中断

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

     1 static uint32_t perfCounter = 0;
     2  
     3 #define PIT_BASEADDR       PIT
     4 #define PIT_SOURCE_CLOCK   CLOCK_GetFreq(kCLOCK_BusClk)
     5 #define PIT_CHANNEL        kPIT_Chnl_0
     6 #define PIT_HANDLER        PIT0_IRQHandler
     7 #define PIT_IRQ_ID         PIT0_IRQn
     8  
     9 void PIT_HANDLER(void) {
    10   PIT_ClearStatusFlags(PIT_BASEADDR, PIT_CHANNEL, kPIT_TimerFlag);
    11   perfCounter++;
    12   __DSB();
    13 }
    14  
    15 void AppConfigureTimerForRuntimeStats(void) {
    16   pit_config_t config;
    17  
    18   PIT_GetDefaultConfig(&config);
    19   config.enableRunInDebug = false;
    20   PIT_Init(PIT_BASEADDR, &config);
    21   PIT_SetTimerPeriod(PIT_BASEADDR, PIT_CHANNEL, USEC_TO_COUNT(100U, PIT_SOURCE_CLOCK));
    22   PIT_EnableInterrupts(PIT_BASEADDR, PIT_CHANNEL, kPIT_TimerInterruptEnable);
    23   NVIC_SetPriority(PIT_IRQ_ID, 0);
    24   EnableIRQ(PIT_IRQ_ID);
    25   PIT_StartTimer(PIT_BASEADDR, PIT_CHANNEL);
    26 }
    27  
    28 uint32_t AppGetRuntimeCounterValueFromISR(void) {
    29   return perfCounter;
    30 }

    6、摘要

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

    7、链接

    欢迎关注:

  • 相关阅读:
    eclipse如何导入项目
    CBC和CTR解密模式——C++实现
    安装java之后没有jre目录
    对称密钥解密——C++方法
    使用Eclipse时一些报错
    C/C++文件I/O操作
    获取string的长度
    新建ftp快捷方式
    一些IT书籍
    C语言获得数组长度的函数
  • 原文地址:https://www.cnblogs.com/foxclever/p/12151472.html
Copyright © 2011-2022 走看看