Hi all, I am working on a small RTOS for MSP430. It should just provide scheduler with ability to switch and change context.... Of course I have system tick ISR which is handling ticks. And here is the thing...When I take a look in disassembly, it says that before msp430 enters system tick ISR it pushes registers R15,R14,R13 and R12(and of course PC and SR) on stack. So I used that for context switching....At the beginning of the ISR I just save SP in TCB of interrupted Task so I could later restore it just by changing SP(changing stacks) and popping from stack. But what will happen if I have code like this in my task routine ? ///////////////////////////// unsigned int j,i,k,q,m; for(i=1;i<0x8;i++){ for(k=1;k<0x7;k++){ for(q=1;q<0x7;q++){ for(m=1;m<0x7;m++){ for(j=1;j<0x7;j++){} } } } } ////////////////////////// Variables j,i,k,q and m will be saved in R15,R14,R13,R12 (these registers are pushed on stack before entering ISR) and one more register, say R10 which is not pushed on stack. Now my question is how come R10(and other registers) is not pushed on stack before entering ISR???? Obviously I will have to add that register (and maybe all of them) to stack if I want my context to be restored as it was..... Am I right? Does that mean that any RTOS has limitation about task routine complexity , in terms of ability of saving context properly? What do you people think which is better, saving context on stack or in task's TCB??? Thanks in advance ! p.s Sorry about my english if there are mistakes:) --------------------------------------- This message was sent using the comp.arch.embedded web interface on http://www.EmbeddedRelated.com
switching context on MSP430
Started by ●September 29, 2009
Reply by ●October 1, 20092009-10-01
"brOS" <bogdanrosandic@gmail.com> wrote in message news:7LadnQ-gzYu8i1_XnZ2dnUVZ_vydnZ2d@giganews.com...> Hi all, > > I am working on a small RTOS for MSP430. It should just provide scheduler > with ability to switch and change context.... Of course I have system tick > ISR which is handling ticks. And here is the thing...When I take a look in > disassembly, it says that before msp430 enters system tick ISR it pushes > registers R15,R14,R13 and R12(and of course PC and SR) on stack. So I used > that for context switching....At the beginning of the ISR I just save SP > in TCB of interrupted Task so I could later restore it just by changing > SP(changing stacks) and popping from stack. But what will happen if I have > code like this in my task routine ? > ///////////////////////////// > unsigned int j,i,k,q,m; > > for(i=1;i<0x8;i++){ > for(k=1;k<0x7;k++){ > for(q=1;q<0x7;q++){ > for(m=1;m<0x7;m++){ > for(j=1;j<0x7;j++){} > } > } > } > } > ////////////////////////// > Variables j,i,k,q and m will be saved in R15,R14,R13,R12 (these registers > are pushed on stack before entering ISR) and one more register, say R10 > which is not pushed on stack. Now my question is how come R10(and other > registers) is not pushed on stack before entering ISR???? > Obviously I will have to add that register (and maybe all of them) to > stack > if I want my context to be restored as it was..... Am I right? > > Does that mean that any RTOS has limitation about task routine complexity > , > in terms of ability of saving context properly? > > What do you people think which is better, saving context on stack or in > task's TCB??? > > Thanks in advance ! > > p.s Sorry about my english if there are mistakes:) > > --------------------------------------- > This message was sent using the comp.arch.embedded web interface on > http://www.EmbeddedRelated.comThere are generally two cases where you save the context of registers, but essentially only one reason. You save the context of the registers because you want to be able to restore them and you have to save them because they are potentially going to be trashed by the ISR code. The two cases of save and restore of context are on ISR entry/exit and pre-emptive task switching. So the standard entry routine of an ISR will save the registers that are going to be over-written by the ISR code. In theory, you only need to save the registers that have the potential to be changed because all of the other registers will remain intact. By only preserving the registers that are going to be used in your ISR, you greatly speed up entry to the ISR and thereby reduce interrupt latency and in the case of high frequency ISRs you will also affect overall system performance. In a non-pre-emptive system, generally the context would be restored by the ISR as it exits and the system would go back to where it was previously. Those registers that were trampled on by the ISR would be restored and the program would continue as if nothing had happened other than the progress of time. The event of the ISR will have been injected into the system and dealt with at some later point. When you move on from the standard context save and restore of an ISR and into the realm of pre-emptive task switching, you open up a whole new world (of pain). You could constrain your entire application code to using local variables and use compiler and assembler directives to prevent registers from ever being used. This would reduce the context that was required to be saved and restored, but could seriously affect the performance of your application. In most pre-emptive systems, tasks maintain their own stack linked to the TCB and the context can be safely saved and forgotten about. My opinion is that your ISR should save and restore as little as possible so that your latency and performance are as good as possible. Your scheduler however should save and restore as much context as is practicable to make each task as free as possible to do the job in hand. In the code example you have given, if the ISR does not use R10, then there is no need to save and restore it because it will still be whatever it was when the ISR exits. However, if ANY task based code ANYWHERE in your system uses R10 as you have shown, then you will need to save it and restore it in your task stack (or force your entire application not to use R10) The bottom line is that you only need to save and restore what might be trashed between pre-emption and return. In the case of an ISR you only need to save and restore what you know your ISR uses. In the case of your task being pre-empted, you need to save and restore what any other task in the system might trash.