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_CM3.c
00001 /** 00002 * @file HAL_CM3.c 00003 * @brief HAL for Cortex-M3 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 * Global Variables 00033 *---------------------------------------------------------------------------*/ 00034 00035 BIT dbg_msg; 00036 00037 /*---------------------------------------------------------------------------- 00038 * Functions 00039 *---------------------------------------------------------------------------*/ 00040 00041 00042 /*--------------------------- rt_set_PSP ------------------------------------*/ 00043 00044 __asm void rt_set_PSP (U32 stack) { 00045 MSR PSP,R0 00046 BX LR 00047 } 00048 00049 00050 /*--------------------------- rt_get_PSP ------------------------------------*/ 00051 00052 __asm U32 rt_get_PSP (void) { 00053 MRS R0,PSP 00054 BX LR 00055 } 00056 00057 00058 /*--------------------------- os_set_env ------------------------------------*/ 00059 00060 __asm void os_set_env (void) { 00061 /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ 00062 MOV R0,SP ; PSP = MSP 00063 MSR PSP,R0 00064 LDR R0,=__cpp(&os_flags) 00065 LDRB R0,[R0] 00066 LSLS R0,#31 00067 MOVNE R0,#0x02 ; Privileged Thread mode, use PSP 00068 MOVEQ R0,#0x03 ; Unprivileged Thread mode, use PSP 00069 MSR CONTROL,R0 00070 BX LR 00071 00072 ALIGN 00073 } 00074 00075 00076 /*--------------------------- _alloc_box ------------------------------------*/ 00077 00078 __asm void *_alloc_box (void *box_mem) { 00079 /* Function wrapper for Unprivileged/Privileged mode. */ 00080 LDR R12,=__cpp(rt_alloc_box) 00081 MRS R3,IPSR 00082 LSLS R3,#24 00083 BXNE R12 00084 MRS R3,CONTROL 00085 LSLS R3,#31 00086 BXEQ R12 00087 SVC 0 00088 BX LR 00089 00090 ALIGN 00091 } 00092 00093 00094 /*--------------------------- _free_box -------------------------------------*/ 00095 00096 __asm int _free_box (void *box_mem, void *box) { 00097 /* Function wrapper for Unprivileged/Privileged mode. */ 00098 LDR R12,=__cpp(rt_free_box) 00099 MRS R3,IPSR 00100 LSLS R3,#24 00101 BXNE R12 00102 MRS R3,CONTROL 00103 LSLS R3,#31 00104 BXEQ R12 00105 SVC 0 00106 BX LR 00107 00108 ALIGN 00109 } 00110 00111 00112 /*-------------------------- SVC_Handler ------------------------------------*/ 00113 00114 __asm void SVC_Handler (void) { 00115 PRESERVE8 00116 00117 #ifdef IFX_XMC4XXX 00118 EXPORT SVC_Handler_Veneer 00119 SVC_Handler_Veneer 00120 #endif 00121 00122 IMPORT SVC_Count 00123 IMPORT SVC_Table 00124 IMPORT rt_stk_check 00125 00126 MRS R0,PSP ; Read PSP 00127 LDR R1,[R0,#24] ; Read Saved PC from Stack 00128 LDRB R1,[R1,#-2] ; Load SVC Number 00129 CBNZ R1,SVC_User 00130 00131 LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack 00132 BLX R12 ; Call SVC Function 00133 00134 MRS R12,PSP ; Read PSP 00135 LDR R3,=__cpp(&os_tsk) 00136 LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new 00137 CMP R1,R2 00138 BEQ SVC_Exit ; no task switch 00139 00140 CBZ R1,SVC_Restore ; Runtask deleted? 00141 00142 PUSH {R2,R3} 00143 MOV R3,#1 00144 STRB R3,[R1,#TCB_RETUPD] ; os_tsk.run->ret_upd = 1 00145 STMDB R12!,{R4-R11} ; Save Old context 00146 STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack 00147 BL rt_stk_check ; Check for Stack overflow 00148 POP {R2,R3} 00149 00150 SVC_Restore 00151 STR R2,[R3] ; os_tsk.run = os_tsk.new 00152 00153 LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack 00154 LDMIA R12!,{R4-R11} ; Restore New Context 00155 LDRB R3,[R2,#TCB_RETUPD] ; Update ret_val? 00156 MSR PSP,R12 ; Write PSP 00157 00158 CBZ R3,SVC_Return 00159 LDRB R0,[R2,#TCB_RETVAL] ; Write os_tsk.new->ret_val 00160 00161 SVC_Exit 00162 STR R0,[R12] ; Function return value 00163 00164 SVC_Return 00165 MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value 00166 #ifdef IFX_XMC4XXX 00167 PUSH {LR} 00168 POP {PC} 00169 #else 00170 BX LR 00171 #endif 00172 00173 /*------------------- User SVC ------------------------------*/ 00174 00175 SVC_User 00176 PUSH {R4,LR} ; Save Registers 00177 LDR R2,=SVC_Count 00178 LDR R2,[R2] 00179 CMP R1,R2 00180 BHI SVC_Done ; Overflow 00181 00182 LDR R4,=SVC_Table-4 00183 LDR R4,[R4,R1,LSL #2] ; Load SVC Function Address 00184 00185 LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack 00186 BLX R4 ; Call SVC Function 00187 00188 MRS R12,PSP 00189 STM R12,{R0-R3} ; Function return values 00190 SVC_Done 00191 POP {R4,PC} ; RETI 00192 00193 ALIGN 00194 } 00195 00196 00197 /*-------------------------- PendSV_Handler ---------------------------------*/ 00198 00199 __asm void PendSV_Handler (void) { 00200 PRESERVE8 00201 00202 #ifdef IFX_XMC4XXX 00203 EXPORT PendSV_Handler_Veneer 00204 PendSV_Handler_Veneer 00205 #endif 00206 00207 BL __cpp(rt_pop_req) 00208 00209 Sys_Switch 00210 LDR R3,=__cpp(&os_tsk) 00211 LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new 00212 CMP R1,R2 00213 BEQ Sys_Exit 00214 00215 PUSH {R2,R3} 00216 MOV R3,#0 00217 STRB R3,[R1,#TCB_RETUPD] ; os_tsk.run->ret_upd = 0 00218 MRS R12,PSP ; Read PSP 00219 STMDB R12!,{R4-R11} ; Save Old context 00220 STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack 00221 BL rt_stk_check ; Check for Stack overflow 00222 00223 POP {R2,R3} 00224 STR R2,[R3] ; os_tsk.run = os_tsk.new 00225 00226 LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack 00227 LDMIA R12!,{R4-R11} ; Restore New Context 00228 MSR PSP,R12 ; Write PSP 00229 00230 LDRB R3,[R2,#TCB_RETUPD] ; Update ret_val? 00231 CBZ R3,Sys_Exit 00232 LDRB R3,[R2,#TCB_RETVAL] ; Write os_tsk.new->ret_val 00233 STR R3,[R12] 00234 Sys_Exit 00235 MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value 00236 #ifdef IFX_XMC4XXX 00237 PUSH {LR} 00238 POP {PC} 00239 #else 00240 BX LR ; Return to Thread Mode 00241 #endif 00242 00243 ALIGN 00244 } 00245 00246 00247 /*-------------------------- SysTick_Handler --------------------------------*/ 00248 00249 __asm void SysTick_Handler (void) { 00250 PRESERVE8 00251 00252 #ifdef IFX_XMC4XXX 00253 EXPORT SysTick_Handler_Veneer 00254 SysTick_Handler_Veneer 00255 #endif 00256 00257 BL __cpp(rt_systick) 00258 B Sys_Switch 00259 00260 ALIGN 00261 } 00262 00263 00264 /*-------------------------- OS_Tick_Handler --------------------------------*/ 00265 00266 __asm void OS_Tick_Handler (void) { 00267 PRESERVE8 00268 00269 BL __cpp(os_tick_irqack) 00270 BL __cpp(rt_systick) 00271 B Sys_Switch 00272 00273 ALIGN 00274 } 00275 00276 00277 /*--------------------------- rt_init_stack ---------------------------------*/ 00278 00279 void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { 00280 /* Prepare TCB and saved context for a first time start of a task. */ 00281 U32 *stk,i,size; 00282 00283 /* Prepare a complete interrupt frame for first task start */ 00284 size = p_TCB->priv_stack >> 2; 00285 if (size == 0) { 00286 size = (U16)os_stackinfo >> 2; 00287 } 00288 00289 /* Write to the top of stack. */ 00290 stk = &p_TCB->stack[size]; 00291 00292 /* Auto correct to 8-byte ARM stack alignment. */ 00293 if ((U32)stk & 0x04) { 00294 stk--; 00295 } 00296 00297 stk -= 16; 00298 00299 /* Default xPSR and initial PC */ 00300 stk[15] = INITIAL_xPSR; 00301 stk[14] = (U32)task_body; 00302 00303 /* Clear R1-R12,LR registers. */ 00304 for (i = 0; i < 14; i++) { 00305 stk[i] = 0; 00306 } 00307 00308 /* Assign a void pointer to R0. */ 00309 stk[8] = (U32)p_TCB->msg; 00310 00311 /* Initial Task stack pointer. */ 00312 p_TCB->tsk_stack = (U32)stk; 00313 00314 /* Task entry point. */ 00315 p_TCB->ptask = task_body; 00316 00317 /* Set a magic word for checking of stack overflow. */ 00318 p_TCB->stack[0] = MAGIC_WORD; 00319 } 00320 00321 00322 /*--------------------------- dbg_init --------------------------------------*/ 00323 00324 void dbg_init (void) { 00325 if ((DEMCR & DEMCR_TRCENA) && 00326 (ITM_CONTROL & ITM_ITMENA) && 00327 (ITM_ENABLE & (1UL << 31))) { 00328 dbg_msg = __TRUE; 00329 } 00330 } 00331 00332 00333 /*--------------------------- dbg_task_notify -------------------------------*/ 00334 00335 void dbg_task_notify (P_TCB p_tcb, BOOL create) { 00336 while (ITM_PORT31_U32 == 0); 00337 ITM_PORT31_U32 = (U32)p_tcb->ptask; 00338 while (ITM_PORT31_U32 == 0); 00339 ITM_PORT31_U16 = (create << 8) | p_tcb->task_id; 00340 } 00341 00342 00343 /*--------------------------- dbg_task_switch -------------------------------*/ 00344 00345 void dbg_task_switch (U32 task_id) { 00346 while (ITM_PORT31_U32 == 0); 00347 ITM_PORT31_U8 = task_id; 00348 } 00349 00350 00351 /*---------------------------------------------------------------------------- 00352 * end of file 00353 *---------------------------------------------------------------------------*/ 00354
Generated on Tue Jul 12 2022 15:37:18 by
1.7.2