1#include <k_config.h> 2 3;****************************************************************************** 4; EXTERN PARAMETERS 5;****************************************************************************** 6 EXTERN g_active_task 7 EXTERN g_preferred_ready_task 8 EXTERN krhino_stack_ovf_check 9 EXTERN krhino_task_sched_stats_get 10 11;****************************************************************************** 12; EXPORT FUNCTIONS 13;****************************************************************************** 14 PUBLIC cpu_intrpt_save 15 PUBLIC cpu_intrpt_restore 16 PUBLIC cpu_task_switch 17 PUBLIC cpu_intrpt_switch 18 PUBLIC cpu_first_task_start 19 PUBLIC _first_task_restore 20 21 PUBLIC PendSV_Handler 22 23;****************************************************************************** 24; EQUATES 25;****************************************************************************** 26SCB_ICSR EQU 0xE000ED04 ; Interrupt Control and State Register. 27SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register. 28ICSR_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception. 29 30SHPR3_PRI_14 EQU 0xE000ED22 ; System Handler Priority Register 3 (PendSV). 31PRI_LVL_PENDSV EQU 0xFF ; PendSV priority level (lowest). 32SHPR3_PRI_15 EQU 0xE000ED23 ; System Handler Priority Register 3 (SysTick). 33PRI_LVL_SYSTICK EQU 0xFF ; SYstick priority level (lowest). 34 35;****************************************************************************** 36; CODE GENERATION DIRECTIVES 37;****************************************************************************** 38 SECTION .text:CODE(2) 39 THUMB 40 REQUIRE8 41 PRESERVE8 42 43;****************************************************************************** 44; Functions: 45; size_t cpu_intrpt_save(void); 46; void cpu_intrpt_restore(size_t cpsr); 47;****************************************************************************** 48cpu_intrpt_save: 49 MRS R0, PRIMASK 50 CPSID I 51 BX LR 52 53cpu_intrpt_restore: 54 MSR PRIMASK, R0 55 BX LR 56 57;****************************************************************************** 58; Functions: 59; void cpu_intrpt_switch(void); 60; void cpu_task_switch(void); 61;****************************************************************************** 62cpu_task_switch: 63 LDR R0, =SCB_ICSR 64 LDR R1, =ICSR_PENDSVSET 65 STR R1, [R0] 66 BX LR 67 68cpu_intrpt_switch: 69 LDR R0, =SCB_ICSR 70 LDR R1, =ICSR_PENDSVSET 71 STR R1, [R0] 72 BX LR 73 74;****************************************************************************** 75; Functions: 76; void cpu_first_task_start(void); 77;****************************************************************************** 78cpu_first_task_start: 79 ;set PendSV prority to the lowest 80 LDR R0, =SHPR3_PRI_14 81 LDR R1, =PRI_LVL_PENDSV 82 STRB R1, [R0] 83 84 ;set Systick prority to the lowest 85 LDR R0, =SHPR3_PRI_15 86 LDR R1, =PRI_LVL_SYSTICK 87 STRB R1, [R0] 88 89 ;indicate PendSV_Handler branch to _pendsv_handler_nosave 90 MOVS R0, #0 91 MSR PSP, R0 92 93 ;make PendSV exception pending 94 LDR R0, =SCB_ICSR 95 LDR R1, =ICSR_PENDSVSET 96 STR R1, [R0] 97 98 ;goto PendSV_Handler 99 CPSIE I 100 B . 101 102;****************************************************************************** 103; Functions: 104; void krhino_pendsv_handler(void); 105;****************************************************************************** 106PendSV_Handler: 107 CPSID I 108 MRS R0, PSP 109 ;branch if cpu_first_task_start 110 CMP R0, #0 111 BEQ _first_task_restore 112 113 ;hardware saved R0~R3,R12,LR,PC,xPSR 114 115 ;save context 116 SUBS R0, R0, #0x24 117 STM R0, {R4-R11, LR} 118 119 ;g_active_task->task_stack = context region 120 LDR R1, =g_active_task 121 LDR R1, [R1] 122 STR R0, [R1] 123 124#if (RHINO_CONFIG_TASK_STACK_OVF_CHECK > 0) 125 BL krhino_stack_ovf_check 126#endif 127#if (RHINO_CONFIG_SYS_STATS > 0) 128 BL krhino_task_sched_stats_get 129#endif 130 131_pendsv_handler_nosave: 132 LDR R0, =g_active_task 133 LDR R1, =g_preferred_ready_task 134 LDR R2, [R1] 135 STR R2, [R0] 136 ;R0 = g_active_task->task_stack = context region 137 LDR R0, [R2] 138 139 ;restore context 140 LDM R0, {R4-R11, LR} 141 ADDS R0, R0, #0x24 142 143 ;return stack = PSP 144 MSR PSP, R0 145 146 CPSIE I 147 ;hardware restore R0~R3,R12,LR,PC,xPSR 148 BX LR 149 150_first_task_restore: 151 ;set MSP to the base of system stack 152 LDR R0, =SCB_VTOR 153 LDR R0, [R0] 154 LDR R0, [R0] 155 MSR MSP, R0 156 157 B _pendsv_handler_nosave 158 159 END 160 161