startup_gcc.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. //*****************************************************************************
  2. // startup_gcc.c
  3. //
  4. // Startup code for use with GCC.
  5. //
  6. // Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
  7. //
  8. //
  9. // Redistribution and use in source and binary forms, with or without
  10. // modification, are permitted provided that the following conditions
  11. // are met:
  12. //
  13. // Redistributions of source code must retain the above copyright
  14. // notice, this list of conditions and the following disclaimer.
  15. //
  16. // Redistributions in binary form must reproduce the above copyright
  17. // notice, this list of conditions and the following disclaimer in the
  18. // documentation and/or other materials provided with the
  19. // distribution.
  20. //
  21. // Neither the name of Texas Instruments Incorporated nor the names of
  22. // its contributors may be used to endorse or promote products derived
  23. // from this software without specific prior written permission.
  24. //
  25. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  26. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  28. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  29. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  30. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  31. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  32. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  33. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  34. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  35. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36. //
  37. //*****************************************************************************
  38. #include <stdint.h>
  39. #include "inc/hw_nvic.h"
  40. #include "inc/hw_types.h"
  41. #include "fault_registers.h"
  42. //*****************************************************************************
  43. //
  44. // The following are constructs created by the linker, indicating where the
  45. // the "data" and "bss" segments reside in memory. The initializers for the
  46. // for the "data" segment resides immediately following the "text" segment.
  47. //
  48. //*****************************************************************************
  49. extern uint32_t _data;
  50. extern uint32_t _edata;
  51. extern uint32_t _bss;
  52. extern uint32_t _ebss;
  53. extern uint32_t _estack;
  54. //*****************************************************************************
  55. //
  56. // Forward declaration of the default fault handlers.
  57. //
  58. //*****************************************************************************
  59. #ifndef BOOTLOADER
  60. __attribute__ ((section (".boot")))
  61. #endif
  62. void ResetISR(void);
  63. #ifdef DEBUG
  64. static void NmiSR(void) __attribute__( ( naked ) );
  65. static void FaultISR( void ) __attribute__( ( naked ) );
  66. void HardFault_HandlerC(uint32_t *pulFaultStackAddress);
  67. static void BusFaultHandler(void) __attribute__( ( naked ) );
  68. #endif
  69. static void IntDefaultHandler(void) __attribute__( ( naked ) );
  70. //*****************************************************************************
  71. //
  72. // External declaration for the freeRTOS handlers
  73. //
  74. //*****************************************************************************
  75. #ifdef USE_FREERTOS
  76. extern void vPortSVCHandler(void);
  77. extern void xPortPendSVHandler(void);
  78. extern void xPortSysTickHandler(void);
  79. #endif
  80. //*****************************************************************************
  81. //
  82. // The entry point for the application.
  83. //
  84. //*****************************************************************************
  85. extern int main(void);
  86. //*****************************************************************************
  87. //
  88. // The vector table. Note that the proper constructs must be placed on this to
  89. // ensure that it ends up at physical address 0x0000.0000.
  90. //
  91. //*****************************************************************************
  92. __attribute__ ((section(".intvecs")))
  93. void (* const g_pfnVectors[256])(void) =
  94. {
  95. (void (*)(void))((uint32_t)&_estack), // The initial stack pointer
  96. ResetISR, // The reset handler
  97. #ifdef DEBUG
  98. NmiSR, // The NMI handler
  99. FaultISR, // The hard fault handler
  100. #else
  101. IntDefaultHandler, // The NMI handler
  102. IntDefaultHandler, // The hard fault handler
  103. #endif
  104. IntDefaultHandler, // The MPU fault handler
  105. #ifdef DEBUG
  106. BusFaultHandler, // The bus fault handler
  107. #else
  108. IntDefaultHandler, // The bus fault handler
  109. #endif
  110. IntDefaultHandler, // The usage fault handler
  111. 0, // Reserved
  112. 0, // Reserved
  113. 0, // Reserved
  114. 0, // Reserved
  115. #ifdef USE_FREERTOS
  116. vPortSVCHandler, // SVCall handler
  117. #else
  118. IntDefaultHandler, // SVCall handler
  119. #endif
  120. IntDefaultHandler, // Debug monitor handler
  121. 0, // Reserved
  122. #ifdef USE_FREERTOS
  123. xPortPendSVHandler, // The PendSV handler
  124. xPortSysTickHandler, // The SysTick handler
  125. #else
  126. IntDefaultHandler, // The PendSV handler
  127. IntDefaultHandler, // The SysTick handler
  128. #endif
  129. IntDefaultHandler, // GPIO Port A
  130. IntDefaultHandler, // GPIO Port B
  131. IntDefaultHandler, // GPIO Port C
  132. IntDefaultHandler, // GPIO Port D
  133. 0, // Reserved
  134. IntDefaultHandler, // UART0 Rx and Tx
  135. IntDefaultHandler, // UART1 Rx and Tx
  136. 0, // Reserved
  137. IntDefaultHandler, // I2C0 Master and Slave
  138. 0,0,0,0,0, // Reserved
  139. IntDefaultHandler, // ADC Channel 0
  140. IntDefaultHandler, // ADC Channel 1
  141. IntDefaultHandler, // ADC Channel 2
  142. IntDefaultHandler, // ADC Channel 3
  143. IntDefaultHandler, // Watchdog Timer
  144. IntDefaultHandler, // Timer 0 subtimer A
  145. IntDefaultHandler, // Timer 0 subtimer B
  146. IntDefaultHandler, // Timer 1 subtimer A
  147. IntDefaultHandler, // Timer 1 subtimer B
  148. IntDefaultHandler, // Timer 2 subtimer A
  149. IntDefaultHandler, // Timer 2 subtimer B
  150. 0,0,0,0, // Reserved
  151. IntDefaultHandler, // Flash
  152. 0,0,0,0,0, // Reserved
  153. IntDefaultHandler, // Timer 3 subtimer A
  154. IntDefaultHandler, // Timer 3 subtimer B
  155. 0,0,0,0,0,0,0,0,0, // Reserved
  156. IntDefaultHandler, // uDMA Software Transfer
  157. IntDefaultHandler, // uDMA Error
  158. 0,0,0,0,0,0,0,0,0,0, // Reserved
  159. 0,0,0,0,0,0,0,0,0,0, // Reserved
  160. 0,0,0,0,0,0,0,0,0,0, // Reserved
  161. 0,0,0,0,0,0,0,0,0,0, // Reserved
  162. 0,0,0,0,0,0,0,0,0,0, // Reserved
  163. 0,0,0,0,0,0,0,0,0,0, // Reserved
  164. 0,0,0,0,0,0,0,0,0,0, // Reserved
  165. 0,0,0,0,0,0,0,0,0,0, // Reserved
  166. 0,0,0,0,0,0,0,0,0,0, // Reserved
  167. 0,0,0,0,0,0,0,0,0,0, // Reserved
  168. IntDefaultHandler, // SHA
  169. 0,0, // Reserved
  170. IntDefaultHandler, // AES
  171. 0, // Reserved
  172. IntDefaultHandler, // DES
  173. 0,0,0,0,0, // Reserved
  174. IntDefaultHandler, // SDHost
  175. 0, // Reserved
  176. IntDefaultHandler, // I2S
  177. 0, // Reserved
  178. IntDefaultHandler, // Camera
  179. 0,0,0,0,0,0,0, // Reserved
  180. IntDefaultHandler, // NWP to APPS Interrupt
  181. IntDefaultHandler, // Power, Reset and Clock module
  182. 0,0, // Reserved
  183. IntDefaultHandler, // Shared SPI
  184. IntDefaultHandler, // Generic SPI
  185. IntDefaultHandler, // Link SPI
  186. 0,0,0,0,0,0,0,0,0,0, // Reserved
  187. 0,0,0,0,0,0,0,0,0,0, // Reserved
  188. 0,0,0,0,0,0,0,0,0,0, // Reserved
  189. 0,0,0,0,0,0,0,0,0,0, // Reserved
  190. 0,0,0,0,0,0,0,0,0,0, // Reserved
  191. 0,0,0,0,0,0,0,0,0,0, // Reserved
  192. 0,0 // Reserved
  193. };
  194. //*****************************************************************************
  195. //
  196. // This is the code that gets called when the processor first starts execution
  197. // following a reset event. Only the absolutely necessary set is performed,
  198. // after which the application supplied entry() routine is called. Any fancy
  199. // actions (such as making decisions based on the reset cause register, and
  200. // resetting the bits in that register) are left solely in the hands of the
  201. // application.
  202. //
  203. //*****************************************************************************
  204. void ResetISR(void)
  205. {
  206. #if defined(DEBUG) && !defined(BOOTLOADER)
  207. {
  208. //
  209. // Fill the main stack with a known value so that
  210. // we can measure the main stack high water mark
  211. //
  212. __asm volatile
  213. (
  214. "ldr r0, =_stack \n"
  215. "ldr r1, =_estack \n"
  216. "mov r2, #0x55555555 \n"
  217. ".thumb_func \n"
  218. "fill_loop: \n"
  219. "cmp r0, r1 \n"
  220. "it lt \n"
  221. "strlt r2, [r0], #4 \n"
  222. "blt fill_loop \n"
  223. );
  224. }
  225. #endif
  226. {
  227. // Get the initial stack pointer location from the vector table
  228. // and write this value to the msp register
  229. __asm volatile
  230. (
  231. "ldr r0, =_text \n"
  232. "ldr r0, [r0] \n"
  233. "msr msp, r0 \n"
  234. );
  235. }
  236. {
  237. //
  238. // Zero fill the bss segment.
  239. //
  240. __asm volatile
  241. (
  242. "ldr r0, =_bss \n"
  243. "ldr r1, =_ebss \n"
  244. "mov r2, #0 \n"
  245. ".thumb_func \n"
  246. "zero_loop: \n"
  247. "cmp r0, r1 \n"
  248. "it lt \n"
  249. "strlt r2, [r0], #4 \n"
  250. "blt zero_loop \n"
  251. );
  252. }
  253. {
  254. //
  255. // Call the application's entry point.
  256. //
  257. main();
  258. }
  259. }
  260. #ifdef DEBUG
  261. //*****************************************************************************
  262. //
  263. // This is the code that gets called when the processor receives a NMI. This
  264. // simply enters an infinite loop, preserving the system state for examination
  265. // by a debugger.
  266. //
  267. //*****************************************************************************
  268. static void NmiSR(void)
  269. {
  270. // Break into the debugger
  271. __asm volatile ("bkpt #0 \n");
  272. //
  273. // Enter an infinite loop.
  274. //
  275. for ( ; ; )
  276. {
  277. }
  278. }
  279. //*****************************************************************************
  280. //
  281. // This is the code that gets called when the processor receives a hard fault
  282. // interrupt. This simply enters an infinite loop, preserving the system state
  283. // for examination by a debugger.
  284. //
  285. //*****************************************************************************
  286. static void FaultISR(void)
  287. {
  288. /*
  289. * Get the appropriate stack pointer, depending on our mode,
  290. * and use it as the parameter to the C handler. This function
  291. * will never return
  292. */
  293. __asm volatile
  294. (
  295. "movs r0, #4 \n"
  296. "mov r1, lr \n"
  297. "tst r0, r1 \n"
  298. "beq _msp \n"
  299. "mrs r0, psp \n"
  300. "b HardFault_HandlerC \n"
  301. "_msp: \n"
  302. "mrs r0, msp \n"
  303. "b HardFault_HandlerC \n"
  304. ) ;
  305. }
  306. //***********************************************************************************
  307. // HardFaultHandler_C:
  308. // This is called from the FaultISR with a pointer the Fault stack
  309. // as the parameter. We can then read the values from the stack and place them
  310. // into local variables for ease of reading.
  311. // We then read the various Fault Status and Address Registers to help decode
  312. // cause of the fault.
  313. // The function ends with a BKPT instruction to force control back into the debugger
  314. //***********************************************************************************
  315. void HardFault_HandlerC(uint32_t *pulFaultStackAddress)
  316. {
  317. volatile uint32_t r0 ;
  318. volatile uint32_t r1 ;
  319. volatile uint32_t r2 ;
  320. volatile uint32_t r3 ;
  321. volatile uint32_t r12 ;
  322. volatile uint32_t lr ;
  323. volatile uint32_t pc ;
  324. volatile uint32_t psr ;
  325. volatile _CFSR_t _CFSR ;
  326. volatile _HFSR_t _HFSR ;
  327. volatile uint32_t _BFAR ;
  328. r0 = pulFaultStackAddress[0];
  329. r1 = pulFaultStackAddress[1];
  330. r2 = pulFaultStackAddress[2];
  331. r3 = pulFaultStackAddress[3];
  332. r12 = pulFaultStackAddress[4];
  333. lr = pulFaultStackAddress[5];
  334. pc = pulFaultStackAddress[6];
  335. psr = pulFaultStackAddress[7];
  336. // Configurable Fault Status Register
  337. // Consists of MMSR, BFSR and UFSR
  338. _CFSR = (*((volatile _CFSR_t *)(0xE000ED28)));
  339. // Hard Fault Status Register
  340. _HFSR = (*((volatile _HFSR_t *)(0xE000ED2C)));
  341. // Bus Fault Address Register
  342. _BFAR = (*((volatile uint32_t *)(0xE000ED38)));
  343. // Break into the debugger
  344. __asm volatile ("bkpt #0 \n");
  345. for ( ; ; )
  346. {
  347. // Keep the compiler happy
  348. (void)r0, (void)r1, (void)r2, (void)r3, (void)r12, (void)lr, (void)pc, (void)psr;
  349. (void)_CFSR, (void)_HFSR, (void)_BFAR;
  350. }
  351. }
  352. //*****************************************************************************
  353. //
  354. // This is the code that gets called when the processor receives an unexpected
  355. // interrupt. This simply enters an infinite loop, preserving the system state
  356. // for examination by a debugger.
  357. //
  358. //*****************************************************************************
  359. static void BusFaultHandler(void)
  360. {
  361. // Break into the debugger
  362. __asm volatile ("bkpt #0 \n");
  363. //
  364. // Enter an infinite loop.
  365. //
  366. for ( ; ; )
  367. {
  368. }
  369. }
  370. #endif
  371. //*****************************************************************************
  372. //
  373. // This is the code that gets called when the processor receives an unexpected
  374. // interrupt. This simply enters an infinite loop, preserving the system state
  375. // for examination by a debugger.
  376. //
  377. //*****************************************************************************
  378. static void IntDefaultHandler(void)
  379. {
  380. #ifdef DEBUG
  381. // Break into the debugger
  382. __asm volatile ("bkpt #0 \n");
  383. #endif
  384. //
  385. // Enter an infinite loop.
  386. //
  387. for ( ; ; )
  388. {
  389. }
  390. }