STM32 HAL CPU Monitor 查询CPU使用率 查询CPU温度

阚砚文
2023-12-01

一、CPU负载计算的实用程序

平均负载表示了对CPU 资源的需求,通过汇总正在运行的线程数(使用率)和正在排队等待运行的线程数(饱和度)计算得出。计算平均负载的一个新方法是把使用率加上线程调度器延时得出,而不是去取样队列长度,从而提高精度。

这个值的意义为,平均负载大于CPU 数量表示CPU 不足以服务线程,有些线程在等待。如果平均负载小于CPU 数量,这(很可能)代表还有一些余量,线程可以在它们想要的时候在CPU 上运行。

平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。

可运行状态的进程:是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。
不可中断状态的进程:是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的 I/O 响应,也就是我们在 ps 命令中看到的 D 状态(Uninterruptible Sleep,也称为 Disk Sleep)的进程。

(1)【查询CPU使用率】 要使用此功能,应遵循以下步骤:

  1. STM32CubeMX软件中找到FREERTOS。选择Config parameters项,找到[USE_IDLE_HOOK][USE_TICK_HOOK]并使能。
    选择Include parameters项,找到[vTaskDelayUntil]并使能。

  2. 在FreeOS_Config.h中定义以下宏定义: 注意!!!是在用户代码区定义,否则会被清除。!!!

示例代码

#define traceTASK_SWITCHED_IN() extern void StartIdleMonitor(void);StartIdleMonitor()
#define traceTASK_SWITCHED_OUT() extern void EndIdleMonitor(void);EndIdleMonitor()
  1. [获取CPU使用率] usage = osGetCPUUsage();

二、【查询CPU温度】 要使用此功能,应遵循以下步骤:

  1. STM32CubeMX软件中找到ADCX(可能是ADC1/ADC2等等),在Mode项,找到Temperature Sensor Channel(温度传感器),并勾选。
    选择Parameter Settings项,ADC_Settings–>Continuous Conversion Mode(连续转换模式),使能连续转换。
    选择Parameter Settings项,Rank–>Sampling Time,设置为[239.5 Cycles],如果有更大,选更大。
    选择Parameter Settings项,ADC Injected Conversion Mode–>Injected Conversion Mode(连续转换模式),选择Auto Injected Mode(自动采集模式)
    选择DMA Settings项,Mode设置为Cirular(循环模式),Data Width设置为Word。

  2. 通过这个[CPU_TEMP_EN]宏定义来控制,查询CPU温度的代码是否编译。

  3. [使用方法]:用于存储采集到CPU温度的两个变量本文件已定义,使用时,加入 #include “cpu_utils.h” 即可。
    HAL_ADC_Start_DMA(&hadc1, &CPU_Temp_AD, 1); //在RTOS任务的循环外调用该采集函数
    CPU_TEMP = osGetCPUTemp(&hadc1);//得到真正温度,需要读取温度时调用

示例代码:

/**
  ******************************************************************************
  * @file    cpu_utils.c
  * @author  MCD Application Team
  * @version V1.1.0
  * @date    20-November-2014
  * @brief   Utilities for CPU Load calculation
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */

/********************** NOTES **********************************************
一、【查询CPU使用率】 要使用此功能,应遵循以下步骤:
1、STM32CubeMX软件中找到FREERTOS。选择Config parameters项,找到[USE_IDLE_HOOK][USE_TICK_HOOK]并使能。
                                  选择Include parameters项,找到[vTaskDelayUntil]并使能。
2、在FreeOS_Config.h中定义以下宏定义:  注意!!!是在用户代码区定义,否则会被清除。!!!
#define traceTASK_SWITCHED_IN() extern void StartIdleMonitor(void);StartIdleMonitor()
#define traceTASK_SWITCHED_OUT() extern void EndIdleMonitor(void);EndIdleMonitor()
3、[获取CPU使用率]  usage = osGetCPUUsage();


二、【查询CPU温度】 要使用此功能,应遵循以下步骤:
1、STM32CubeMX软件中找到ADCX(可能是ADC1/ADC2等等),在Mode项,找到Temperature Sensor Channel(温度传感器),并勾选。
   选择Parameter Settings项,ADC_Settings-->Continuous Conversion Mode(连续转换模式),使能连续转换。
   选择Parameter Settings项,Rank-->Sampling Time,设置为[239.5 Cycles],如果有更大,选更大。
   选择Parameter Settings项,ADC Injected Conversion Mode-->Injected Conversion Mode(连续转换模式),选择Auto Injected Mode(自动采集模式)
   选择DMA Settings项,Mode设置为Cirular(循环模式),Data Width设置为Word。
2、通过这个[CPU_TEMP_EN]宏定义来控制,查询CPU温度的代码是否编译。

3、[使用方法]:用于存储采集到CPU温度的两个变量本文件已定义,使用时,加入 #include "cpu_utils.h" 即可。
   HAL_ADC_Start_DMA(&hadc1, &CPU_Temp_AD, 1); //在RTOS任务的循环外调用该采集函数
   CPU_TEMP = osGetCPUTemp(&hadc1);//得到真正温度,需要读取温度时调用

*******************************************************************************/


/* Includes ------------------------------------------------------------------*/
#include "cpu_utils.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define CPU_TEMP_EN 1  //0不启用,1启动
/* Private macro -------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private variables ---------------------------------------------------------*/

xTaskHandle    xIdleHandle = NULL;
__IO uint32_t  osCPU_Usage = 0;
uint32_t       osCPU_IdleStartTime = 0;
uint32_t       osCPU_IdleSpentTime = 0;
uint32_t       osCPU_TotalIdleTime = 0;

volatile double CPU_TEMP = 0; //用于存放温度值
volatile uint32_t CPU_Temp_AD = 0; //用于存放温度AD值
/* Private functions ---------------------------------------------------------*/
/**
  * @brief  Application Idle Hook
  */
void vApplicationIdleHook(void)
{
    if( xIdleHandle == NULL )
    {
        /* Store the handle to the idle task. */
        xIdleHandle = xTaskGetCurrentTaskHandle();
    }
}

/**
  * @brief  Application Idle Hook
  */
void vApplicationTickHook (void)
{
    static int tick = 0;

    if(tick ++ > CALCULATION_PERIOD)
    {
        tick = 0;

        if(osCPU_TotalIdleTime > 1000)
        {
            osCPU_TotalIdleTime = 1000;
        }
        osCPU_Usage = (100 - (osCPU_TotalIdleTime * 100) / CALCULATION_PERIOD);
        osCPU_TotalIdleTime = 0;
    }
}

/**
  * @brief  Start Idle monitor
  */
void StartIdleMonitor (void)
{
    if( xTaskGetCurrentTaskHandle() == xIdleHandle )
    {
        osCPU_IdleStartTime = xTaskGetTickCountFromISR();
    }
}

/**
  * @brief  Stop Idle monitor
  */
void EndIdleMonitor (void)
{
    if( xTaskGetCurrentTaskHandle() == xIdleHandle )
    {
        /* Store the handle to the idle task. */
        osCPU_IdleSpentTime = xTaskGetTickCountFromISR() - osCPU_IdleStartTime;
        osCPU_TotalIdleTime += osCPU_IdleSpentTime;
    }
}


/*********************************************
函数名:osGetCPUUsage
功  能:得到CPU使用率 %
**********************************************/
uint16_t osGetCPUUsage (void)
{
    return (uint16_t)osCPU_Usage;
}

/*********************************************
函数名:osGetCPUTemp
功  能:得到CPU内部温度
形  参:hadc--ADC选择  Temp_AD--ADC采集的模拟量
返回值:
备  注:(1.43 - 3.3/4095 * SampleValue)/0.0043 + 25
笔  记:MX配置生成的ADC默认1000,未找到原因
**********************************************/
#if CPU_TEMP_EN

double osGetCPUTemp(ADC_HandleTypeDef* hadc)
{
    static uint8_t i = 0;
    double temp = 0;

    if(i == 0)
    {
        i = 1;
        HAL_ADC_Start_DMA(hadc, (uint32_t *)&CPU_Temp_AD, 1);
        HAL_Delay(5);
    }
    for(uint8_t a = 0; a < 10; a++)
    {
        temp += CPU_Temp_AD;
        HAL_Delay(2);
    }
    return (1.43 - (temp/1000/10)) + 25;
//return CPU_Temp_AD;
}
#endif
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

/**
  ******************************************************************************
  * @file    cpu_utils.h
  * @author  MCD Application Team
  * @version V1.1.0
  * @date    20-November-2014
  * @brief   Header for cpu_utils module
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */ 

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _CPU_UTILS_H__
#define _CPU_UTILS_H__

#ifdef __cplusplus
 extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "cmsis_os.h"
#include "stm32f1xx_hal.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
extern volatile double CPU_TEMP;
extern volatile uint32_t CPU_Temp_AD;
/* Exported macro ------------------------------------------------------------*/
#define CALCULATION_PERIOD    1000

/* Exported functions ------------------------------------------------------- */
uint16_t osGetCPUUsage (void);
double osGetCPUTemp(ADC_HandleTypeDef* hadc);
#ifdef __cplusplus
}
#endif

#endif /* _CPU_UTILS_H__ */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

 类似资料: