历史上的今天
返回首页

历史上的今天

今天是:2024年12月15日(星期日)

2018年12月15日 | STM32CubeMX中FreeRTOS系统CPU使用率监测测试

2018-12-15 来源:eefocus

1.测试描述:


使用STM32CubeMX自动配置的工程,对其提供的FreeRTOS系统的CPU使用率进行监测,并通过串口打印。


2.测试环境:


(1)软件环境:STM32CubeMX-4.22.0,IAR-7.5,串口调试工具 
(2)硬件环境:原子战舰V3开发板


3.测试准备:


(1)STM32CubeMX软件主要配置:


管脚和其他外设的配置直接省略了,具体的可查看源码文件里的ioc文件。下面贴出主要的系统方面配置图: 

首先是Configuration界面,从图中可以看出测试工程使用的东西并不多;


这里写图片描述


点击中间层的FREERTOS进入系统配置界面,主要注意下图中红色标注的部分;


这里写图片描述


下图对一些系统的函数进行使能和失能操作,由于测试工程里有用到vTaskDelayUntil函数,所以对其使能。


这里写图片描述


(2)IAR软件配置:


首先从stm32官网下载的固件包里找到如下文件: 

这里写图片描述 

细心的人会发现这个是在F7的固件包里找的,当然F1的固件包里也可以找到,所以此方式也适用于其他支持FreeRTOS的stm32芯片。 

将两个文件复制到测试工程文件夹内,对应地址如下图(地址在后面添加头文件时有用,可实际根据自身情况拖放): 


这里写图片描述


在工程里添加cpu_utils.c文件


这里写图片描述


在工程配置选项里添加cpu_utils.h文件路径,这里我用的是相对路径,如果换别的电脑上时使用只需要重新ReBuild一下工程就好了。


这里写图片描述


在cpu_utils.h里添加使用到的两个头文件:


这里写图片描述


最后在FreeRTOSConfig.h文件的用户代码区添加如下两段代码。这一步很重要,如果没有,那么监测到的使用率一直为100%。


这里写图片描述


4.测试代码:


  • /* Includes ------------------------------------------------------------------*/

  • #include "FreeRTOS.h"

  • #include "task.h"

  • #include "cmsis_os.h"

  •  

  • /* USER CODE BEGIN Includes */     

  • #include "gpio.h"

  • #include "string.h"

  • #include "usart.h"

  • #include "cpu_utils.h"

  • /* USER CODE END Includes */

  •  

  • /* Variables -----------------------------------------------------------------*/

  • osThreadId defaultTaskHandle;

  •  

  • /* USER CODE BEGIN Variables */

  •  

  • #define START_TASK_PRIO           1

  • #define START_STK_SIZE            64

  • TaskHandle_t xHandleTaskStart;

  • void StartTask(void const * argument);

  •  

  • #define LED1_TASK_PRIO            5

  • #define LED1_STK_SIZE             128

  • TaskHandle_t xHandleTaskLED1;

  • void TaskLED1(void const * argument);

  •  

  • #define LED2_TASK_PRIO            6

  • #define LED2_STK_SIZE             128

  • TaskHandle_t xHandleTaskLED2;

  • void TaskLED2(void const * argument);

  •  

  • void MX_FREERTOS_Init(void) {

  • //系统自建的任务,不去动它,屏蔽了也没关系。

  •   osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);

  •   defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

  •  

  •   /* USER CODE BEGIN RTOS_QUEUES */

  •   /* add queues, ... */

  •   //创建开始任务

  •   xTaskCreate((TaskFunction_t )StartTask,

  •         (const char *  )"Start Task",

  •         (uint16_t       )START_STK_SIZE,

  •         (void *         )NULL,

  •         (UBaseType_t    )START_TASK_PRIO,

  •         (TaskHandle_t * )&xHandleTaskStart);       

  •   /* USER CODE END RTOS_QUEUES */

  • }

  •  

  • //开始任务,用于创建两个新的测试任务

  • void StartTask(void const * argument)

  • {

  •   taskENTER_CRITICAL();

  •   xTaskCreate((TaskFunction_t )TaskLED1,

  •               (const char *  )"LED1 Task",

  •               (uint16_t       )LED1_STK_SIZE,

  •               (void *         )str1,

  •               (UBaseType_t    )LED1_TASK_PRIO,

  •               (TaskHandle_t * )&xHandleTaskLED1);

  •  

  •   xTaskCreate((TaskFunction_t )TaskLED2,

  •               (const char *  )"LED2 Task",

  •               (uint16_t       )LED2_STK_SIZE,

  •               (void *         )str2,

  •               (UBaseType_t    )LED2_TASK_PRIO,

  •               (TaskHandle_t * )&xHandleTaskLED2);

  •  

  •   vTaskDelete(xHandleTaskStart);

  •   taskEXIT_CRITICAL();

  • }

  •  

  • //LED1任务

  • void TaskLED1(void const * argument)

  • {

  •   char str1[] = "TASK LED1 is Running!\r\n";

  •   portTickType xLastWakeTime;

  •   static uint16_t usage = 0;

  •   uint32_t num  = 0;

  •   char buffer[100];

  •   //延时时间单元初始值记录

  •   xLastWakeTime = xTaskGetTickCount();

  •   while(1)

  •   {

  •     //串口1发送提示字符串

  •     HAL_UART_Transmit(&huart1,(uint8_t *)str1,strlen(str1),0xFFFF);

  •     while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)!=SET);

  •  

  •     //获取CPU使用率并串口打印

  •     usage = osGetCPUUsage();

  •     num = sprintf(buffer,"1---CPU 使用率为:%d%%\r\n",usage);

  •  

  •     HAL_UART_Transmit(&huart1,(uint8_t *)buffer,num,0xFFFF);

  •     while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)!=SET);

  •  

  •     //LED闪烁

  •     HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);

  •     vTaskDelayUntil(&xLastWakeTime,(1000/portTICK_RATE_MS));

  •   }

  • }

  •  

  • //LED2任务

  • void TaskLED2(void const * argument)

  • {

  •   char str2[] = "TASK LED2 is Running!\r\n";

  •   portTickType xLastWakeTime;

  •  

  •   static  uint16_t usage = 0;

  •   uint32_t num  = 0;

  •   char buffer[100];

  •  

  •   //延时时间单元初始值记录

  •   xLastWakeTime = xTaskGetTickCount();

  •   while(1)

  •   {

  •     //串口1发送提示字符串

  •     HAL_UART_Transmit(&huart1,(uint8_t *)str2,strlen(str2),0xFFFF);

  •     while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)!=SET);

  •  

  •     //获取CPU使用率并串口打印

  •     usage = osGetCPUUsage();

  •     num = sprintf(buffer,"2---CPU 使用率为:%d%%\r\n",usage);

  •  

  •     HAL_UART_Transmit(&huart1,(uint8_t *)buffer,num,0xFFFF);

  •     while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)!=SET);

  •  

  •     //LED闪烁

  •     HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET);

  •     vTaskDelayUntil(&xLastWakeTime,(300/portTICK_RATE_MS));

  •     HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);

  •     vTaskDelayUntil(&xLastWakeTime,(1200/portTICK_RATE_MS));

  •   }

  • }

  • /* USER CODE END Application */


5.测试源码分析:


在嵌入式系统中,如果当前没有任何计划的任务运行,则系统会自动切换到空闲任务当中去。当一个系统中空闲任务占用一段时间的比值越大,对应硬件CPU对于工程所留的计算余量也就越大,则这个系统的CPU使用率越低。 
实际算法可简化为以下公式:


系统使用率 = 1 - 空闲任务占用时间/总测算时间


下图中箭头指向的位置是CPU使用率计算的算法核心,它是在Tick中断发生1000次时进行一次计算处理。也就是总测算时间为1000个心跳时钟。其中计算部分对原公式右边乘上了100倍,实际计算出来的osCPU_Usage为百分数。


这里写图片描述


以下两个函数是在FreeRTOSConfig.h宏定义中提到的函数,红色数字标注的是要重点关注的地方。这两个函数就是用来测算进入空闲函数的时间。


这里写图片描述


以上两个函数通过宏定义的方式,实际调用在系统任务切换函数里。也就是在这两个位置进行处理,进而得到需要的空闲任务占用时间。


这里写图片描述


6.测试结果:


在IAR的Live Watch窗口监测的系统使用率的值、系统心跳时基和空闲任务总占用时间。


这里写图片描述


下面是串口的输出,看出系统在刚开始时使用率有一段波动,后面趋于平稳,一直处于1%。


这里写图片描述


推荐阅读

史海拾趣

Electromagnetic Industries Llp公司的发展小趣事

在技术创新的同时,EMI公司也注重市场拓展。公司根据市场需求和产品特点,制定了有针对性的营销策略。一方面,公司积极参加国内外各种电子展会和论坛,展示产品和技术实力;另一方面,公司加强与客户的沟通和合作,深入了解客户需求,提供个性化的解决方案。通过这些努力,EMI公司的市场份额不断扩大,品牌影响力也逐渐提升。

BESTECH公司的发展小趣事

在技术创新的同时,EMI公司也注重市场拓展。公司根据市场需求和产品特点,制定了有针对性的营销策略。一方面,公司积极参加国内外各种电子展会和论坛,展示产品和技术实力;另一方面,公司加强与客户的沟通和合作,深入了解客户需求,提供个性化的解决方案。通过这些努力,EMI公司的市场份额不断扩大,品牌影响力也逐渐提升。

Green Power Solutions公司的发展小趣事
将新的电子管按照原位置和方向安装好,并确保连接牢固可靠。
CDIL[Continental Device India Pvt. Ltd.]公司的发展小趣事

自1964年起,CDIL便踏上了半导体制造的先驱之路。当时,电子产业正处于蓬勃发展的初期,CDIL凭借对技术的敏锐洞察和不懈追求,迅速成为印度乃至全球半导体制造领域的佼佼者。其硅芯片和器件的制造质量和技术水平均达到了世界级标准,为印度电子产业的发展奠定了坚实基础。

Fractus公司的发展小趣事

面对不断变化的市场需求和技术挑战,Fractus始终保持着对研发的重视和投入。公司拥有一支经验丰富的研发团队,致力于在天线技术领域进行持续的创新和探索。近年来,Fractus在微型化、多波段和智能天线技术方面取得了显著进展,并推出了多款具有自主知识产权的创新产品。展望未来,Fractus将继续秉承创新精神,推动天线技术的不断发展,为电子行业的进步贡献更多力量。

CT [ Central Technologies ]公司的发展小趣事

随着国内市场的饱和,CT公司开始将目光投向国际市场。公司制定了一系列国际化发展战略,包括在海外设立研发中心、拓展销售渠道以及与国际知名企业建立战略合作关系等。通过这些举措,CT公司的产品和服务逐渐渗透到全球范围内,公司的国际影响力不断增强。

问答坊 | AI 解惑

PCB设计中可能遇到的问题及解答

问题: Query:在从原理图更新到PCB的时候,如何保持原有器件的布局? 在Protel中,通常都会遇到需要修改原理图时,如何保持原有PCB板中器件的布局的问题。下面讲述一种有效的方式就是在PCB编辑窗口中使用菜单命令Project » Component Links来完成 ...…

查看全部问答>

创建Windows CE操作系统(二)

之前介绍过如何创建一个基本的Windows CE的平台,现在咱就上一次没有提到的部分进行一下补充定制并build OS。 首先,在VS2005 IDE中的View -> Other Windows -> Catalog Items中,添加或者删除相应的模块来完成OS定制,选项如下: 然后配置buil ...…

查看全部问答>

模拟乘法器(checked)

本帖最后由 辛昕 于 2018-4-8 22:59 编辑 关于这个东西,我后来其实从来没捡起过。 但是,也就没有必要惦记着了。 当然了,每次说到这个东西,都会想起,故人已去~ 在做运放的过程中,知道了一个叫做模拟乘法器的东西。 但是想上网看看这个东 ...…

查看全部问答>

calibrate_delay 的头文件是什么

嵌入式开发,Linux系统,是可以在驱动里面调用calibrate_delay 这个函数的吧 不知道需要包含什么头文件…

查看全部问答>

我的移动硬盘使用时,怎么显示:"本地磁盘"啊?

求救:     我的移动硬盘使用时,怎么显示:\"本地磁盘\"啊?     而且打不开! 谁知道 怎么解决? 谢谢!!!…

查看全部问答>

Windows CE 5.0的ARMV4I补丁求种

Windows CE 5.0的ARMV4I补丁,名称如下:    WinCEPB50-051231-Product-Update-Rollup-Armv4I.msi    WinCEPB50-060131-2006M01-Armv4I.msi    WinCEPB50-060228-2006M02-Armv4I.msi    WinCEPB50-06 ...…

查看全部问答>

wince下的CMMB播放程序

谁有这样的程序,急求,可以和我联系. email:gcgaoxj@yahoo.com [ 本帖最后由 dreaming123 于 2011-3-16 21:42 编辑 ]…

查看全部问答>

刚刚看到可以用:用社区芯币兑换51开发板PCB板!

刚刚看到可以用:用社区芯币兑换51开发板PCB板!早知道在这里换了,自己花了150快大洋买了一个 能不能用社区芯币兑换ARM的开发板呢…

查看全部问答>

microblaze的一些问题探讨下

请问有没有建立工程的教程,我按照官方网站的教程建立,(用的是ise13.1), 各种无奈啊,遇到的问题: 1、头文件的处理,我把用到的头文件拷到板级包的include文件夹,开始时可以,但是后面工程关闭,又出现 没找到头文件,那不是又得拷贝一次, ...…

查看全部问答>

【信号处理】一种雷达通用信号处理系统的实现与应用

摘要:鉴于FPGA和DSP各自的优势,FPGA+DSP信号处理架构,已成为信号处理系统的常用结构。但目前此结构处理平台功能固定、通用性差,或对平台的介绍缺乏具体实现。文中针对以上两点提出一种通用信号处理系统。该系统不仅将两种处理器的优点集于一身 ...…

查看全部问答>