1/**************************************************************************/ 2/* */ 3/* Copyright (c) Microsoft Corporation. All rights reserved. */ 4/* */ 5/* This software is licensed under the Microsoft Software License */ 6/* Terms for Microsoft Azure RTOS. Full text of the license can be */ 7/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ 8/* and in the root directory of this software. */ 9/* */ 10/**************************************************************************/ 11 12 13/**************************************************************************/ 14/**************************************************************************/ 15/** */ 16/** ThreadX Component */ 17/** */ 18/** Initialize */ 19/** */ 20/**************************************************************************/ 21/**************************************************************************/ 22 23#ifdef TX_INCLUDE_USER_DEFINE_FILE 24#include "tx_user.h" 25#endif 26 27 EXTERN _tx_thread_system_stack_ptr 28 EXTERN _tx_initialize_unused_memory 29 EXTERN _tx_timer_interrupt 30 EXTERN __main 31 EXTERN __vector_table 32 EXTERN _tx_thread_current_ptr 33 EXTERN _tx_thread_stack_error_handler 34 35SYSTEM_CLOCK EQU 96000000 36SYSTICK_CYCLES EQU ((SYSTEM_CLOCK / 100) -1) 37 38 RSEG FREE_MEM:DATA 39 PUBLIC __tx_free_memory_start 40__tx_free_memory_start 41 DS32 4 42 43 SECTION `.text`:CODE:NOROOT(2) 44 THUMB 45/**************************************************************************/ 46/* */ 47/* FUNCTION RELEASE */ 48/* */ 49/* _tx_initialize_low_level Cortex-Mxx/IAR */ 50/* 6.1 */ 51/* AUTHOR */ 52/* */ 53/* Scott Larson, Microsoft Corporation */ 54/* */ 55/* DESCRIPTION */ 56/* */ 57/* This function is responsible for any low-level processor */ 58/* initialization, including setting up interrupt vectors, setting */ 59/* up a periodic timer interrupt source, saving the system stack */ 60/* pointer for use in ISR processing later, and finding the first */ 61/* available RAM memory address for tx_application_define. */ 62/* */ 63/* INPUT */ 64/* */ 65/* None */ 66/* */ 67/* OUTPUT */ 68/* */ 69/* None */ 70/* */ 71/* CALLS */ 72/* */ 73/* None */ 74/* */ 75/* CALLED BY */ 76/* */ 77/* _tx_initialize_kernel_enter ThreadX entry function */ 78/* */ 79/* RELEASE HISTORY */ 80/* */ 81/* DATE NAME DESCRIPTION */ 82/* */ 83/* 09-30-2020 Scott Larson Initial Version 6.1 */ 84/* */ 85/**************************************************************************/ 86// VOID _tx_initialize_low_level(VOID) 87// { 88 PUBLIC _tx_initialize_low_level 89_tx_initialize_low_level: 90 91 /* Disable interrupts during ThreadX initialization. */ 92 CPSID i 93 94 /* Set base of available memory to end of non-initialised RAM area. */ 95 LDR r0, =_tx_initialize_unused_memory // Build address of unused memory pointer 96 LDR r1, =__tx_free_memory_start // Build first free address 97 STR r1, [r0] // Setup first unused memory pointer 98 99 /* Setup Vector Table Offset Register. */ 100 MOV r0, #0xE000E000 // Build address of NVIC registers 101 LDR r1, =__vector_table // Pickup address of vector table 102 STR r1, [r0, #0xD08] // Set vector table address 103 104 /* Enable the cycle count register. */ 105// LDR r0, =0xE0001000 // Build address of DWT register 106// LDR r1, [r0] // Pickup the current value 107// ORR r1, r1, #1 // Set the CYCCNTENA bit 108// STR r1, [r0] // Enable the cycle count register 109 110 /* Set system stack pointer from vector value. */ 111 LDR r0, =_tx_thread_system_stack_ptr // Build address of system stack pointer 112 LDR r1, =__vector_table // Pickup address of vector table 113 LDR r1, [r1] // Pickup reset stack pointer 114 STR r1, [r0] // Save system stack pointer 115 116 /* Configure SysTick. */ 117 MOV r0, #0xE000E000 // Build address of NVIC registers 118 LDR r1, =SYSTICK_CYCLES 119 STR r1, [r0, #0x14] // Setup SysTick Reload Value 120 MOV r1, #0x7 // Build SysTick Control Enable Value 121 STR r1, [r0, #0x10] // Setup SysTick Control 122 123 /* Configure handler priorities. */ 124 LDR r1, =0x00000000 // Rsrv, UsgF, BusF, MemM 125 STR r1, [r0, #0xD18] // Setup System Handlers 4-7 Priority Registers 126 LDR r1, =0xFF000000 // SVCl, Rsrv, Rsrv, Rsrv 127 STR r1, [r0, #0xD1C] // Setup System Handlers 8-11 Priority Registers 128 // Note: SVC must be lowest priority, which is 0xFF 129 LDR r1, =0x40FF0000 // SysT, PnSV, Rsrv, DbgM 130 STR r1, [r0, #0xD20] // Setup System Handlers 12-15 Priority Registers 131 // Note: PnSV must be lowest priority, which is 0xFF 132 133 /* Return to caller. */ 134 BX lr 135// } 136 137 138/* Define shells for each of the unused vectors. */ 139 140 PUBLIC __tx_BadHandler 141__tx_BadHandler: 142 B __tx_BadHandler 143 144 145 PUBLIC __tx_IntHandler 146__tx_IntHandler: 147// VOID InterruptHandler (VOID) 148// { 149 PUSH {r0,lr} // Save LR (and dummy r0 to maintain stack alignment) 150#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) 151 BL _tx_execution_isr_enter // Call the ISR enter function 152#endif 153 /* Do interrupt handler work here */ 154 /* .... */ 155#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) 156 BL _tx_execution_isr_exit // Call the ISR exit function 157#endif 158 POP {r0,lr} 159 BX lr 160// } 161 162 163 PUBLIC __tx_SysTickHandler 164 PUBLIC SysTick_Handler 165SysTick_Handler: 166__tx_SysTickHandler: 167// VOID TimerInterruptHandler (VOID) 168// { 169 PUSH {r0,lr} // Save LR (and dummy r0 to maintain stack alignment) 170#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) 171 BL _tx_execution_isr_enter // Call the ISR enter function 172#endif 173 BL _tx_timer_interrupt 174#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) 175 BL _tx_execution_isr_exit // Call the ISR exit function 176#endif 177 POP {r0,lr} 178 BX lr 179// } 180 181 PUBLIC HardFault_Handler 182HardFault_Handler: 183 B HardFault_Handler 184 185 186 PUBLIC UsageFault_Handler 187UsageFault_Handler: 188 CPSID i // Disable interrupts 189 // Check for stack limit fault 190 LDR r0, =0xE000ED28 // CFSR address 191 LDR r1,[r0] // Pick up CFSR 192 TST r1, #0x00100000 // Check for Stack Overflow 193_unhandled_usage_loop 194 BEQ _unhandled_usage_loop // If not stack overflow then loop 195 196 // Handle stack overflow 197 STR r1, [r0] // Clear CFSR flag(s) 198 199#ifdef __ARMVFP__ 200 LDR r0, =0xE000EF34 // Cleanup FPU context: Load FPCCR address 201 LDR r1, [r0] // Load FPCCR 202 BIC r1, r1, #1 // Clear the lazy preservation active bit 203 STR r1, [r0] // Store the value 204#endif 205 206 LDR r0, =_tx_thread_current_ptr // Build current thread pointer address 207 LDR r0,[r0] // Pick up current thread pointer 208 PUSH {r0,lr} // Save LR (and r0 to maintain stack alignment) 209 BL _tx_thread_stack_error_handler // Call ThreadX/user handler 210 POP {r0,lr} // Restore LR and dummy reg 211 212#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) 213 // Call the thread exit function to indicate the thread is no longer executing. 214 PUSH {r0, lr} // Save LR (and r0 just for alignment) 215 BL _tx_execution_thread_exit // Call the thread exit function 216 POP {r0, lr} // Recover LR 217#endif 218 219 MOV r1, #0 // Build NULL value 220 LDR r0, =_tx_thread_current_ptr // Pickup address of current thread pointer 221 STR r1, [r0] // Clear current thread pointer 222 223 // Return from UsageFault_Handler exception 224 LDR r0, =0xE000ED04 // Load ICSR 225 LDR r1, =0x10000000 // Set PENDSVSET bit 226 STR r1, [r0] // Store ICSR 227 DSB // Wait for memory access to complete 228 CPSIE i // Enable interrupts 229 BX lr // Return from exception 230 231 232 PUBLIC __tx_NMIHandler 233__tx_NMIHandler: 234 B __tx_NMIHandler 235 236 237 PUBLIC __tx_DBGHandler 238__tx_DBGHandler: 239 B __tx_DBGHandler 240 241 END 242