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