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