2023-02-21 09:17 AM
Heyho,
I was just trying to check awake vs sleep in my H723 application (no OS), so I wanted to make sure that my code is okay.
It's using the cycle counter to measure all the cycles when the CPU is NOT sleeping, then compares the cycle sum to the SysTicks (1 ms).
So please have a look if I did something wrong - because I was surprised about the results.
When doing audio streaming via lwIP's TCP, it's about 50% sleeping at maximum bandwidth (~50Mbit/s), when streaming is off sleep percentage goes up to 98%.
Here's where the cycle counter is recorded:
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* MSTATE_IDLE:
* CPU enters SLEEP mode to make room for DMA transfers
*/
case MSTATE_IDLE:
{
#if DEBUG_CPU_TIMING
u32CycFuncStop = DWT->CYCCNT;
u32CycFuncSum[15] = u32CycFuncStop - u32CycFuncStrtWake;
u64CycSumFunc[15] += (uint64_t)u32CycFuncSum[15];
if( (u32CycFuncSum[15] > u32CycFuncMax[15]) && (u32CycFuncStrtWake != 0) )
u32CycFuncMax[15] = u32CycFuncSum[15];
u32CycFuncCalls[15]++;
#endif
CpuSleepMode();
#if DEBUG_CPU_TIMING
u32CycFuncStrtWake = DWT->CYCCNT;
#endif
u8MainState = MSTATE_LWIP;
break;
}
And here's how I get the sleep / awake percentage:
float flClockkHz = (float)HAL_RCC_GetSysClockFreq() / 1E3;
uint32_t u32TickTotal = 0;
u32CycTickStop = HAL_GetTick();
u32TickTotal = u32CycTickStop - u32CycTickStart;
...
/* SLEEP time / percentage, using ticks since start */
uart_printf("\n\rnot SLEEPing:\n\r");
uart_printf("SysTick since cycle start / reset = %lu ms\n\r", u32TickTotal);
flVal = (float)(u64CycSumFunc[CYC_FUNC_AWAKE] / (uint64_t)1E6);
uart_printf("u64CycSumFunc = %.3f Mega cycles\n\r", flVal);
flVal /= (float)u32TickTotal;
uart_printf("-> %.3f Mcyc/tick\n\r", flVal);
uart_printf("-> %.3f Mcyc/s\n\r", (flVal * 1000.0f));
flVal *= 1E6f;
flVal /= flClockkHz;
flVal *= 100.0f;
uart_printf("-> %.2f %% AWAKE\n\r", flVal);
uart_printf("-> %.2f %% SLEEP\n\r", (float)(100.0f - flVal));
Solved! Go to Solution.
2023-03-12 01:18 PM
There is a critical thing missing related to interrupts. Read my posts there:
There is no necessity of arrays or floating point math. Just accumulate the load and total cycles for a second. When the total cycles reach SystemCoreClock, calculate the load percentage. The period, of course, can be chosen different and the load factor can also be expressed, for example, as a 1/10000th fractions.
In addition take note that a constant like "1E3" is a number of a double type.
2023-03-12 01:18 PM
There is a critical thing missing related to interrupts. Read my posts there:
There is no necessity of arrays or floating point math. Just accumulate the load and total cycles for a second. When the total cycles reach SystemCoreClock, calculate the load percentage. The period, of course, can be chosen different and the load factor can also be expressed, for example, as a 1/10000th fractions.
In addition take note that a constant like "1E3" is a number of a double type.
2023-03-12 11:18 PM
Thanks, @Piranha !
2023-03-12 11:20 PM
... and that takes another 5% from sleep time.
Doesn't really matter, but I thought my ISRs were a little faster.