Dependents: rtest LeonardoMbos OS_test Labo_TRSE_Drone ... more
mbos_asm.s@6:cf660b28b2a4, 2012-01-09 (annotated)
- Committer:
- AndrewL
- Date:
- Mon Jan 09 03:11:46 2012 +0000
- Revision:
- 6:cf660b28b2a4
- Parent:
- 0:1dafafe7d505
Fixed error relating to timer events posted to tasks that are not waiting
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AndrewL | 0:1dafafe7d505 | 1 | ;*********************************************************************************** |
AndrewL | 0:1dafafe7d505 | 2 | ; m b o s R T O S F O R m b e d (ARM CORTEX M3) |
AndrewL | 0:1dafafe7d505 | 3 | ; |
AndrewL | 0:1dafafe7d505 | 4 | ; Copyright (c) 2010 - 2011 Andrew Levido |
AndrewL | 0:1dafafe7d505 | 5 | ; |
AndrewL | 0:1dafafe7d505 | 6 | ; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED |
AndrewL | 0:1dafafe7d505 | 7 | ; WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
AndrewL | 0:1dafafe7d505 | 8 | ; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT |
AndrewL | 0:1dafafe7d505 | 9 | ; SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
AndrewL | 0:1dafafe7d505 | 10 | ; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT |
AndrewL | 0:1dafafe7d505 | 11 | ; OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
AndrewL | 0:1dafafe7d505 | 12 | ; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
AndrewL | 0:1dafafe7d505 | 13 | ; STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
AndrewL | 0:1dafafe7d505 | 14 | ; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
AndrewL | 0:1dafafe7d505 | 15 | |
AndrewL | 0:1dafafe7d505 | 16 | EXPORT _startos |
AndrewL | 0:1dafafe7d505 | 17 | EXPORT SVC_Handler |
AndrewL | 0:1dafafe7d505 | 18 | EXPORT PendSV_Handler |
AndrewL | 0:1dafafe7d505 | 19 | EXPORT _swap |
AndrewL | 0:1dafafe7d505 | 20 | |
AndrewL | 0:1dafafe7d505 | 21 | EXTERN _tasklist |
AndrewL | 0:1dafafe7d505 | 22 | EXTERN _tasklistsize |
AndrewL | 0:1dafafe7d505 | 23 | EXTERN _stackerror |
AndrewL | 0:1dafafe7d505 | 24 | EXTERN _hardstacklimit |
AndrewL | 0:1dafafe7d505 | 25 | |
AndrewL | 0:1dafafe7d505 | 26 | ID_OFFSET equ 0 ; 0 word (0byte) offset |
AndrewL | 0:1dafafe7d505 | 27 | STACK_OFFSET equ 4 ; 1 word (4byte) offset |
AndrewL | 0:1dafafe7d505 | 28 | PRIO_OFFSET equ 8 ; 2 word (8byte) offset |
AndrewL | 0:1dafafe7d505 | 29 | LIMIT_OFFSET equ 20 ; 5 word (20byte) offset |
AndrewL | 0:1dafafe7d505 | 30 | |
AndrewL | 0:1dafafe7d505 | 31 | AREA |.text|, CODE, READONLY, ALIGN=3 |
AndrewL | 0:1dafafe7d505 | 32 | PRESERVE8 |
AndrewL | 0:1dafafe7d505 | 33 | |
AndrewL | 0:1dafafe7d505 | 34 | ; Function to invoke an SVC exception to start 1st task ---------------------------------- |
AndrewL | 0:1dafafe7d505 | 35 | _startos |
AndrewL | 0:1dafafe7d505 | 36 | svc 0 ; Initiate a system call to start the first task |
AndrewL | 0:1dafafe7d505 | 37 | bx lr ; Return (should never happen!) |
AndrewL | 0:1dafafe7d505 | 38 | ALIGN |
AndrewL | 0:1dafafe7d505 | 39 | |
AndrewL | 0:1dafafe7d505 | 40 | ; Function to initiate a SetPend Exception to swap tasks --------------------------------- |
AndrewL | 0:1dafafe7d505 | 41 | _swap |
AndrewL | 0:1dafafe7d505 | 42 | mov r0, #0xe000e000 ; Base address of ICSR |
AndrewL | 0:1dafafe7d505 | 43 | ldr r1, [r0, #0x0d04] ; Read ICSR |
AndrewL | 0:1dafafe7d505 | 44 | orr r1, #0x10000000 ; Set setPend bit |
AndrewL | 0:1dafafe7d505 | 45 | str r1, [r0, #0xd04] ; write back to ICSR |
AndrewL | 0:1dafafe7d505 | 46 | bx lr |
AndrewL | 0:1dafafe7d505 | 47 | ALIGN |
AndrewL | 0:1dafafe7d505 | 48 | |
AndrewL | 0:1dafafe7d505 | 49 | ; Main task switching and scheduling functions ------------------------------------------- |
AndrewL | 0:1dafafe7d505 | 50 | PendSV_Handler ; entered here as handler for context switch |
AndrewL | 0:1dafafe7d505 | 51 | cpsid i ; disable interrupts |
AndrewL | 0:1dafafe7d505 | 52 | ; save context of running task (that not saved by exception entry) |
AndrewL | 0:1dafafe7d505 | 53 | mrs r0, msp |
AndrewL | 0:1dafafe7d505 | 54 | stmdb r0!, {r4-r11} |
AndrewL | 0:1dafafe7d505 | 55 | ; store the sp in the tcb |
AndrewL | 0:1dafafe7d505 | 56 | ldr r1, =_tasklist |
AndrewL | 0:1dafafe7d505 | 57 | ldr r1, [r1] |
AndrewL | 0:1dafafe7d505 | 58 | ldr r1, [r1] |
AndrewL | 0:1dafafe7d505 | 59 | str r0, [r1, #STACK_OFFSET] |
AndrewL | 0:1dafafe7d505 | 60 | ; check for stack overflow against task limit |
AndrewL | 0:1dafafe7d505 | 61 | ldr r2, [r1, #LIMIT_OFFSET] |
AndrewL | 0:1dafafe7d505 | 62 | cmp r0, r2 |
AndrewL | 0:1dafafe7d505 | 63 | bls stackerror |
AndrewL | 0:1dafafe7d505 | 64 | ; check for stack overflow against hard limit |
AndrewL | 0:1dafafe7d505 | 65 | ldr r2, =_hardstacklimit |
AndrewL | 0:1dafafe7d505 | 66 | ldr r2, [r2] |
AndrewL | 0:1dafafe7d505 | 67 | cmp r0, r2 |
AndrewL | 0:1dafafe7d505 | 68 | bls stackerror |
AndrewL | 0:1dafafe7d505 | 69 | SVC_Handler ; entered here as handler for 1st task start |
AndrewL | 0:1dafafe7d505 | 70 | cpsid i ; Disable interrupts |
AndrewL | 0:1dafafe7d505 | 71 | ; sort the task list |
AndrewL | 0:1dafafe7d505 | 72 | ldr r5, =_tasklist ; r5 = _tasklist[i] where i = 0 |
AndrewL | 0:1dafafe7d505 | 73 | ldr r5, [r5] |
AndrewL | 0:1dafafe7d505 | 74 | ldr r9, =_tasklistsize ; byte offset of last item in tasklist |
AndrewL | 0:1dafafe7d505 | 75 | ldr r9, [r9] |
AndrewL | 0:1dafafe7d505 | 76 | add r9, r5 ; outer loop limit |
AndrewL | 0:1dafafe7d505 | 77 | sub r10, r9, #4 ; inner loop limit |
AndrewL | 0:1dafafe7d505 | 78 | outerloop |
AndrewL | 0:1dafafe7d505 | 79 | ldr r1, [r5] ; r8 = _tasklist[i]->priostate |
AndrewL | 0:1dafafe7d505 | 80 | ldr r8, [r1, #PRIO_OFFSET] |
AndrewL | 0:1dafafe7d505 | 81 | mov r7, r5 ; k = i |
AndrewL | 0:1dafafe7d505 | 82 | add r6, r5, #4 ; j = i + 1 |
AndrewL | 0:1dafafe7d505 | 83 | innerloop |
AndrewL | 0:1dafafe7d505 | 84 | ldr r0, [r6] ; r0 = _tasklist[j]->priostate |
AndrewL | 0:1dafafe7d505 | 85 | ldr r0, [r0, #PRIO_OFFSET] |
AndrewL | 0:1dafafe7d505 | 86 | cmp r0, r8 ; r0 - r8 |
AndrewL | 0:1dafafe7d505 | 87 | bcc innerlooptest ; branch if r8 higher |
AndrewL | 0:1dafafe7d505 | 88 | ; found bigger or same! |
AndrewL | 0:1dafafe7d505 | 89 | mov r7, r6 ; k = j |
AndrewL | 0:1dafafe7d505 | 90 | mov r8, r0 ; r8 = _tasklist[j]->priostate |
AndrewL | 0:1dafafe7d505 | 91 | innerlooptest |
AndrewL | 0:1dafafe7d505 | 92 | add r6, #4 ; j++ |
AndrewL | 0:1dafafe7d505 | 93 | cmp r6, r9 ; r6 - r9 (j - inner limit) |
AndrewL | 0:1dafafe7d505 | 94 | bls innerloop ; branch if r9 lower or same |
AndrewL | 0:1dafafe7d505 | 95 | ; swap |
AndrewL | 0:1dafafe7d505 | 96 | ldr r0, [r5] |
AndrewL | 0:1dafafe7d505 | 97 | ldr r1, [r7] |
AndrewL | 0:1dafafe7d505 | 98 | str r1, [r5] |
AndrewL | 0:1dafafe7d505 | 99 | str r0, [r7] |
AndrewL | 0:1dafafe7d505 | 100 | outerlooptest |
AndrewL | 0:1dafafe7d505 | 101 | add r5, #4 ; i++ |
AndrewL | 0:1dafafe7d505 | 102 | cmp r5, r10 ; r5 - r10 (i - outer limit) |
AndrewL | 0:1dafafe7d505 | 103 | bls outerloop ; branch if r10 is lower or same |
AndrewL | 0:1dafafe7d505 | 104 | ; restore the context (that not restored by the exception exit) --------------------- |
AndrewL | 0:1dafafe7d505 | 105 | ldr r0, =_tasklist ; get the sp from the TCB |
AndrewL | 0:1dafafe7d505 | 106 | ldr r0, [r0] |
AndrewL | 0:1dafafe7d505 | 107 | ldr r0, [r0] |
AndrewL | 0:1dafafe7d505 | 108 | ldr r0, [r0, #STACK_OFFSET] |
AndrewL | 0:1dafafe7d505 | 109 | ldmia r0!,{r4-r11} ; pop the stack |
AndrewL | 0:1dafafe7d505 | 110 | msr msp, r0 ; and put the sp away |
AndrewL | 0:1dafafe7d505 | 111 | cpsie i ; re-enable interrupts |
AndrewL | 0:1dafafe7d505 | 112 | ; Force a return from exception and the restoration of the rest of the regs |
AndrewL | 0:1dafafe7d505 | 113 | bx lr |
AndrewL | 0:1dafafe7d505 | 114 | ; A stack error has occurred |
AndrewL | 0:1dafafe7d505 | 115 | stackerror |
AndrewL | 0:1dafafe7d505 | 116 | ldr r0, [r1, #ID_OFFSET] ; get id of task into r0 |
AndrewL | 0:1dafafe7d505 | 117 | bl.w _stackerror ; call the C function |
AndrewL | 0:1dafafe7d505 | 118 | _donothing |
AndrewL | 0:1dafafe7d505 | 119 | bl _donothing |
AndrewL | 0:1dafafe7d505 | 120 | ALIGN |
AndrewL | 0:1dafafe7d505 | 121 | END |