Dependents:   rtest LeonardoMbos OS_test Labo_TRSE_Drone ... more

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?

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