Dependents: rtest LeonardoMbos OS_test Labo_TRSE_Drone ... more
Diff: mbos_asm.s
- Revision:
- 0:1dafafe7d505
diff -r 000000000000 -r 1dafafe7d505 mbos_asm.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbos_asm.s Sat Dec 04 16:51:52 2010 +0000 @@ -0,0 +1,121 @@ +;*********************************************************************************** +; m b o s R T O S F O R m b e d (ARM CORTEX M3) +; +; Copyright (c) 2010 - 2011 Andrew Levido +; +; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED +; WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +; SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +; OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +; STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + EXPORT _startos + EXPORT SVC_Handler + EXPORT PendSV_Handler + EXPORT _swap + + EXTERN _tasklist + EXTERN _tasklistsize + EXTERN _stackerror + EXTERN _hardstacklimit + +ID_OFFSET equ 0 ; 0 word (0byte) offset +STACK_OFFSET equ 4 ; 1 word (4byte) offset +PRIO_OFFSET equ 8 ; 2 word (8byte) offset +LIMIT_OFFSET equ 20 ; 5 word (20byte) offset + + AREA |.text|, CODE, READONLY, ALIGN=3 + PRESERVE8 + +; Function to invoke an SVC exception to start 1st task ---------------------------------- +_startos + svc 0 ; Initiate a system call to start the first task + bx lr ; Return (should never happen!) + ALIGN + +; Function to initiate a SetPend Exception to swap tasks --------------------------------- +_swap + mov r0, #0xe000e000 ; Base address of ICSR + ldr r1, [r0, #0x0d04] ; Read ICSR + orr r1, #0x10000000 ; Set setPend bit + str r1, [r0, #0xd04] ; write back to ICSR + bx lr + ALIGN + +; Main task switching and scheduling functions ------------------------------------------- +PendSV_Handler ; entered here as handler for context switch + cpsid i ; disable interrupts + ; save context of running task (that not saved by exception entry) + mrs r0, msp + stmdb r0!, {r4-r11} +; store the sp in the tcb + ldr r1, =_tasklist + ldr r1, [r1] + ldr r1, [r1] + str r0, [r1, #STACK_OFFSET] +; check for stack overflow against task limit + ldr r2, [r1, #LIMIT_OFFSET] + cmp r0, r2 + bls stackerror +; check for stack overflow against hard limit + ldr r2, =_hardstacklimit + ldr r2, [r2] + cmp r0, r2 + bls stackerror +SVC_Handler ; entered here as handler for 1st task start + cpsid i ; Disable interrupts +; sort the task list + ldr r5, =_tasklist ; r5 = _tasklist[i] where i = 0 + ldr r5, [r5] + ldr r9, =_tasklistsize ; byte offset of last item in tasklist + ldr r9, [r9] + add r9, r5 ; outer loop limit + sub r10, r9, #4 ; inner loop limit +outerloop + ldr r1, [r5] ; r8 = _tasklist[i]->priostate + ldr r8, [r1, #PRIO_OFFSET] + mov r7, r5 ; k = i + add r6, r5, #4 ; j = i + 1 +innerloop + ldr r0, [r6] ; r0 = _tasklist[j]->priostate + ldr r0, [r0, #PRIO_OFFSET] + cmp r0, r8 ; r0 - r8 + bcc innerlooptest ; branch if r8 higher +; found bigger or same! + mov r7, r6 ; k = j + mov r8, r0 ; r8 = _tasklist[j]->priostate +innerlooptest + add r6, #4 ; j++ + cmp r6, r9 ; r6 - r9 (j - inner limit) + bls innerloop ; branch if r9 lower or same +; swap + ldr r0, [r5] + ldr r1, [r7] + str r1, [r5] + str r0, [r7] +outerlooptest + add r5, #4 ; i++ + cmp r5, r10 ; r5 - r10 (i - outer limit) + bls outerloop ; branch if r10 is lower or same + ; restore the context (that not restored by the exception exit) --------------------- + ldr r0, =_tasklist ; get the sp from the TCB + ldr r0, [r0] + ldr r0, [r0] + ldr r0, [r0, #STACK_OFFSET] + ldmia r0!,{r4-r11} ; pop the stack + msr msp, r0 ; and put the sp away + cpsie i ; re-enable interrupts +; Force a return from exception and the restoration of the rest of the regs + bx lr +; A stack error has occurred +stackerror + ldr r0, [r1, #ID_OFFSET] ; get id of task into r0 + bl.w _stackerror ; call the C function +_donothing + bl _donothing + ALIGN + END \ No newline at end of file