----- Ursprüngliche Nachricht -----
Von: Sergio Campamá
Gesendet am: 07 Dez 2011 03:33:31

> Hey, maybe I'm straying a bit from the conversation, but 

Yes. A little bit. :)
So I took the freedom to change the topic a little bit too :)

> 1. Is there a way to obtain (and set) the registers? I want to try a feature 
> where I create preemptive "threads", in which after 
> certain interrupts, I will save the current context (registers) and the 
> instruction line I was executing (which is already in the 
> registers, the PC), and start executing from another address.. And when I'm 
> done with that, reload the PC and all the other 
> registers and resume working on that "thread"… I'm guessing that  8 * 16 = 
> 128 bytes would be the least memory I would need 
> for each context save. Is it not?

You can use inline assembly to do so. The GCC inline assembler
is very powerful and allows a tight integration of assembly code into C code.
It isn't that easy to learn, as this C/ASM connection requires to learn about
how to tell the compiler about used/altered/clobbered variables and registers.
But without this, you'll run into problems about the current register states
(used for temporary values, register variables, whatever)

I wrote a multitasker myself some time ago (based on the RTC timer of the 
MSP430F5438)
I use a separate stack for each thread, because this is the only way to allow
real task switching, sleeping tasks etc.
Remember, the threads will have more than just the pushed register on its stack 
when
you switch. If you re-use the same stack, then when you swith from thread 2 to 
1,
thread 1 will have return addresses or local variables of thread 2 on top of 
the stack,
which surely isn't what anyone would expect or could handle.
And saving the complete stack history onf one thread into a struct is
basically the same as switching the stack to a new memory location.
We have unified memory, so the stack can be anywhere in writable memory.
Even inside the 'struct'.

So for each nrew thread I reserve a block of n bytes for the new stack 
(definable from
the function that spawns the new thread), plus some bytes for guard values
on both ends (to detect a stack over/undeflow, which will kill the thread),
chaining info (the areas are daisy-chained), sleep state and wakeup event flags 
etc.
And the stack pointer.

When the interrupt for the thread switch comes, I simply store all registers
except PC and SP (SR is already on the stack from ISR entry) on the stack,
load the SP form the new active thread, and pop the registers (from the
new threads stack whcih is immediately active after restorign SP).
The thread setup is a bit complicated, but the thread switch is extremely fast,
especially since you can use the POPX instructions for pushing/popping
all 12 registers with one instruction in 14 cycles and 4 bytes code.

The whole thing is written in inline assembly (the ISR is "naked").

However, nested interrupts are tricky then - a thread switch will
also put any interrupted ISR 'on-hold' until the context is switched
back again.

> 2. Where can I find tutorials or more info to read about custom linking 
> scripts? 

Good question. I'd like to know too. My linker script experience is based
100% on analysis of existing scripts.

> I also want to try a feature where I have a base 
> system setup and a special memory area reserved for a module, and when the 
> base system receives a new module (with a 
> flash memory proxy or whatever), it replaces the old one… I'm assuming the 
> entry point for that module would have to be the 
> same function name and the same memory address (is it not?)

That's relatively easy. The linker script defines sections. Name, purpose, 
begin and length.
You can alter begin and (or only) length of the existing sextions and
add your own one filling the gap.

Next is that you need to add an instruction to move code/variables for compiler 
segment 'x'
into linker section 'y'.

Last step is that you need to tell the compiler that a specific variable or 
code shall be placed into
compiler segment 'x' instead of the default '.text' etc.
Just like you do it for variables that shall be end up in uninitialized 
variable space or INFO segment
or code for lower/upper flash.
Only that you use the segment name(s) you 'defined' in the linker script 
instruction you created.

JMGross


------------------------------------------------------------------------------
Cloud Services Checklist: Pricing and Packaging Optimization
This white paper is intended to serve as a reference, checklist and point of 
discussion for anyone considering optimizing the pricing and packaging model 
of a cloud services business. Read Now!
http://www.accelacomm.com/jaw/sfnl/114/51491232/
_______________________________________________
Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mspgcc-users

Reply via email to