Nesting of critical regions

I’m working on a port for the pic18 using wizC as development environment. It looks like "enter_critical"/"exit_critical" should be able to be nested. The current MCC18 port for the pic18 uses the softwarestack to do this. Because wizC does not use a framepointer, I cannot use this technique. I looked through some other ports and found an alternative in the "GCCMSP430F449"-port. But I was wondering: Can the pic’s hardwarestack be used for this? This stack is used by wizC as call/return-stack but is modifiable from software. I think it can be done IF all combinations of enter/exit are at the same level. What I mean is: An enter_critical and it’s counterpart should always be in the same functioncall-depth. Can anyone tell me if this is guaranteed the case? Now and in the future?

Nesting of critical regions

Because my first tests run succefully, I think the answer to the above question is ‘yes’, but confirmation is still appreciated.

Nesting of critical regions

I’m not sure I quite follow this one. The msp430 port uses the method for systems that cannot modify the stack without crashing the program – typically systems that don’t use a frame pointer as you say. It works by simply maintaining a count of the depth of critical section nesting.  Each task must have it’s own count, so the count is saved and restored as part of the tasks context. As far as I can remember the hardware stack on the PIC is used by the processor itself when jumps are made.  It might be that you can use values on the stack yourself, provided no function calls are made while the stack has been modified.  The bit width of the stack may be odd.  I suggest that this has potential to be a dangerous approach … but I’m always willing to be proved wrong.

Nesting of critical regions

Indeed, I don’t have a framepointer and therefore cannot modify the software-stack. The pic hardwarestack is mostly used as a implicit call/return-stack, but it’s use is not limited to that. It can also be used as a datastack by using the push/pop instructions. Functioncalling between the push/pop combinations is no problem as long as the pop is done after returning from these functions (stack must be the same before the pop as it was just after the push). Basically what I am asking is: Are the enter_critical and the exit_critical always in the same function? So, this is no problem: … enter_critical call func     return from func exit_critical … But this is a problem: … enter_critical call func   exit_critical   return from func … Perhaps it’s easier to simply use the msp430 way. It’s part of my personality: when I dive into something, I want to get to the bottom… :-)

Nesting of critical regions

Things are a little complicated. The enter/exit routines are always in the same function (function calls can exist between them however) … BUT … It is possible for a context switch to occur within a critical region.  This sounds odd but there are places where a portYIELD is called within a critical section.  This is ok as each task maintains it’s own interrupt flags so the next task will start with interrupt enabled.  When the task that called yield from within the critical section starts again it will start with interrupts disabled. I’m not sure how this affects your idea.  When a yield is performed the hardware stack is swapped out (presumably) so any modifications may just get saved as part of the task context and then not affect any other tasks.  I think the only way to get confidence in this is to step through a few switches in the simulator.  You could try adding: portENTER_CRITICAL();     taskYIELD(); portEXIT_CRITICAL(); within a simple task and see what happens!

Nesting of critical regions

Tested it with no problems! Even with multiple tasks sharing their code using different values for pvParameters. But I have decided to go the MSP430-way because I don’t see (m)any advantages in my approach. Besides, adding a new concept could possibly interfere with future modifications/additions of FreeRtos. Thanks anyway, I’m really learning a lot!