Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By pangolin
#88064 btidey's answer is a good one - we need to think of what we actually mean by "CPU load". In a single-thread/process/core it is not very meaningful. Comparing an ESP8266 with e.g. linux or widows task manager is not only pointless and irrelevant, but quite impossible, since those are full multitasking OSs and ESP8266 is nothing like that.

On those systems CPU load is the percentage of time spent running tasks. ESP8266 has no "tasks" as such* hence the only sensible figure you could get using that argument is 0% - ALL the CPU power is available to you. (*I'm excluding the "background" WiFi and any RTOS SDK for the sake of simplicity). Another argument is that since yours is the only code and is always running, the load is always 100%

So the first question must be: "what are you trying to measure / show"?

If the answer is to show how much time is my cpu doing "useful work" then YOU must define what "useful work" is. No MCU or software framework can know that - which is why there is no standard or "easy" way to do this, because it's user-defined.

I have firmware that does something like this and even shows a rolling graph in the web UI...but the firmware includes its own scheduler, so I have a useful metric: Tsched / Tloop *100 i.e. the percentage of time spent in scheduled tasks as a proportion of time in the main loop NOT running a scheduled task. In effect the main loop becomes the "idle" task. (See video https://www.youtube.com/watch?v=i9hjpYnfQoc @ 4:00 onwards. N.B. The firmware no longer includes CPU% mainly because there are much better / more useful metrics)

But see what just happened there - I am talking again about task scheduling and idle time: like an OS. It is only in this context that the question makes any sense at all. With just your own code, the question is meaningless - hence perhaps why there have been no answers - the simple truth is: there isn't one!

I suspect what the OP is asking is how to measure the amount of time spent inside certain functions, i.e. real-time profiling. he will need to "instrument" those functions and maintain his own figures - there is no automatic way to do this. If he takes the difference between cycle count on entry and exit then he can comparte this with max possible cycles in a given "time slice" by knowing the clock speed and can thus show % of CPU used by the instrumented functions (only) in that time slice. He would also need to ensure that all function exit points were timed, or that there was always a single common exit point.

This would require something like a Ticker function once per second (the actual length of the slice is irrelevant) and a global variable cyclesUsed. Each instrumented function adds its own no. of cycles used (Ccount EXIT - Ccount ENTRY) to the global. On each tick, calculate the proportion of used cycles vs total available cycles in one time slice. If he wanted accurate values he would also need to subtract the number of cycles used by the ticker function and % calculation. If he doesn't care about accuracy, then it again begs the question: what is he trying to measure and why?

So while that is a working exmaple of real-time profiling, the figure it produces is not very helpful as... what can you do with it? what differences / changes can you make based upon it? what is it actually telling you? It tells you nothing about true CPU load unless you a) instrument every single function b) edit the whole body of the ESP core to instrument all those functions too.

I hope this helps explain the difficulties in answering the question. The only better answers will come when we know what the OP thinks he wants to measure.
User avatar
By prof7bit
#94185
In the Arduino environment the simplistic and not useful answer is that the CPU load is 100%.


At my workplace (a company producing industrial sensors) I'm doing a lot of stuff with bare metal ARM Cortex controllers (no framework at all) and on the ARM there exists an assembly instruction WFI (wait for interrupt). What it essentially does is to suspend the core (but leave all peripherals running) until the next interrupt happens. Then it will immediately wake up, serve the pending interrupt handler(s), then exit the WFI instruction and do exactly one main loop iteration until it encounters the WFI again and sleep again.

So in a scenario like this the CPU consumption would be defined as the time spent outside this WFI instruction. Sometimes I set an unused GPIO pin high immediately before WFI and set it low immediately after WFI and then use the oscilloscope to measure CPU consumption.

A few weeks ago I finally bought my first ESP8266 boards for my private smart home installation and with it I was confronted with actually using (not only reading about) the Arduino framework for the first time in my life.

And the first thing after I got my initial skeleton working I was looking for was the ESP8266 equivalent of WFI.

For me it just does not feel right to let the CPU needlessly spin in the main loop more often than exactly once after every interrupt, but I cannot really find any information about how this is done in the Arduino framework on more modern (than Atmega) processors or if it is possible at all (on the ESP).

The docs about ESP8266 power management and "automatic light/modem sleep" are talking about "when the CPU is idle" but fail to explain what exactly constitutes an idle CPU, it seems that calling delay() in the Arduino framework has something to do with it but I could not yet explore what exactly happens in the delay() function on the ESP-Arduino that makes the CPU "idle" and allows Modem-Sleep or Light-Sleep.

I found this thread while trying to google for this whole general problem complex because it mentioned the word "idle". I have still not quite understood what exactly is going on behind the scenes on the ESP with regards to "idle", delay() and "sleep".
User avatar
By Inq720
#94196 Like the previous posts mentioned, there is no concept of hardware throttling. PC CPU's change CPU speed, and shutdown components and that is what you're seeing with the Windows Task Manager. MPU's at this end of the scale have no such concept... they're 100% all the time. The delay(), idle(), etc... just offer up the MPU to work on something else. If nothing takes it up on it, the Espressif layer takes it back and runs something else. Remember... calling your loop() method is at the bottom of the priority list. Interrupts come first, then doing other high-priority things like WiFi, PWM or Serial communications (software versions). If nothing else needs the CPU, the loop() is called. If the rest of the MPU is lightly loaded, the loop() gets called more often - faster.

Like you, I wanted some gauge as well... Knowing the above, I implement the obvious one... Loop Frequency rate. If the CPU is busy doing things like WiFi, messing with Flash, PWM, etc, the Loop Hz rate drops. If you go below 1Hz you're getting in the area where the watchdog starts getting ugly... at around 0.3Hz.

I've incorporated Loop Frequency along with some other useful server metrics into InqPortal. If the server is just sitting there doing what we would think of as being idle, the Loop Frequency is around 130kHz. If you bump up the clock rate to 160MHz, the Loop Frequency is around... 270 kHz. In InqPortal's case lightly loaded still means handling a WebSocket connection pumping out these metrics to the Browser client.

This image shows InqPortal under a fairly high load. It is calculating the Math cosine function at a rate of 100 Hz, while also handling 4 web socket connections and pumping out about ~13kB/second worth of data. The Loop Frequency is hovering around ~97kHz.
load.png


Here is another example showing the built-in Task Manager. Here it shows the ESP8266 performance metrics while uploading about 2 MB of web content to the flash "disk". It shows
  • Rate - Data transfer rate of the file upload.
  • Loop - Dropping from the "idle" of 130kHz to close to zero in some samples
  • Memory - Heap allocation as the files are added and the Dictionary gets built.
  • Voltage - Using ADC_MODE(ADC_VCC) to get supply voltage to the ESP8266.
Upload.png
You do not have the required permissions to view the files attached to this post.
User avatar
By oswe
#96101 this is a very interesting topic. we know rtos in esp8266 implementation has some hidden functions. we call them only by name theres no specific documentation....so how can we be sure that our program will not crash ????
ive made a simple wifi and print counter and after 2 hours it resetted because of wdt . now, i have not the slightest idea of what can it be.... hehe!
so . Arduino approach is not free from this as in the lower layer is esp-idf with its hidden rom functions ....
the only thing that is free from this comments are all other micros with a real datasheed, an accumulator, an ALU, some registers.... where you really know what is happening... (old times hehe)