Testing [Andrew L] mbos RTOS for mbed Simply by copying code for main.cpp from mbos.h-comments
mbos_asm.s
- Committer:
- chalikias
- Date:
- 2011-05-05
- Revision:
- 0:a61d29450691
File content as of revision 0:a61d29450691:
;***********************************************************************************
; 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