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