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