Even at the dawn of my career I had a chance to work with RTOS VxWorks and the Tornado development environment. The impressions were extremely positive (especially now there is something to compare), but the post is not about that. A component of the system at that time was a system for collecting and visualizing information on switching tasks in real time. I must say that the thing is extremely useful, not for nothing that they say that it is better to see once. For example, if you have at least two dozen tasks in your system, then with 99% certainty you can be surprised that when you see the task switching visualization, it will not be at all what you imagined it to be.
You can see the last moments of the system’s life, for example, in case of an unexpected failure, freeze or reboot!
But what to do if you have to work with RTOS and the environment where there is no such convenient mechanism? Of course, do it yourself!
')
Part one, collecting statistics.
Everything is simple - we need an exact timer (microseconds or more precisely) and some free memory space. In memory, we allocate space for the array for data (based on “one switch - taskId + time”), “hang” on the OC event “switch tasks” (and on the input-output to / from the interrupt, if you want to track them too), and save the data (the ID of the active task and the timer value) into an array (which is used as a cyclic buffer).
You can also implement “User-defined events” - write a function that, when it is called, will enter values ​​into this array to see when exactly one or another event in the code happens.
We implement the ability to start-stop logging on demand (CLI, function call ...) and the possibility of continuous logging (to track, for example, the last moments before a failure - after all, after rebooting, the saved data will be perfectly stored in memory, unless of course the memory is not forcibly cleared).
And, depending on the embedded system, we will implement some method of transferring this array from the embedded device to the PC, where we will visualize it. If embedded has a file system - it can be an entry in the file, if not - then some other option - sending over the network, for example. I used RS232, used in the system for debugging.
It remains to visualize the collected information. And here we don’t even have to write anything (or almost nothing). You can use the free package Octave, which can draw 2D graphics functions and perfectly implements zoom-in - zoom-out (even if you collect data in just a couple of seconds, considering that usually a task time slice is 1 millisecond, without a zoom not enough).
All you need to do is convert the collected data to the Octave format:
y = [time1, time2, ..., timeN];
x = [task1, task2, ..., taskN];
plot (x, y)
grid on
Here, timeX is time (in any units, it is more convenient to use, for example, micro- or milliseconds, and make time1 equal 0), and taskX is the task ID (in principle, any number, but it is more convenient, again, to sort tasks by priorities and ration them so that their IDs were 1, 2, 3 ..., remembering what value of which task). If there are interruptions and user events, you can also think of something, for example, by numbering user events with negative numbers.
How to do this conversion - everyone can choose for himself (it is here that you will have to write a little of your code).
The result will be something like this. This is how the system looked in the idle state:

And so - fully loaded:

"
It seems to me that the opportunity to see what is really happening in the system with my own eyes is worth it to spend a little time and do the above actions.
A professionally made decision from WindRiver was, of course, more beautiful, it showed task names, not abstract IDs, showed interesting points in dots on the graph ... But if it isn’t, then it’s better to have your own, albeit simpler than not to have it at all.