Wow JM, thanks a lot!

I'll try fidgeting with these concepts when I have the chance… My main worry 
about having multiple stacks is detecting if I have enough memory to "allocate" 
a new stack, and overflow/underflow problems… I tried to solve this by having a 
defined number of available threads, and allocate space for them on RAM 
statically in C structs. How can I dimension the required stack size for the 
thread? Just trial and error?

Best of luck...
---------------------------------------
Sergio Campamá
sergiocamp...@gmail.com




On Dec 8, 2011, at 10:19 AM, JMGross wrote:

> ----- 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