nobody wrote on Wednesday, March 08, 2006:
Comments are included below.
>The problem is that when exiting from the critical region, interrupts always
>get enabled - even if they were already disabled on entry to the critical
>region.
This can only be the case if interrupts were disabled by some means other than a call to portENTER_CRITICAL().
>Ok, so you may ask why do I want to enter a critical region when interrupts
>are already disabled? Well, I use a few utility functions which make use of
>critical region. These can be called from both interrupt and normal context.
>I don’t want to implement an interrupt and a normal context version of each
>such function.
Starting to make sense now. You want to use the ENTER/EXIT from within an ISR without the EXIT enabling interrupts.
>As another example I want to read the current timer tick value within my ISR
>by calling xTaskGetTickCount. But since xTaskGetTickCount() uses a critical
>region internally, interrupts are enabled on return - i.e. still within my ISR.
>That was what I referred to as a side effect. I means that I get nested
>interrupts,
Now I understand
>To summarize, there are 2 different issues:
>
>1. The current ARM7 port does not restore the interrupt state to its true
>previous
>state when exiting from a critical region. This is what i fixed by reverting
>to the implementation of FreeRTOS version 2.5.1.
>2. Saving the interrupt state on the stack is potentially unsafe and very much
>depending on compiler and optimization setting. The results of my
>trial-and-error
>experiments above might not even be valid with the next GCC version.
>Maintaining
>a list of valid optimization settings per compiler is a continous effort.
The documentation should be more specific on the effect if used from within an ISR.
>To prove the risk of saving interrupt state on the stack, I can supply another
>example:
>Yesterday I built a FreeRTOS application for an AVR target using the IAR
>compiler
>verion 4.12. For certain combinations of optimization, that application also
>crashes due to stack corruption caused by the critical region macros. The crash
>typically happens already in the function vTaskStartScheduler().
>
>My suggestion for a long-term solution is to change the programming interface
>to portENTER_CRITICAL and portEXIT_CRITICAL in such a way that
>portENTER_CRITICAL
>returns the current interrupt state, which the application function must store
>in its own local variable. This state variable must be supplied as a parameter
>to portEXIT_CRITICAL, which will restore the interrupt state to the value of
>this parameter. In other words: The developer must supply his own storage for
>the interrupt state instead of FreeRTOS trying to save it on the stack.
>Given this interface, it will be possible to revert the ARM7 implementation
>to that of release 2.5.1 and thus avoid the nesting counter.
This is in general I think a good idea but at the expense of the application writter having more responsibility.
What do other people think?