Dependents: rtest LeonardoMbos OS_test Labo_TRSE_Drone ... more
mbos_asm.s
- Committer:
- AndrewL
- Date:
- 2012-01-09
- Revision:
- 6:cf660b28b2a4
- Parent:
- 0:1dafafe7d505
File content as of revision 6:cf660b28b2a4:
;*********************************************************************************** ; 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