About porting the 8051 using Keil C.

nobody wrote on Monday, March 21, 2005:

Is that possible to use Keil C to compile the 8051 port? It seems that the Keil C did not have _naked functions as SDCC and with poor in-line assembler.

Also, will Keil C maintains a seperated SP and Frame pointer? Is that I need to make modification so as to include counters for Macro " enter_critical_section" and "leaving_critical_section"? Is that I also need to save this counter into the SP during context switching? Thank you!

nobody wrote on Monday, March 21, 2005:

[sorry for any belated replies - limited email access currently]

I’m sure it would be possible to use Keil C, but unfortunately I have no experience with the compiler so cannot offer direct help.

Regarding the stack pointer - frame pointer issue.  On systems that do not maintain both, or on systems that do not allow the stack pointer to be modified, then critical sections cannot use the stack to store the interrupt status.  Instead a critical nesting counter can be used.  This basically counts the nesting depth of the critical nesting, and only enables interrupts when the nesting reaches 0.  The nesting counter is then saved as part of the stack context.  This means the stack is not modified at any time other than when the context is saved.  See the GCC LPC2106 port for an example of this (portISR.c).

Regarding the lack of _task (or __attribute__ ((naked)).  Sometimes it is necessary to write an assembler wrapper around the C functions.  This means that asm is used as the entry point, but all the asm does is call the C function once the context is saved.  See the SAM7 port for an example.  This includes a small asm file with wrappers.

Slightly rushed answer …

Regards.

nobody wrote on Tuesday, March 22, 2005:

Thanks a lot!
But I want to make sure the follow things:

If I need to store the nesting depth counter, do I still need to store the Enable interrupt bit? If this is so, is that the nesting depth counter need to keep checking if 0 , then restore the EA bit during context restoration?

For 8051 port, it is known that XRAM is required for context switching. Thus, if NAKE function is not supported in Keil, do I need to impement this COPY XRAM to STACK / COPY STACK to XRAM to ASM macro? As if I do that by function call, seems that would corrupt the stack’s content.

Thank you for your advice.

rtel wrote on Tuesday, March 22, 2005:

>If I need to store the nesting depth counter, do I still
>need to store the Enable interrupt bit? If this is so, is
>that the nesting depth counter need to keep checking
>if 0 , then restore the EA bit during context
>restoration?

I don’t quite follow your question, but will try to answer it.

In the 8051 port a yield is performed by simply calling the vPortYield() function.  In other ports a software interrupt is used. 

When a software interrupt is used the status registers are saved to the stack by the processor, so the save/restore context functions do not have to explicitly save/restore the interrupt status flags.

When a function is used (as in the 8051 port) the status registers are not automatically saved to the stack by the processor, so the save/restore context functions must do this explicitly - even when you are saving the nesting depth counter.  When the context is restored the interrupt flag is set back to the same value it was when the context was saved.  The nesting counter is also restored so the kernel knows how many times EXIT_CRITICAL() has to be called before interrupts can be enabled (assuming they are disabled).

>For 8051 port, it is known that XRAM is required for
>context switching. Thus, if NAKE function is not
>supported in Keil, do I need to impement this COPY
>XRAM to STACK / COPY STACK to XRAM to ASM
>macro? As if I do that by function call, seems that
>would corrupt the stack’s content.

Again, don’t quite follow the question but I will try to answer …

If Naked cannot be used then the entry to the yield functions might have to be written in an asm file.  An asm file is used to prevent the compiler generating any function entry code - as this will corrupt the stack.

In the asm file, the first thing that should be done is to save the context and copy it to XRAM.  Therefore the context is immediately saved onto the stack before the stack is modified in any other way.

Once the context has been saved the C function can be called.  Now it does not matter if the stack is modified as the context is already saved.

After the C function has returned, the stack will be back to it’s original state.  The stack can be copied back from XRAM and the restore context macro can now be called (both from the asm file) to restore the stack of the task immediately prior to returning to the task.

It is a pain if the compiler does not support __naked as I prefer to avoid asm code whenever possible! (some compilers call this __task, have you checked to see if this is available?).

Hope this helps.
Regards.

nobody wrote on Tuesday, March 22, 2005:

Sorry for my poor question, let me clearify :stuck_out_tongue:

For the first question: I would like to ask for context switching, as you said before, if the compiler cannot maintains the SP/frame pointer, we should use nesting counter. So , I design to push this counter during context switching. However, the point is… is this counter should be used for re-enabling the interrupt bit(EA) (for example checking the nesting counter at the end of context switching, if =0 , reenable the EA) or just follow the old port, store the EA bit inside the stack would works fine?

The next question is that, for those XRAM to STACK/ STACK to XRAM copying macro used in 8051 port. It seems that if I try to modify it to use as FUNCTION CALL, this would make the 8051 to push its PC /other register which … for example during copy stack from XRAM… restoring the stack… but after the XRAM to STACK function returns… the “RET” would damge the whole STACK pointer’s location…

thank you again :slight_smile: hope this would be clear

nobody wrote on Tuesday, March 22, 2005:

Let me guess your meaning:
Enable interrupt bit still need to be stored in context switching
Nesting counter needed to be stored to TCB too!

But nesting counter is not for restore the EA bits! All just depends on the EA bit stored inside the stack… even nesting counter > 0?

For XRAM copy to Stack and Stack Copy to Xram and context switching(stack pop /push) , if no method to make a "naked" function call, I need to implement both by Pure ASM code. XRAM copy to Stack and Stack Copy to Xram is not possible to use a "non-naked" functions to save/restore as the push /pop of function call would damage the restored stack of the tcb immediately after the return of the function, right?

thanks a lot .

rtel wrote on Tuesday, March 22, 2005:

>Nesting counter needed to be stored to TCB too!

The nesting counter is stored on the stack - not in the TCB.

>But nesting counter is not for restore the EA bits! All
>just depends on the EA bit stored inside the stack…
>even nesting counter > 0?

This is correct.  Both the EA bits and the nesting counter should just be restored from the stack to exactly the value they were when the context was saved.

The task that was swapped out then back in should have no knowledge that this has happened.  As far as it is concerned everything is identical.

>For XRAM copy to Stack and Stack Copy to Xram
>and context switching(stack pop /push) , if no
>method to make a "naked" function call, I need to
>implement both by Pure ASM code. XRAM copy to
>Stack and Stack Copy to Xram is not possible to use
>a "non-naked" functions to save/restore as the
>push /pop of function call would damage the restored
>stack of the tcb immediately after the return of the
>function, right?

Yes this is right.

Naked functions make life a lot easier!

rtel wrote on Tuesday, March 22, 2005:

[getting a bit confused about the order of these questions - ]

>However, the point is… is this counter should be used
>for re-enabling the interrupt bit(EA) (for example
>checking the nesting counter at the end of context
>switching, if =0 , reenable the EA)

The counter and the EA bit should be restored exactly to their values as per when they were saved.  You do not need to check the nesting counter during a restore.  This is as per the other ports.

>The next question is that, for those XRAM to STACK/
>STACK to XRAM copying macro used in 8051 port.
>It seems that if I try to modify it to use as FUNCTION
>CALL, this would make the 8051 to push its
>PC /other register which … for example during copy
>stack from XRAM… restoring the stack… but after the
>XRAM to STACK function returns… the “RET” would
>damge the whole STACK pointer’s location…

This is correct.

Without the naked attribute (or _task, or _naked, whatever) a function call will modify the stack, so the stack would get modified before you saved it.

This >might< be ok as the stack->xram and xram->stack functions have a similar stack frame, but without being able to try it myself I would say it was very dangerous and asm would be safe.

nobody wrote on Tuesday, March 22, 2005:

Thank you for your answer :slight_smile: RichardBarry.
I would resume this painful task tomorrow morning.

Thanks a lot for your help!