Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
HAL_CM1.c
00001 /** 00002 * @file HAL_CM1.c 00003 * @brief HAL for Cortex-M0(p) 00004 * 00005 * DAPLink Interface Firmware 00006 * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved 00007 * SPDX-License-Identifier: Apache-2.0 00008 * 00009 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00010 * not use this file except in compliance with the License. 00011 * You may obtain a copy of the License at 00012 * 00013 * http://www.apache.org/licenses/LICENSE-2.0 00014 * 00015 * Unless required by applicable law or agreed to in writing, software 00016 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00017 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00018 * See the License for the specific language governing permissions and 00019 * limitations under the License. 00020 */ 00021 00022 #include "rt_TypeDef.h" 00023 #include "RTX_Config.h" 00024 #include "rt_System.h" 00025 #include "rt_HAL_CM.h" 00026 #include "rt_Task.h" 00027 #include "rt_List.h" 00028 #include "rt_MemBox.h" 00029 00030 00031 /*---------------------------------------------------------------------------- 00032 * Functions 00033 *---------------------------------------------------------------------------*/ 00034 00035 00036 /*--------------------------- rt_set_PSP ------------------------------------*/ 00037 00038 __asm void rt_set_PSP (U32 stack) { 00039 MSR PSP,R0 00040 BX LR 00041 } 00042 00043 00044 /*--------------------------- rt_get_PSP ------------------------------------*/ 00045 00046 __asm U32 rt_get_PSP (void) { 00047 MRS R0,PSP 00048 BX LR 00049 } 00050 00051 00052 /*--------------------------- os_set_env ------------------------------------*/ 00053 00054 __asm void os_set_env (void) { 00055 /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ 00056 MOV R0,SP ; PSP = MSP 00057 MSR PSP,R0 00058 LDR R0,=__cpp(&os_flags) 00059 LDRB R0,[R0] 00060 LSLS R0,#31 00061 BNE PrivilegedE 00062 MOVS R0,#0x03 ; Unprivileged Thread mode, use PSP 00063 MSR CONTROL,R0 00064 BX LR 00065 PrivilegedE 00066 MOVS R0,#0x02 ; Privileged Thread mode, use PSP 00067 MSR CONTROL,R0 00068 BX LR 00069 00070 ALIGN 00071 } 00072 00073 00074 /*--------------------------- _alloc_box ------------------------------------*/ 00075 00076 __asm void *_alloc_box (void *box_mem) { 00077 /* Function wrapper for Unprivileged/Privileged mode. */ 00078 LDR R3,=__cpp(rt_alloc_box) 00079 MOV R12,R3 00080 MRS R3,IPSR 00081 LSLS R3,#24 00082 BNE PrivilegedA 00083 MRS R3,CONTROL 00084 LSLS R3,#31 00085 BEQ PrivilegedA 00086 SVC 0 00087 BX LR 00088 PrivilegedA 00089 BX R12 00090 00091 ALIGN 00092 } 00093 00094 00095 /*--------------------------- _free_box -------------------------------------*/ 00096 00097 __asm int _free_box (void *box_mem, void *box) { 00098 /* Function wrapper for Unprivileged/Privileged mode. */ 00099 LDR R3,=__cpp(rt_free_box) 00100 MOV R12,R3 00101 MRS R3,IPSR 00102 LSLS R3,#24 00103 BNE PrivilegedF 00104 MRS R3,CONTROL 00105 LSLS R3,#31 00106 BEQ PrivilegedF 00107 SVC 0 00108 BX LR 00109 PrivilegedF 00110 BX R12 00111 00112 ALIGN 00113 } 00114 00115 00116 /*-------------------------- SVC_Handler ------------------------------------*/ 00117 00118 __asm void SVC_Handler (void) { 00119 PRESERVE8 00120 00121 IMPORT SVC_Count 00122 IMPORT SVC_Table 00123 IMPORT rt_stk_check 00124 00125 MRS R0,PSP ; Read PSP 00126 LDR R1,[R0,#24] ; Read Saved PC from Stack 00127 SUBS R1,R1,#2 ; Point to SVC Instruction 00128 LDRB R1,[R1] ; Load SVC Number 00129 CMP R1,#0 00130 BNE SVC_User ; User SVC Number > 0 00131 00132 MOV LR,R4 00133 LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack 00134 MOV R12,R4 00135 MOV R4,LR 00136 BLX R12 ; Call SVC Function 00137 00138 LDR R3,=__cpp(&os_tsk) 00139 LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new 00140 CMP R1,R2 00141 BEQ SVC_Exit ; no task switch 00142 00143 SUBS R3,#8 00144 CMP R1,#0 ; Runtask deleted? 00145 BEQ SVC_Restore 00146 00147 PUSH {R2,R3} 00148 ADDS R1,#32 ; for STRB offset < 32 00149 MOVS R3,#1 00150 STRB R3,[R1,#TCB_RETUPD-32] ; os_tsk.run->ret_upd = 1 00151 00152 MRS R3,PSP ; Read PSP 00153 SUBS R3,R3,#32 ; Adjust Start Address 00154 STR R3,[R1,#TCB_TSTACK-32] ; Update os_tsk.run->tsk_stack 00155 STMIA R3!,{R4-R7} ; Save old context (R4-R7) 00156 MOV R4,R8 00157 MOV R5,R9 00158 MOV R6,R10 00159 MOV R7,R11 00160 STMIA R3!,{R4-R7} ; Save old context (R8-R11) 00161 BL rt_stk_check ; Check for Stack overflow 00162 POP {R2,R3} 00163 00164 SVC_Restore 00165 STR R2,[R3] ; os_tsk.run = os_tsk.new 00166 00167 ADDS R2,#32 ; for STRB offset < 32 00168 LDR R3,[R2,#TCB_TSTACK-32] ; os_tsk.new->tsk_stack 00169 ADDS R3,R3,#16 ; Adjust Start Address 00170 LDMIA R3!,{R4-R7} ; Restore new Context (R8-R11) 00171 MOV R8,R4 00172 MOV R9,R5 00173 MOV R10,R6 00174 MOV R11,R7 00175 MSR PSP,R3 ; Write PSP 00176 SUBS R3,R3,#32 ; Adjust Start Address 00177 LDMIA R3!,{R4-R7} ; Restore new Context (R4-R7) 00178 00179 LDRB R0,[R2,#TCB_RETUPD-32] ; Update ret_val ? 00180 CMP R0,#0 00181 BEQ SVC_Return 00182 LDRB R0,[R2,#TCB_RETVAL-32] ; Write os_tsk.new->ret_val 00183 00184 SVC_Exit 00185 MRS R3,PSP ; Read PSP 00186 STR R0,[R3] ; Function return value 00187 00188 SVC_Return 00189 MOVS R3,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value 00190 MVNS R3,R3 00191 BX R3 ; RETI to Thread Mode, use PSP 00192 00193 /*------------------- User SVC ------------------------------*/ 00194 00195 SVC_User 00196 PUSH {R4,LR} ; Save Registers 00197 LDR R2,=SVC_Count 00198 LDR R2,[R2] 00199 CMP R1,R2 00200 BHI SVC_Done ; Overflow 00201 00202 LDR R4,=SVC_Table-4 00203 LSLS R1,R1,#2 00204 LDR R4,[R4,R1] ; Load SVC Function Address 00205 MOV LR,R4 00206 00207 LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack 00208 MOV R12,R4 00209 BLX LR ; Call SVC Function 00210 00211 MRS R4,PSP ; Read PSP 00212 STMIA R4!,{R0-R3} ; Function return values 00213 SVC_Done 00214 POP {R4,PC} ; RETI 00215 00216 ALIGN 00217 } 00218 00219 00220 /*-------------------------- PendSV_Handler ---------------------------------*/ 00221 00222 __asm void PendSV_Handler (void) { 00223 PRESERVE8 00224 00225 BL __cpp(rt_pop_req) 00226 00227 Sys_Switch 00228 LDR R3,=__cpp(&os_tsk) 00229 LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new 00230 CMP R1,R2 00231 BEQ Sys_Exit ; no task switch 00232 00233 SUBS R3,#8 00234 PUSH {R2,R3} 00235 ADDS R1,#32 ; for STRB offset < 32 00236 00237 MOVS R3,#0 00238 STRB R3,[R1,#TCB_RETUPD-32] ; os_tsk.run->ret_upd = 0 00239 MRS R3,PSP ; Read PSP 00240 SUBS R3,R3,#32 ; Adjust Start Address 00241 STR R3,[R1,#TCB_TSTACK-32] ; Update os_tsk.run->tsk_stack 00242 STMIA R3!,{R4-R7} ; Save old context (R4-R7) 00243 MOV R4,R8 00244 MOV R5,R9 00245 MOV R6,R10 00246 MOV R7,R11 00247 STMIA R3!,{R4-R7} ; Save old context (R8-R11) 00248 BL rt_stk_check ; Check for Stack overflow 00249 00250 POP {R2,R3} 00251 STR R2,[R3] ; os_tsk.run = os_tsk.new 00252 ADDS R2,#32 ; for STRB offset < 32 00253 00254 LDR R3,[R2,#TCB_TSTACK-32] ; os_tsk.new->tsk_stack 00255 ADDS R3,R3,#16 ; Adjust Start Address 00256 LDMIA R3!,{R4-R7} ; Restore new Context (R8-R11) 00257 MOV R8,R4 00258 MOV R9,R5 00259 MOV R10,R6 00260 MOV R11,R7 00261 MSR PSP,R3 ; Write PSP 00262 SUBS R3,R3,#32 ; Adjust Start Address 00263 LDMIA R3!,{R4-R7} ; Restore new Context (R4-R7) 00264 00265 LDRB R0,[R2,#TCB_RETUPD-32] ; Update ret_val ? 00266 CMP R0,#0 00267 BEQ Sys_Exit 00268 LDRB R0,[R2,#TCB_RETVAL-32] ; Write os_tsk.new->ret_val 00269 STR R0,[R3,#16] 00270 Sys_Exit 00271 MOVS R3,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value 00272 MVNS R3,R3 00273 BX R3 ; RETI to Thread Mode, use PSP 00274 00275 ALIGN 00276 } 00277 00278 00279 /*-------------------------- SysTick_Handler --------------------------------*/ 00280 00281 __asm void SysTick_Handler (void) { 00282 PRESERVE8 00283 00284 BL __cpp(rt_systick) 00285 B Sys_Switch 00286 00287 ALIGN 00288 } 00289 00290 00291 /*-------------------------- OS_Tick_Handler --------------------------------*/ 00292 00293 __asm void OS_Tick_Handler (void) { 00294 PRESERVE8 00295 00296 BL __cpp(os_tick_irqack) 00297 BL __cpp(rt_systick) 00298 B Sys_Switch 00299 00300 ALIGN 00301 } 00302 00303 00304 /*--------------------------- rt_init_stack ---------------------------------*/ 00305 00306 void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { 00307 /* Prepare TCB and saved context for a first time start of a task. */ 00308 U32 *stk,i,size; 00309 00310 /* Prepare a complete interrupt frame for first task start */ 00311 size = p_TCB->priv_stack >> 2; 00312 if (size == 0) { 00313 size = (U16)os_stackinfo >> 2; 00314 } 00315 00316 /* Write to the top of stack. */ 00317 stk = &p_TCB->stack[size]; 00318 00319 /* Auto correct to 8-byte ARM stack alignment. */ 00320 if ((U32)stk & 0x04) { 00321 stk--; 00322 } 00323 00324 stk -= 16; 00325 00326 /* Default xPSR and initial PC */ 00327 stk[15] = INITIAL_xPSR; 00328 stk[14] = (U32)task_body; 00329 00330 /* Clear R1-R12,LR registers. */ 00331 for (i = 0; i < 14; i++) { 00332 stk[i] = 0; 00333 } 00334 00335 /* Assign a void pointer to R0. */ 00336 stk[8] = (U32)p_TCB->msg; 00337 00338 /* Initial Task stack pointer. */ 00339 p_TCB->tsk_stack = (U32)stk; 00340 00341 /* Task entry point. */ 00342 p_TCB->ptask = task_body; 00343 00344 /* Set a magic word for checking of stack overflow. */ 00345 p_TCB->stack[0] = MAGIC_WORD; 00346 } 00347 00348 00349 /*---------------------------------------------------------------------------- 00350 * end of file 00351 *---------------------------------------------------------------------------*/ 00352
Generated on Tue Jul 12 2022 15:37:18 by
