Dan Searle / mbed-rtos

Dependents:   LEDFun NetTester

Fork of mbed-rtos by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HAL_CM4.c Source File

HAL_CM4.c

00001 /*----------------------------------------------------------------------------
00002  *      RL-ARM - RTX
00003  *----------------------------------------------------------------------------
00004  *      Name:    HAL_CM4.C
00005  *      Purpose: Hardware Abstraction Layer for Cortex-M4
00006  *      Rev.:    V4.70
00007  *----------------------------------------------------------------------------
00008  *
00009  * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
00010  * All rights reserved.
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are met:
00013  *  - Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  *  - Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  *  - Neither the name of ARM  nor the names of its contributors may be used 
00019  *    to endorse or promote products derived from this software without 
00020  *    specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
00023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
00026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
00028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
00031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  * POSSIBILITY OF SUCH DAMAGE.
00033  *---------------------------------------------------------------------------*/
00034 
00035 #include "rt_TypeDef.h"
00036 #include "RTX_Conf.h"
00037 #include "rt_System.h"
00038 #include "rt_HAL_CM.h"
00039 #include "rt_Task.h"
00040 #include "rt_MemBox.h"
00041 
00042 
00043 /*----------------------------------------------------------------------------
00044  *      Functions
00045  *---------------------------------------------------------------------------*/
00046 
00047 
00048 /*--------------------------- rt_set_PSP ------------------------------------*/
00049 
00050 __asm void rt_set_PSP (U32 stack) {
00051         MSR     PSP,R0
00052         BX      LR
00053 }
00054 
00055 
00056 /*--------------------------- rt_get_PSP ------------------------------------*/
00057 
00058 __asm U32 rt_get_PSP (void) {
00059         MRS     R0,PSP
00060         BX      LR
00061 }
00062 
00063 
00064 /*--------------------------- os_set_env ------------------------------------*/
00065 
00066 __asm void os_set_env (void) {
00067    /* Switch to Unprivileged/Privileged Thread mode, use PSP. */
00068         MOV     R0,SP                   ; PSP = MSP
00069         MSR     PSP,R0
00070         LDR     R0,=__cpp(&os_flags)
00071         LDRB    R0,[R0]
00072         LSLS    R0,#31
00073         MOVNE   R0,#0x02                ; Privileged Thread mode, use PSP
00074         MOVEQ   R0,#0x03                ; Unprivileged Thread mode, use PSP
00075         MSR     CONTROL,R0
00076         BX      LR
00077 
00078         ALIGN
00079 }
00080 
00081 
00082 /*--------------------------- _alloc_box ------------------------------------*/
00083 
00084 __asm void *_alloc_box (void *box_mem) {
00085    /* Function wrapper for Unprivileged/Privileged mode. */
00086         LDR     R12,=__cpp(rt_alloc_box)
00087         MRS     R3,IPSR
00088         LSLS    R3,#24
00089         BXNE    R12
00090         MRS     R3,CONTROL
00091         LSLS    R3,#31
00092         BXEQ    R12
00093         SVC     0
00094         BX      LR
00095 
00096         ALIGN
00097 }
00098 
00099 
00100 /*--------------------------- _free_box -------------------------------------*/
00101 
00102 __asm int _free_box (void *box_mem, void *box) {
00103    /* Function wrapper for Unprivileged/Privileged mode. */
00104         LDR     R12,=__cpp(rt_free_box)
00105         MRS     R3,IPSR
00106         LSLS    R3,#24
00107         BXNE    R12
00108         MRS     R3,CONTROL
00109         LSLS    R3,#31
00110         BXEQ    R12
00111         SVC     0
00112         BX      LR
00113 
00114         ALIGN
00115 }
00116 
00117 
00118 /*-------------------------- SVC_Handler ------------------------------------*/
00119 
00120 __asm void SVC_Handler (void) {
00121         PRESERVE8
00122 
00123         IMPORT  SVC_Count
00124         IMPORT  SVC_Table
00125         IMPORT  rt_stk_check
00126 
00127 #ifdef  IFX_XMC4XXX
00128         EXPORT  SVC_Handler_Veneer
00129 SVC_Handler_Veneer        
00130 #endif
00131 
00132         MRS     R0,PSP                  ; Read PSP
00133         LDR     R1,[R0,#24]             ; Read Saved PC from Stack
00134         LDRB    R1,[R1,#-2]             ; Load SVC Number
00135         CBNZ    R1,SVC_User
00136 
00137         LDM     R0,{R0-R3,R12}          ; Read R0-R3,R12 from stack
00138         PUSH    {R4,LR}                 ; Save EXC_RETURN
00139         BLX     R12                     ; Call SVC Function 
00140         POP     {R4,LR}                 ; Restore EXC_RETURN
00141 
00142         MRS     R12,PSP                 ; Read PSP
00143         STM     R12,{R0-R2}             ; Store return values
00144 
00145         LDR     R3,=__cpp(&os_tsk)
00146         LDM     R3,{R1,R2}              ; os_tsk.run, os_tsk.new
00147         CMP     R1,R2
00148 #ifdef  IFX_XMC4XXX
00149         PUSHEQ  {LR}
00150         POPEQ   {PC}
00151 #else
00152         BXEQ    LR                      ; RETI, no task switch
00153 #endif
00154 
00155         CBZ     R1,SVC_Next             ; Runtask deleted?
00156         TST     LR,#0x10                ; is it extended frame?
00157         VSTMDBEQ R12!,{S16-S31}         ; yes, stack also VFP hi-regs
00158         MOVEQ   R0,#0x01                ; os_tsk->stack_frame val
00159         MOVNE   R0,#0x00
00160         STRB    R0,[R1,#TCB_STACKF]     ; os_tsk.run->stack_frame = val
00161         STMDB   R12!,{R4-R11}           ; Save Old context
00162         STR     R12,[R1,#TCB_TSTACK]    ; Update os_tsk.run->tsk_stack
00163 
00164         PUSH    {R2,R3}
00165         BL      rt_stk_check            ; Check for Stack overflow
00166         POP     {R2,R3}
00167 
00168 SVC_Next
00169         STR     R2,[R3]                 ; os_tsk.run = os_tsk.new
00170 
00171         LDR     R12,[R2,#TCB_TSTACK]    ; os_tsk.new->tsk_stack
00172         LDMIA   R12!,{R4-R11}           ; Restore New Context
00173         LDRB    R0,[R2,#TCB_STACKF]     ; Stack Frame
00174         CMP     R0,#0                   ; Basic/Extended Stack Frame
00175         VLDMIANE R12!,{S16-S31}         ; restore VFP hi-registers
00176         MVNNE   LR,#:NOT:0xFFFFFFED     ; set EXC_RETURN value
00177         MVNEQ   LR,#:NOT:0xFFFFFFFD
00178         MSR     PSP,R12                 ; Write PSP
00179 
00180 SVC_Exit
00181 #ifdef  IFX_XMC4XXX
00182         PUSH    {LR}
00183         POP     {PC}
00184 #else
00185         BX      LR
00186 #endif
00187 
00188         /*------------------- User SVC ------------------------------*/
00189 
00190 SVC_User
00191         PUSH    {R4,LR}                 ; Save Registers
00192         LDR     R2,=SVC_Count
00193         LDR     R2,[R2]
00194         CMP     R1,R2
00195         BHI     SVC_Done                ; Overflow
00196 
00197         LDR     R4,=SVC_Table-4
00198         LDR     R4,[R4,R1,LSL #2]       ; Load SVC Function Address
00199 
00200         LDM     R0,{R0-R3,R12}          ; Read R0-R3,R12 from stack
00201         BLX     R4                      ; Call SVC Function
00202 
00203         MRS     R12,PSP
00204         STM     R12,{R0-R3}             ; Function return values
00205 SVC_Done
00206         POP     {R4,PC}                 ; RETI
00207 
00208         ALIGN
00209 }
00210 
00211 
00212 /*-------------------------- PendSV_Handler ---------------------------------*/
00213 
00214 __asm void PendSV_Handler (void) {
00215         PRESERVE8
00216 
00217 #ifdef  IFX_XMC4XXX
00218         EXPORT  PendSV_Handler_Veneer
00219 PendSV_Handler_Veneer        
00220 #endif
00221 
00222         PUSH    {R4,LR}                 ; Save EXC_RETURN
00223         BL      __cpp(rt_pop_req)
00224 
00225 Sys_Switch
00226         POP     {R4,LR}                 ; Restore EXC_RETURN
00227 
00228         LDR     R3,=__cpp(&os_tsk)
00229         LDM     R3,{R1,R2}              ; os_tsk.run, os_tsk.new
00230         CMP     R1,R2
00231 #ifdef  IFX_XMC4XXX
00232         PUSHEQ  {LR}
00233         POPEQ   {PC}
00234 #else
00235         BXEQ    LR                      ; RETI, no task switch
00236 #endif
00237 
00238         MRS     R12,PSP                 ; Read PSP
00239         TST     LR,#0x10                ; is it extended frame?
00240         VSTMDBEQ R12!,{S16-S31}         ; yes, stack also VFP hi-regs
00241         MOVEQ   R0,#0x01                ; os_tsk->stack_frame val
00242         MOVNE   R0,#0x00
00243         STRB    R0,[R1,#TCB_STACKF]     ; os_tsk.run->stack_frame = val
00244         STMDB   R12!,{R4-R11}           ; Save Old context
00245         STR     R12,[R1,#TCB_TSTACK]    ; Update os_tsk.run->tsk_stack
00246 
00247         PUSH    {R2,R3}
00248         BL      rt_stk_check            ; Check for Stack overflow
00249         POP     {R2,R3}
00250 
00251         STR     R2,[R3]                 ; os_tsk.run = os_tsk.new
00252 
00253         LDR     R12,[R2,#TCB_TSTACK]    ; os_tsk.new->tsk_stack
00254         LDMIA   R12!,{R4-R11}           ; Restore New Context
00255         LDRB    R0,[R2,#TCB_STACKF]     ; Stack Frame
00256         CMP     R0,#0                   ; Basic/Extended Stack Frame
00257         VLDMIANE R12!,{S16-S31}         ; restore VFP hi-regs
00258         MVNNE   LR,#:NOT:0xFFFFFFED     ; set EXC_RETURN value
00259         MVNEQ   LR,#:NOT:0xFFFFFFFD
00260         MSR     PSP,R12                 ; Write PSP
00261 
00262 Sys_Exit
00263 #ifdef  IFX_XMC4XXX
00264         PUSH    {LR}
00265         POP     {PC}
00266 #else
00267         BX      LR                      ; Return to Thread Mode
00268 #endif
00269 
00270         ALIGN
00271 }
00272 
00273 
00274 /*-------------------------- SysTick_Handler --------------------------------*/
00275 
00276 __asm void SysTick_Handler (void) {
00277         PRESERVE8
00278 
00279 #ifdef  IFX_XMC4XXX
00280         EXPORT  SysTick_Handler_Veneer
00281 SysTick_Handler_Veneer        
00282 #endif
00283 
00284         PUSH    {R4,LR}                 ; Save EXC_RETURN
00285         BL      __cpp(rt_systick)
00286         B       Sys_Switch
00287 
00288         ALIGN
00289 }
00290 
00291 
00292 /*-------------------------- OS_Tick_Handler --------------------------------*/
00293 
00294 __asm void OS_Tick_Handler (void) {
00295         PRESERVE8
00296 
00297         PUSH    {R4,LR}                 ; Save EXC_RETURN
00298         BL      __cpp(os_tick_irqack)
00299         BL      __cpp(rt_systick)
00300         B       Sys_Switch
00301 
00302         ALIGN
00303 }
00304 
00305 
00306 /*----------------------------------------------------------------------------
00307  * end of file
00308  *---------------------------------------------------------------------------*/
00309