I got the EventRecorder to work at last, but in the component tab it doesn't show the name of the threads. They are all called "RTX Thread". I already entered a name in the osThreadAttr_t, but it is not visible during debugging. I can also see the thread_id in HEX format, but I would have to know those by heart which is not practical.
Did you try using the System Analyzer? It will trace thread events graphically (start, context switches, etc.) and will label threads with their 'names'.
Yes, but I think I have not really understood yet how it works. It doesn't show me a lot of information usually. At the moment I can only see "Event Recorder Start", but sometimes it shows me more information. Don't know why.
If using the RTOS2 API, make sure you have selected 'Source' for the Keil RTX5 component and enabled event generation in RTX_Config.h. If you have 'Library' selected, you won't see RTOS2 events.
If you're using the older RTOS API, you can choose to have it implemented using RTOS2 ('RTX5'). Choose 'Source' and you should see the events.
If you don't see ThreadCreation events, then the Event Recorder might not be configured to track them. Halt the target and click the filter icon in the Event Recorder window to show the events that are being tracked. Update the list and restart the target and you should see the events in the EventRecorder and the System Analyzer.
I didn't mean the Event Recorder. That one shows events without problems. In the system analyzer I don't see all events
EDIT: I made a second svdc file whose content doesn't get deleted now. Now I can see the events in the System Analyzer, but only after I have stopped the code execution. Is this normal?
I also see that I have sometimes up to four threads in the running state at the same time as shown in the screenshot below. Since the Cortex M3 has only one core, I wonder why that is. I can imagine that the EventRecorder is recording to slow or something. It is really confusing.
One behaviour is really weird. Sometimes all threads are loaded into the System Analyzer as soon as I hit run, sometimes some threads are loaded and sometimes no threads are loaded. Could it be that I initialize the EventRecorder too late? I am initaliazing it via the option "Global initialization". I also increased the number of records to 128, because I thought maybe there might not be enough memory. It did not solve the problem. I have to get out of debugging mode and start it again until some threads are loaded by chance.
If Golbal Initialization is enabled, you don't need to explicitly call the initialization function. Best not to, because that can lead to unexpected behavior from the system analyzer.
I do think that the event recorder can be overwhelmed and miss events. Use the filtering options in the EventRecorder view and in the RTC_Config.h file to reduce the number of events and the missing threads should re-appear.
As for multiple threads running on the same core -- there could be a few different causes for that apparent behavior. I would guess that your code is relying on the kernel preempting threads, because I don't see a lot of 'blocked' threads.
Adam Lins said:I do think that the event recorder can be overwhelmed and miss events. Use the filtering options in the EventRecorder view and in the RTC_Config.h file to reduce the number of events and the missing threads should re-appear.
I have already reduced the events to a minimum. I guess I have to live with it then. It might also be caused by the ULINK ME2. I think it is not the fastest JTAG.
Adam Lins said:As for multiple threads running on the same core -- there could be a few different causes for that apparent behavior. I would guess that your code is relying on the kernel preempting threads, because I don't see a lot of 'blocked' threads.
I am not that experienced with the multithreading design options yet. This design was also not made by me.
From what I have seen it works like this:Threads are created with the same priorities and after the execution of each thread an osThreadYield is called. Is this an okay solution? From what I understand the threads should be managed by the kernel and not manually. There are also a lot of problems with the design. TCP threads are running when nothing happens. A lot of computing time seems wasted. A lot of host buffer overflows are shown in the EventRecorder. The operation seems a bit sluggish at times. I probably need to optimize it properly.
I am just curious how it is even possible that multiple threads are running concurrently on a single-core processor.
Concurrent execution of threads is not the same as concurrent execution of instructions from different threads. System Analyzer says multiple threads are in the RUNNING state. That doesn't mean the instructions for the code in each thread are executing concurrently at the timescale of the CPU clock.
System Analyzer gets its data from the EventRecorder, so everything being in the RUNNING state could just be an artifact of data logging falling behind (as you noted). You can trim back RTOS events to the critical ones you need to get debugging done, which might just be a few custom events.
The IDE will use bandwidth on the debugger link to maintain System Views, watched variables, memory, etc. Turn off any of those you don't need to maximize the bandwidth for EventRecorder.
Instead of osThreadYield() I prefer to wait for signals sent to the thread (which can be set in an ISR) and/or timers. That means most of the time is spent in the RTOS idle thread. On the other hand, use of osThreadYield() could be appropriate for your design. Unless things aren't working as desired.
I had to revert back to an old code and I made the same changes to see events. Now the System Analyzer never shows thread, although the Event Recorder is active and working...
Adam Lins said:Concurrent execution of threads is not the same as concurrent execution of instructions from different threads. System Analyzer says multiple threads are in the RUNNING state. That doesn't mean the instructions for the code in each thread are executing concurrently at the timescale of the CPU clock.
It makes sense that not every instruction is visible in the Event Recorder or System Analyzer.
Adam Lins said:Instead of osThreadYield() I prefer to wait for signals sent to the thread (which can be set in an ISR) and/or timers. That means most of the time is spent in the RTOS idle thread. On the other hand, use of osThreadYield() could be appropriate for your design. Unless things aren't working as desired.
This is a good tip. I will try to maximize the performance after everything has been implemented.
Thank you for your extended explanations and your time. It has been really helpful!