Quick and dirty port of scmRTOS demo to mbed 1768. scmRTOS is a small RTOS written using C++. Offers (static) processes, critical sections, mutexes, messages, channels.
scmRTOS/CortexM3/OS_Target_asm.s@0:a405220cf420, 2010-09-09 (annotated)
- Committer:
- igorsk
- Date:
- Thu Sep 09 21:19:01 2010 +0000
- Revision:
- 0:a405220cf420
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
igorsk | 0:a405220cf420 | 1 | ; ****************************************************************************** |
igorsk | 0:a405220cf420 | 2 | ; * |
igorsk | 0:a405220cf420 | 3 | ; * FULLNAME: Single-Chip Microcontroller Real-Time Operating System |
igorsk | 0:a405220cf420 | 4 | ; * |
igorsk | 0:a405220cf420 | 5 | ; * NICKNAME: scmRTOS |
igorsk | 0:a405220cf420 | 6 | ; * |
igorsk | 0:a405220cf420 | 7 | ; * PROCESSOR: ARM Cortex-M3 |
igorsk | 0:a405220cf420 | 8 | ; * |
igorsk | 0:a405220cf420 | 9 | ; * TOOLKIT: EWARM (IAR Systems) |
igorsk | 0:a405220cf420 | 10 | ; * |
igorsk | 0:a405220cf420 | 11 | ; * PURPOSE: Target Dependent Low-Level Stuff |
igorsk | 0:a405220cf420 | 12 | ; * |
igorsk | 0:a405220cf420 | 13 | ; * Version: 3.10 |
igorsk | 0:a405220cf420 | 14 | ; * |
igorsk | 0:a405220cf420 | 15 | ; * $Revision: 195 $ |
igorsk | 0:a405220cf420 | 16 | ; * $Date:: 2008-06-19 #$ |
igorsk | 0:a405220cf420 | 17 | ; * |
igorsk | 0:a405220cf420 | 18 | ; * Copyright (c) 2003-2010, Harry E. Zhurov |
igorsk | 0:a405220cf420 | 19 | ; * |
igorsk | 0:a405220cf420 | 20 | ; * Permission is hereby granted, free of charge, to any person |
igorsk | 0:a405220cf420 | 21 | ; * obtaining a copy of this software and associated documentation |
igorsk | 0:a405220cf420 | 22 | ; * files (the "Software"), to deal in the Software without restriction, |
igorsk | 0:a405220cf420 | 23 | ; * including without limitation the rights to use, copy, modify, merge, |
igorsk | 0:a405220cf420 | 24 | ; * publish, distribute, sublicense, and/or sell copies of the Software, |
igorsk | 0:a405220cf420 | 25 | ; * and to permit persons to whom the Software is furnished to do so, |
igorsk | 0:a405220cf420 | 26 | ; * subject to the following conditions: |
igorsk | 0:a405220cf420 | 27 | ; * |
igorsk | 0:a405220cf420 | 28 | ; * The above copyright notice and this permission notice shall be included |
igorsk | 0:a405220cf420 | 29 | ; * in all copies or substantial portions of the Software. |
igorsk | 0:a405220cf420 | 30 | ; * |
igorsk | 0:a405220cf420 | 31 | ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
igorsk | 0:a405220cf420 | 32 | ; * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
igorsk | 0:a405220cf420 | 33 | ; * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
igorsk | 0:a405220cf420 | 34 | ; * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
igorsk | 0:a405220cf420 | 35 | ; * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
igorsk | 0:a405220cf420 | 36 | ; * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH |
igorsk | 0:a405220cf420 | 37 | ; * THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
igorsk | 0:a405220cf420 | 38 | ; * |
igorsk | 0:a405220cf420 | 39 | ; * ================================================================= |
igorsk | 0:a405220cf420 | 40 | ; * See http://scmrtos.sourceforge.net for documentation, latest |
igorsk | 0:a405220cf420 | 41 | ; * information, license and contact details. |
igorsk | 0:a405220cf420 | 42 | ; * ================================================================= |
igorsk | 0:a405220cf420 | 43 | ; * |
igorsk | 0:a405220cf420 | 44 | ; ****************************************************************************** |
igorsk | 0:a405220cf420 | 45 | ; * Ported by Andrey Chuikin, Copyright (c) 2008-2010 |
igorsk | 0:a405220cf420 | 46 | |
igorsk | 0:a405220cf420 | 47 | ; #include "scmRTOS_TARGET_CFG.h" |
igorsk | 0:a405220cf420 | 48 | |
igorsk | 0:a405220cf420 | 49 | ; ----------------------------------------------------------------------------- |
igorsk | 0:a405220cf420 | 50 | ; PUBLIC FUNCTIONS |
igorsk | 0:a405220cf420 | 51 | ; |
igorsk | 0:a405220cf420 | 52 | EXTERN OS_ContextSwitchHook |
igorsk | 0:a405220cf420 | 53 | |
igorsk | 0:a405220cf420 | 54 | EXPORT OS_Start |
igorsk | 0:a405220cf420 | 55 | EXPORT PendSV_Handler |
igorsk | 0:a405220cf420 | 56 | |
igorsk | 0:a405220cf420 | 57 | ; ----------------------------------------------------------------------------- |
igorsk | 0:a405220cf420 | 58 | ; EQUATES |
igorsk | 0:a405220cf420 | 59 | ; |
igorsk | 0:a405220cf420 | 60 | NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt control state register. |
igorsk | 0:a405220cf420 | 61 | NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception. |
igorsk | 0:a405220cf420 | 62 | |
igorsk | 0:a405220cf420 | 63 | NVIC_SYSPRI14 EQU 0xE000ED22 ; System priority register (priority 14). |
igorsk | 0:a405220cf420 | 64 | NVIC_PENDSV_PRI EQU 0xFF ; PendSV priority value (lowest). |
igorsk | 0:a405220cf420 | 65 | NVIC_SYSPRI15 EQU 0xE000ED23 ; System priority register (priority 15). |
igorsk | 0:a405220cf420 | 66 | NVIC_ST_PRI EQU 0xFF ; SysTick priority value (lowest). |
igorsk | 0:a405220cf420 | 67 | |
igorsk | 0:a405220cf420 | 68 | NVIC_ST_CTRL EQU 0xE000E010 ; SysTick Ctrl & Status Reg. |
igorsk | 0:a405220cf420 | 69 | NVIC_ST_RELOAD EQU 0xE000E014 ; SysTick Reload Value Reg. |
igorsk | 0:a405220cf420 | 70 | NVIC_ST_CTRL_CLK_SRC EQU 0x00000004 ; Clock Source. |
igorsk | 0:a405220cf420 | 71 | NVIC_ST_CTRL_INTEN EQU 0x00000002 ; Interrupt enable. |
igorsk | 0:a405220cf420 | 72 | NVIC_ST_CTRL_ENABLE EQU 0x00000001 ; Counter mode. |
igorsk | 0:a405220cf420 | 73 | |
igorsk | 0:a405220cf420 | 74 | ; should be the same as in scmRTOS_TARGET_CFG.h |
igorsk | 0:a405220cf420 | 75 | SYSTICKFREQ EQU 100000000 |
igorsk | 0:a405220cf420 | 76 | SYSTICKINTRATE EQU 1000 |
igorsk | 0:a405220cf420 | 77 | |
igorsk | 0:a405220cf420 | 78 | ; ----------------------------------------------------------------------------- |
igorsk | 0:a405220cf420 | 79 | ; CODE GENERATION DIRECTIVES |
igorsk | 0:a405220cf420 | 80 | ; |
igorsk | 0:a405220cf420 | 81 | AREA TEXT, CODE, READONLY |
igorsk | 0:a405220cf420 | 82 | THUMB |
igorsk | 0:a405220cf420 | 83 | |
igorsk | 0:a405220cf420 | 84 | ; ----------------------------------------------------------------------------- |
igorsk | 0:a405220cf420 | 85 | ; HANDLE PendSV EXCEPTION |
igorsk | 0:a405220cf420 | 86 | ; void PendSV_Handler(void) |
igorsk | 0:a405220cf420 | 87 | ; |
igorsk | 0:a405220cf420 | 88 | ; Note(s) : 1) PendSV is used to cause a context switch. This is a recommended method for performing |
igorsk | 0:a405220cf420 | 89 | ; context switches with Cortex-M3. This is because the Cortex-M3 auto-saves half of the |
igorsk | 0:a405220cf420 | 90 | ; processor context on any exception, and restores same on return from exception. So only |
igorsk | 0:a405220cf420 | 91 | ; saving of R4-R11 is required and fixing up the stack pointers. Using the PendSV exception |
igorsk | 0:a405220cf420 | 92 | ; this way means that context saving and restoring is identical whether it is initiated from |
igorsk | 0:a405220cf420 | 93 | ; a thread or occurs due to an interrupt or exception. |
igorsk | 0:a405220cf420 | 94 | ; |
igorsk | 0:a405220cf420 | 95 | ; 2) Pseudo-code is: |
igorsk | 0:a405220cf420 | 96 | ; a) Get the process SP, if 0 then skip (goto f) the saving part (first context switch); |
igorsk | 0:a405220cf420 | 97 | ; b) Save remaining regs r4-r11 on process stack; |
igorsk | 0:a405220cf420 | 98 | ; c) Call OS_ContextSwitchHook for save current task SP and get new task SP; |
igorsk | 0:a405220cf420 | 99 | ; d) Restore R4-R11 from new process stack; |
igorsk | 0:a405220cf420 | 100 | ; e) Perform exception return which will restore remaining context. |
igorsk | 0:a405220cf420 | 101 | ; f) Get SP for the first context switch (R2 hold it); |
igorsk | 0:a405220cf420 | 102 | ; run SysTick; goto d); |
igorsk | 0:a405220cf420 | 103 | ; |
igorsk | 0:a405220cf420 | 104 | ; 3) On entry into PendSV handler: |
igorsk | 0:a405220cf420 | 105 | ; a) The following have been saved on the process stack (by processor): |
igorsk | 0:a405220cf420 | 106 | ; xPSR, PC, LR, R12, R0-R3 |
igorsk | 0:a405220cf420 | 107 | ; b) Processor mode is switched to Handler mode (from Thread mode) |
igorsk | 0:a405220cf420 | 108 | ; c) Stack is Main stack (switched from Process stack) |
igorsk | 0:a405220cf420 | 109 | ; |
igorsk | 0:a405220cf420 | 110 | ; 4) Since PendSV is set to lowest priority in the system (by OS_Start() below), we |
igorsk | 0:a405220cf420 | 111 | ; know that it will only be run when no other exception or interrupt is active, and |
igorsk | 0:a405220cf420 | 112 | ; therefore safe to assume that context being switched out was using the process stack (PSP). |
igorsk | 0:a405220cf420 | 113 | ; |
igorsk | 0:a405220cf420 | 114 | PendSV_Handler |
igorsk | 0:a405220cf420 | 115 | CPSID I ; Prevent interruption during context switch |
igorsk | 0:a405220cf420 | 116 | MRS R0, PSP ; PSP is process stack pointer |
igorsk | 0:a405220cf420 | 117 | CBZ R0, nosave ; Skip register save the first time |
igorsk | 0:a405220cf420 | 118 | |
igorsk | 0:a405220cf420 | 119 | STMDB R0!, {R4-R11} ; Save remaining regs r4-11 on process stack |
igorsk | 0:a405220cf420 | 120 | ; At this point, entire context of process has been saved |
igorsk | 0:a405220cf420 | 121 | |
igorsk | 0:a405220cf420 | 122 | PUSH {R14} ; Save LR exc_return value |
igorsk | 0:a405220cf420 | 123 | LDR R1, =OS_ContextSwitchHook ; OS_ContextSwitchHook(); |
igorsk | 0:a405220cf420 | 124 | BLX R1 |
igorsk | 0:a405220cf420 | 125 | POP {R14} |
igorsk | 0:a405220cf420 | 126 | |
igorsk | 0:a405220cf420 | 127 | ContextRestore |
igorsk | 0:a405220cf420 | 128 | ; R0 is new process SP; |
igorsk | 0:a405220cf420 | 129 | LDMIA R0!, {R4-R11} ; Restore r4-11 from new process stack |
igorsk | 0:a405220cf420 | 130 | MSR PSP, R0 ; Load PSP with new process SP |
igorsk | 0:a405220cf420 | 131 | ORR LR, LR, #0x04 ; Ensure exception return uses process stack |
igorsk | 0:a405220cf420 | 132 | CPSIE I |
igorsk | 0:a405220cf420 | 133 | BX LR ; Exception return will restore remaining context |
igorsk | 0:a405220cf420 | 134 | nosave |
igorsk | 0:a405220cf420 | 135 | MOV R0, R2 ; R2 hold the first task SP |
igorsk | 0:a405220cf420 | 136 | |
igorsk | 0:a405220cf420 | 137 | LDR R1, =NVIC_ST_CTRL ; Enable and run SysTick |
igorsk | 0:a405220cf420 | 138 | LDR R2, =(NVIC_ST_CTRL_CLK_SRC | NVIC_ST_CTRL_INTEN | NVIC_ST_CTRL_ENABLE) |
igorsk | 0:a405220cf420 | 139 | STR R2, [R1] |
igorsk | 0:a405220cf420 | 140 | |
igorsk | 0:a405220cf420 | 141 | B ContextRestore |
igorsk | 0:a405220cf420 | 142 | |
igorsk | 0:a405220cf420 | 143 | |
igorsk | 0:a405220cf420 | 144 | ; ----------------------------------------------------------------------------- |
igorsk | 0:a405220cf420 | 145 | ; START MULTITASKING |
igorsk | 0:a405220cf420 | 146 | ; void OS_Start(TStackItem* sp) |
igorsk | 0:a405220cf420 | 147 | ; |
igorsk | 0:a405220cf420 | 148 | ; Note(s) : 1) OS_Start() MUST: |
igorsk | 0:a405220cf420 | 149 | ; a) Setup PendSV and SysTick exception priority to lowest; |
igorsk | 0:a405220cf420 | 150 | ; b) Setup SysTick (reload value); |
igorsk | 0:a405220cf420 | 151 | ; c) Enable interrupts (tasks will run with interrupts enabled). |
igorsk | 0:a405220cf420 | 152 | ; |
igorsk | 0:a405220cf420 | 153 | OS_Start |
igorsk | 0:a405220cf420 | 154 | LDR R1, =NVIC_SYSPRI14 ; Set the PendSV exception priority (lowest) |
igorsk | 0:a405220cf420 | 155 | LDR R2, =NVIC_PENDSV_PRI |
igorsk | 0:a405220cf420 | 156 | STRB R2, [R1] |
igorsk | 0:a405220cf420 | 157 | LDR R1, =NVIC_SYSPRI15 ; Set the SysTick exception priority (lowest) |
igorsk | 0:a405220cf420 | 158 | LDR R2, =NVIC_ST_PRI |
igorsk | 0:a405220cf420 | 159 | STRB R2, [R1] |
igorsk | 0:a405220cf420 | 160 | |
igorsk | 0:a405220cf420 | 161 | LDR R1, =NVIC_ST_RELOAD ; Setup SysTick |
igorsk | 0:a405220cf420 | 162 | LDR R2, =(SYSTICKFREQ/SYSTICKINTRATE-1) |
igorsk | 0:a405220cf420 | 163 | STR R2, [R1] |
igorsk | 0:a405220cf420 | 164 | |
igorsk | 0:a405220cf420 | 165 | MOV R2, R0 ; Save the first task stack |
igorsk | 0:a405220cf420 | 166 | MOVS R0, #0 ; Set the PSP to 0 for initial context switch call |
igorsk | 0:a405220cf420 | 167 | MSR PSP, R0 |
igorsk | 0:a405220cf420 | 168 | |
igorsk | 0:a405220cf420 | 169 | LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch) |
igorsk | 0:a405220cf420 | 170 | LDR R1, =NVIC_PENDSVSET |
igorsk | 0:a405220cf420 | 171 | STR R1, [R0] |
igorsk | 0:a405220cf420 | 172 | |
igorsk | 0:a405220cf420 | 173 | CPSIE I ; Enable interrupts at processor level |
igorsk | 0:a405220cf420 | 174 | loop |
igorsk | 0:a405220cf420 | 175 | B loop ; Should never get here |
igorsk | 0:a405220cf420 | 176 | |
igorsk | 0:a405220cf420 | 177 | |
igorsk | 0:a405220cf420 | 178 | END |