Testing [Andrew L] mbos RTOS for mbed Simply by copying code for main.cpp from mbos.h-comments

Dependencies:   mbed

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