Questions about PIC24 port

armag1234 wrote on Saturday, December 08, 2007:

Hi, I’m new to FreeRTOS. I want to learn more about the PIC24 port which is the version I’m most interested in.

Question 1:
Why is the omit frame pointer optimization necessary.  When I turn this optimization on I can no longer view the call stack in MPLAB.  In fact, MPLAB(8.0) hangs without this optimization.

Question 2:
I’m alittle confusion about the context switching code.  Browsing through the code, it looks like a context switch can only happen inside a yield function( Interrupt routines call Yield if the interrupt changes the currently active thread ).   The C30 manual says W0-W7 are caller saved so that it doesn’t need to saved( the save happens in the caller ).  Also, instead of building an interrupt context it would be possible to simply save the old priority in the local variable section of the call frame.  I realive that C30 doesn’t support the naked attribute, but it seems pretty easy to create a small asm file for Yield.  I’m thinking about making these changes on my local copy of FreeRTOS but I just want to make sure this is safe.

Question 3:
Why isn’t the stack limit register switched during a context switch.

armag1234 wrote on Sunday, December 09, 2007:

Ok, I think I understand questions 2 and 3.  For question 2, it’s necessary to save all the registers so that a new task can properly start.  The parameters argment is passed in w0.  For question 3, it looks like C30 never initializes SPLIM.  It’s set to the highest RAM address.

I still don’t understand question 1.  Why is the omit frame pointer optimization necessary?  With this optimization enabled MPLAB 8.0 crashes/hangs when viewing call stacks.

picmeup wrote on Sunday, December 09, 2007:

Without omit frame pointer the epilogue code is different for a standard function and an interrupt service routine. Using the optimisation allows a single task switch function to be used in both cases. I am not convinced it is necessary though given the way the task switch is performed from in a separate function anyway. It looks like the frame pointer thing was used on the assumption the switch was to be done from a macro. I will look at this again. Whether a macro or function is better depends on if you want less execution time or less object code.

I dont know if it is the same for PIC24 but in ARM the GCC has a bug with frame pointers so they should not be used. You can see this looking through the change history. Maybe this is why it is not used.

Relying on what the compiler says it is going to do is not always good as this can change with compiler versions and at different optimization levels. There are always going to be trade offs. But take a look at the PIC32 port. This uses an assembly file rather than a C file for the task switch. This would be a more efficient method for the PIC24 port as well as it would prevent saving some registers more than once in the absence of the naked attribute. Again a macro would save this as well but result in more object code.

I have written it using the stack limit register before but cant find the code. Maybe it is on my work computer. What you have to do is save the task context, set the stack limit to the end of the heap, then restore the new task context, and finally set the limit register to the correct place for the new task. If you miss out step two you will generate an exception if the task being swapped in has a stack that is outside the current limit.

Try this change then send it to Richard and see if he will include it. I think the safe RTOS code has stack limit checking already. The PIC24 port is very stable but could be more efficient with assembly file as PIC32.

armag1234 wrote on Sunday, December 09, 2007:

Ok, I’ll take a crack at converting the Yield function into a pure assembly function in a separate ASM file.   I think if this were done FreeRTOS would work regardless if the omit frame pointer optimization is on or off( easier to debug ).  In my opinion, allowing easier debugging is a bigger plus then more optimal task switching.  I’ll try to incorporate the SPLIM change as well.

For C30 the calling convention is documentated quite well.  If Microchip were to change this between compiler versions they would break all the people mixing ASM and C including themselves since parts of the runtime libraries are written in ASM.

I’m planning to use FreeRTOS in a robot project that can be used as a test for my changes.  If everything works, then I can try to see if I can get the change included.  Perhaps a good way to get the changes included is to have both versions for awhile and people that don’t want to turn on optimizations can use the alternative version until the alt version proves itself to be stable. 

richpainter wrote on Wednesday, May 21, 2008:

I don’t see any followup on this… What did you do to resolve this?

I would like to be able to use frame pointers in my MPLAB dsPIC33 project.

There should be a way to just selectively omit-frame-pointers for just the FreeRTOS module that needs it instead of absolutely everything!

Please advise.