How to dynamically get the CPU speed

Status
Not open for further replies.

pix-os

Well-known member
hi all, i have written a small example on how to get dynamic cpu speed detection instead of using the sille F_CPU macro, which is only used at compile time.

why i did this?

well, to determine the cpu cpeed at run-time, because the environment and such can have influence on the cpu clock.
this bit is also useful for when one wants to change cpu cpeed and adjust at run time things according to the speed.

the measurements are slightly off (like if setting cpu speed to 96mhz optimized oc, the value shown will be at around 100mhz)

code below:

Code:
uint32_t UNLOADED_IDLE_COUNTS = 0;
uint8_t cpu_speed_ = 0;
void setup() {
	detect_cpu_speed();
	delay(2000);
	Serial.begin(9600);
	Serial.print(cpu_speed_);
	Serial.println(" MHZ");
}

void loop() {

}

void detect_cpu_speed(){
  //cpu detection magic!
  //make sure only standard arduino ISR's are running, and NO user ISR's!!
  uint32_t microspassed = micros();
  while (1) {
   UNLOADED_IDLE_COUNTS++;
   if (micros() - microspassed > 250000) {
    break; //250ms to detect calculations/second
   }
  }
  cpu_speed_ = (UNLOADED_IDLE_COUNTS * 8)/50000; //convert to the actual CPU speed
}


i hope that this is usefull :)
 
i doubt it'll work, as the micros() is an interrupt function, and by doing the method above will cause it to run forever as micros isn't updated.
 
I just combined this and the CPU/RAM Usage sketch.

Compiling with 'Optimized @96MHz' .versus. '96MHz'
The RAM seem to track usably against what is shown at the end of compiling, though I didn't have any code allocating RAM.

But the Speed detect and CPU usage do not - so compiler optimizations are altering the code's intent. Adding the "noInterrupts(); Interrupts();" didn't seem to change the CPU speed calc.

'Optimized @96MHz'
100 MHZ
Ram Check started
CPU usage: 6%
Free RAM: 60415

'96MHz'
81 MHZ
Ram Check started
CPU usage: 249%
Free RAM: 62487
 
hm... weird that the compiler optimizations are altering the code's intent...

also, i didn't know the UNLOADED_IDLE_COUNTS was wrong as well! :O

i wonder if there is another way to get the cpu speed (inline, aside from F_CPU)...
also, i merely ported this from the OSdev wiki :p
 
Not sure how you saw
UNLOADED_IDLE_COUNTS was wrong
but ... My bad with UNLOADED_IDLE_COUNTS: You had a #define and a variable {between your sketches I combined}. Not sure how that compiled. I renamed the variable to vUNLOADED_IDLE_COUNTS.

How can this exist and compile in the same source file? One is removed in pre compile parsing (#define) and the other remains for the compiler (uint32_t)?
Code:
#define UNLOADED_IDLE_COUNTS 152000
  uint32_t UNLOADED_IDLE_COUNTS = 0;

weird that the compiler optimizations are altering the code's intent...

Compiler optimizations are sometimes surprising. They "calculate" 'wasted effort' and improve or remove it based on the effect or non-effect on any useful data changes, as well as re-ordering and cleaning things up - or breaking them - depending on the your intent and their applicability.
 
Status
Not open for further replies.
Back
Top