AnsweredAssumed Answered

CPU utilization/Load on STM32F767

Question asked by raviteja L on Feb 26, 2018
Latest reply on Feb 26, 2018 by T J

Hi,

I am trying to get CPU load/utilization on STM32F767 Nucleo 144 board.
I am using CPU Load calculation implementation from
https://stm32f4-discovery.net/2015/08/hal-library-19-cpu-load-monitor-for-stm32fxxx/
(tm_stm32_cpu_load, tm_stm32_general files alone)and HAL library is generated from STM32 cube.
This implementation is based on DWT Cycle count.

 

As shown in above link, here is the logic to calculate CPU load,

 

    while (1) {
        /* Check if CPU LOAD variable is updated */
        if (CPU_LOAD.Updated) {
            /* Print to user */
            printf("W: %u; S: %u; Load: %5.2f\n", CPU_LOAD.WCNT, CPU_LOAD.SCNT, CPU_LOAD.Load);
        }
        
        /* Toggle leds */
        //TM_DISCO_LedToggle(LED_ALL);
        HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7);
        
        /* If button pressed, do some useless counting */
        //if (TM_DISCO_ButtonPressed()) {
        if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)) {
            /* Count something to waste some time before entering to sleep mode */
            i = 0;
            while (i++ < 0x1FFF);
        }
        
        /* Go low power mode, sleep mode until next interrupt (Systick or anything else), measure CPU load */
        TM_CPULOAD_GoToSleepMode(&CPU_LOAD);
    }

 

uint8_t TM_CPULOAD_GoToSleepMode(TM_CPULOAD_t* CPU_Load) {
        uint32_t t;
        static uint32_t l = 0;
        static uint32_t WorkingTime = 0;
        static uint32_t SleepingTime = 0;
        static uint32_t LastTime = 0;
        uint8_t irq_status;

 

        /* Add to working time */
        WorkingTime += DWT->CYCCNT - l;

 

        /* Save count cycle time */
        t = DWT->CYCCNT;

 

        /* Get interrupt status */
        irq_status = __get_PRIMASK();

 

        /* Disable interrupts */
        __disable_irq();

 

        /* Go to sleep mode */
        /* Wait for wake up interrupt, systick can do it too */
        __WFI();

 

        /* Increase number of sleeping time in CPU cycles */
        SleepingTime += DWT->CYCCNT - t;

 

        /* Save current time to get number of working CPU cycles */
        l = DWT->CYCCNT;

 

        /* Enable interrupts, process/execute an interrupt routine which wake up CPU */
        if (!irq_status) {
                __enable_irq();
        }

 

        /* Reset flag */
        CPU_Load->Updated = 0;

 

        /* Every 1000ms print CPU load via USART */
        //if ((SleepingTime + WorkingTime) >= HAL_RCC_GetHCLKFreq()) {
        if ((TM_DELAY_Time() - LastTime) >= 5000) {
                /* Save values */
                LastTime = TM_DELAY_Time();
                CPU_Load->SCNT = SleepingTime;
                CPU_Load->WCNT = WorkingTime;
                CPU_Load->Load = ((float)WorkingTime / (float)(SleepingTime + WorkingTime) * 100);
                CPU_Load->Updated = 1;

 

                /* Reset time */
                SleepingTime = 0;
                WorkingTime = 0;
        }

 

        /* Return updated status */
        return CPU_Load->Updated;
}    

 

I have remapped the Disco led to LD2, Button to User Button 2 and Usart6 to Usart1 using HAL from STM32 Cube.
I am able to flash and run the code but the CPU load always comes around 88% and when the button is pressed, it goes to 99 %,
 please tell me what could be going wrong ??

 

 log sample:
W: 1263737; S: 209832; Load: 85.760292 (Without button press)
W: 80240036; S: 30744; Load: 99.961693 (Button pressed)

 

Thanks,
Raviteja

Outcomes