For performance reasons, sometimes we want to know the CPU usage rate, so as to determine the CPU load and whether it is "capable" enough for the current operating environment. This article will introduce a method for calculating CPU occupancy and its implementation principle.
2. Transplantation Algorithm
2.1 Algorithm Introduction
This algorithm is based on the operating system. In theory, it is not limited to any operating system, as long as there is task scheduling. This article will take FreeRTOST as an example to introduce the use of this algorithm.
The algorithm introduced in this article comes from the Cube library. Its location in the Cube library is shown in the figure below:
This article will take STM32F4 as an example, and the test environment is the STM3240G-EVAL evaluation board.
2.2. Start porting
This article takes the sample code project STM32Cube_FW_F4_V1.10.0\Projects\STM324xG_EVAL\Applications\FreeRTOS\FreeRTOS_ThreadCreation in CubeF4 as an example, and uses IAR as the IDE.
Step 1:
Use IAR to open the FreeRTOS_ThreadCreation project, add the cpu_utils.c file to the project, and add the corresponding header file directory to the project:
Step 2: Open the FreeRTOST configuration header file FreeRTOSConfig.h and modify the values of the macros configUSE_IDLE_HOOK and configUSE_TICK_HOOK to 1:
#defineconfigUSE_PREEMPTION 1
#defineconfigUSE_IDLE_HOOK 1 //Modify the value of this macro to 1
#defineconfigUSE_TICK_HOOK 1 //Modify the value of this macro to 1
#defineconfigCPU_CLOCK_HZ (SystemCoreClock )
#defineconfigTICK_RATE_HZ ( (TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 8 )
#define configMINIMAL_STACK_SIZE (( uint16_t ) 128 )
Step 3: Continue to add traceTASK_SWITCHED_IN and traceTASK_SWITCHED_OUT definitions at the end of the FreeRTOSConfig.h header file:
#definetraceTASK_SWITCHED_IN() extern voidStartIdleMonitor(void); \
StartIdleMonitor()
#define traceTASK_SWITCHED_OUT() extern voidEndIdleMonitor(void); \
EndIdleMonitor()
Step 4: Include "cmsis_os.h" in the main.h header file
:
#include "stm32f4xx_hal.h"
#include "stm324xg_eval.h"
#include "cmsis_os.h" //Add this header file
//…
Step 5: Modify the project properties so that the compilation process does not require function prototypes:
Step 6: In any user code in the project, you can call the osGetCPUUsage() function to get the current CPU usage:
static void LED_Thread2(void const *argument)
{
uint32_t count;
uint16_t usage =0;
(void) argument;
for(;;)
{
count =osKernelSysTick() + 10000;
/* Toggle LED2 every500 ms for 10 s */
while (count >=osKernelSysTick())
{
BSP_LED_Toggle(LED2);
osDelay(500);
}
usage =osGetCPUUsage(); //Get the current CPU usage
/* Turn off LED2 */
BSP_LED_Off(LED2);
/* Resume Thread 1 */
osThreadResume(LEDThread1Handle);
/* Suspend Thread 2 */
osThreadSuspend(NULL);
}
}
Step 7: Compile and run the test
Use the Live Watch window to monitor the values of all variables osCPU_Usage in the debugging state:
osCPU_Usage is a global variable defined in the cpu_utils.c file. It indicates the current CPU usage rate. It is a dynamic value. As shown in the figure above, the dynamic value of CPU usage rate is 20%. In the actual code, the osGetCPUUsage() function is called in step 6 to obtain the current CPU usage rate.
So far, the algorithm usage method has been introduced.
3. Analysis of the algorithm implementation principle
When the operating system is running, it constantly switches between different tasks, and the scheduling process is driven by the system tick. That is, each time a system tick is generated, the environment of the currently running task is checked to determine whether it is necessary to switch tasks, that is, scheduling. If necessary, PendSV is triggered, and the vTaskSwitchContext() function is called in the PendSV interrupt to implement task scheduling. The CPU usage algorithm to be described in this article is to calculate the total amount of time slices occupied by idle tasks within a certain period of time (within 1000 time slices). 100 minus the percentage of idle tasks is the percentage of working tasks, that is, CPU usage.
void vApplicationIdleHook(void)
{
if( xIdleHandle == NULL )
{
/* Store the handle to the idle task. */
xIdleHandle =xTaskGetCurrentTaskHandle(); //Record the handle of the idle task
}
}
This function is the idle task hook function. This hook function will be run every time when switching to the idle task. Its function is to record the handle of the current idle task and save it to the global variable xIdleHandle.
void vApplicationTickHook (void)
{
static int tick = 0;
if(tick ++ >CALCULATION_PERIOD) //Refresh CPU usage every 1000 ticks
{
tick = 0;
if(osCPU_TotalIdleTime> 1000)
{
osCPU_TotalIdleTime =1000;
}
osCPU_Usage = (100 -(osCPU_TotalIdleTime * 100) / CALCULATION_PERIOD); //This line of code is the specific calculation method of CPU usage
osCPU_TotalIdleTime =0;
}
}
This function is the tick hook function of the operating system, that is, each time a system tick interrupt is generated, it will enter this hook function. This hook function is actually the specific algorithm for calculating CPU usage. osCPU_TotalIdleTime is a global variable, which indicates the total time slice occupied by the idle task within 1000 ticks. The value of CALCULATION_PERIOD macro is 1000, which means the CPU usage is recalculated every 1000 ticks. The
following two functions are how to calculate osCPU_TotalIdleTime:
void StartIdleMonitor(void)
{
if( xTaskGetCurrentTaskHandle() ==xIdleHandle ) //If it is switched to the idle task
{
osCPU_IdleStartTime =xTaskGetTickCountFromISR(); //Record the time point when the idle task is switched
}
}
void EndIdleMonitor(void)
{
if( xTaskGetCurrentTaskHandle() ==xIdleHandle ) //If it is switched out from the idle task
{
/* Store the handle to the idle task. */
osCPU_IdleSpentTime =xTaskGetTickCountFromISR() - osCPU_IdleStartTime; //Calculate how long this idle task takes
osCPU_TotalIdleTime += osCPU_IdleSpentTime;//Accumulate the time occupied by the idle task
}
}
These two functions are scheduler hook functions, which are called back when the scheduler switches in and out of tasks respectively. The StartIdleMonitor() function records the time point when switching to the idle task, and the EndIdleMonitor() calculates how long the idle task takes when exiting the idle task, and accumulates it to osCPU_TotalIdleTime, which is the total time slice occupied by the idle task.
uint16_t osGetCPUUsage(void)
{
return (uint16_t)osCPU_Usage; //Directly return the global variable osCPU_Usage, i.e. CPU usage
}
The global variable osCPU_Usage stores the CPU usage, which is recalculated every 1000 ticks in the tick hook function of the operating system.
4 Conclusion
This method can be used to evaluate the operating performance of the STM23 MCU.
Previous article:Several common reasons for serious MCU function abnormalities
Next article:Explanation of IdMask mode of STM8 CAN bus
Recommended ReadingLatest update time:2024-11-16 20:22
- Popular Resources
- Popular amplifiers
- Siemens PLC Programming Technology and Application Cases (Edited by Liu Zhenquan, Wang Hanzhi, Yang Kun, etc.)
- Siemens PLC from Beginner to Mastery with Color Illustrations (Yang Rui)
- Experience and skills in using Siemens S7-200PLC (Shang Baoxing)
- Siemens S7-1200-PLC Programming and Application Tutorial (3rd Edition) (Edited by Shi Shouyong)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- #The best content of the "Interview with famous teachers" in the Electronics Competition#The third issue - Professor Li Yubai of the University of Electronic Science and Technology of China
- #idlemarket# MM32 development board exchange open source development board
- Since the signal that needs to be sampled is 0.01uA-10uA, is there any low-voltage MOS with Ids leakage current in nA or pA level?
- Forum Prize: Texas Instruments TI-36X Pro Scientific Calculator Disassembly and Analysis
- Why does Kalman filter need to do the prediction step?
- Is this a circuit that can prevent the MCU from hanging?
- When southern girls start soldering irons to do projects, what do science and engineering men need? - Arduino, hardware, project tutorials
- The principle and method of generating multiple PWM waveforms using one timer
- The impact of 5G on positioning technology
- Why is the output waveform of Quartus 13.0 always at a low level?