I understand that calling
taskENTER_CRITICAL() starts a critical section, and
taskEXIT_CRITICAL() ends it.
The documentation says that:
Critical sections must be kept very short, otherwise they will adversely affect interrupt response times.
This implies that the interrupts that occur while the processor is in the critical section are attended to, once the critical section has ended.
Can someone confirm that this is indeed the case - I don’t want to enter a critical section and consequently stand a chance to “lose” interrupts by not responding to them.
Also, what would happen if the same interrupt occurs more than once during a critical section:
The ISR would be executed once, once the critical section ends
The ISR would be executed twice, once the critical section ends
It depend a bit on the interrupt. Most interrupts will only be deferred for the duration of the critical section. On some processors, if the interrupt request goes away before the interrupt is serviced (the IRQ line to the processor was asserted then de asserted during the critical section) then the interrupt will not happen.
For your second question, that is basically just another case of the first, if the actual interrupt request goes away and then comes back, the first interrupt likely gets forgotten.
If it is something like a serial port, and two characters come in, and are stored in a hardware FIFO, then it is a matter that a well written ISR will check if multiple characters are available, and get them all. A poorly written ISR might just (incorrectly) assume that only 1 character might be available, and only get one.
To just re-iterate what @richard-damon was saying, the way interrupts work through critical sections has nothing to do with FreeRTOS and everything to do with your specific CPU.
The only way to answer this is to look at your port (specifically taskENTER_CRITICAL ) for how a critical section is implemented on the port for the CPU you are using, and then hit the datasheet for the CPU to understand what will happen. This also means that there is no guarantee that the behavior will be the same on all targets.
Another thing to consider is that there are very few use cases in which application code really need to claim a critical section (cs) - the cs is traditionally hopelessly overused; in many cases where FreeRTOS tasks do use it, a closer code analysis reveals that other, finer-granularity synchronization schemes would suffice.
In a well designed system, only those interrupts are turned off that may interfere with the code to be protected. The cs effectively breaks the system to a grinding halt., suspending the scheduler as well as the os clock (tick counter) along the way.
I have opted at least twice for a documentation change that labels the cs as code to be used exclusively for system and system relevant use so that application developers think twice before considering using it.
I would disagree on the idea that Critical Section are just for system code, at least for single core application.
I find I often need to make a quick operation atomic, and the speed of a critical section vs the overhead of a finer grade operation makes the critical section the hands down winner.
Perhaps the key is that I have strict limits of what is allowed to be inside the critical section (like no loops or function calls).