]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Demo/FreeRTOS_Plus_UDP_and_CLI_LPC1830_GCC/cr_startup_lpc18xx.c
13853fc1d7a158d0731e14c6d53387e1c22b0a01
[freertos] / FreeRTOS-Plus / Demo / FreeRTOS_Plus_UDP_and_CLI_LPC1830_GCC / cr_startup_lpc18xx.c
1 // *****************************************************************************\r
2 //   +--+\r
3 //   | ++----+\r
4 //   +-++    |\r
5 //     |     |\r
6 //   +-+--+  |\r
7 //   | +--+--+\r
8 //   +----+    Copyright (c) 2011-12 Code Red Technologies Ltd.\r
9 //\r
10 // LPC43xx Microcontroller Startup code for use with Red Suite\r
11 //\r
12 // Version : 120430\r
13 //\r
14 // Software License Agreement\r
15 //\r
16 // The software is owned by Code Red Technologies and/or its suppliers, and is\r
17 // protected under applicable copyright laws.  All rights are reserved.  Any\r
18 // use in violation of the foregoing restrictions may subject the user to criminal\r
19 // sanctions under applicable laws, as well as to civil liability for the breach\r
20 // of the terms and conditions of this license.\r
21 //\r
22 // THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
23 // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
24 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
25 // USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT\r
26 // TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH\r
27 // CODE RED TECHNOLOGIES LTD.\r
28 //\r
29 // *****************************************************************************\r
30 \r
31 #include "stdint.h"\r
32 \r
33 #if defined(__cplusplus)\r
34 #ifdef __REDLIB__\r
35 #error Redlib does not support C++\r
36 #else\r
37 // *****************************************************************************\r
38 //\r
39 // The entry point for the C++ library startup\r
40 //\r
41 // *****************************************************************************\r
42 extern "C" {\r
43 extern void __libc_init_array(void);\r
44 \r
45 }\r
46 #endif\r
47 #endif\r
48 \r
49 #define WEAK __attribute__ ((weak))\r
50 #define ALIAS(f) __attribute__ ((weak, alias(# f)))\r
51 \r
52 // Code Red - if CMSIS is being used, then SystemInit() routine\r
53 // will be called by startup code rather than in application's main()\r
54 extern void SystemInit(void);\r
55 \r
56 // *****************************************************************************\r
57 #if defined(__cplusplus)\r
58 extern "C" {\r
59 #endif\r
60 \r
61 // *****************************************************************************\r
62 //\r
63 // Forward declaration of the default handlers. These are aliased.\r
64 // When the application defines a handler (with the same name), this will\r
65 // automatically take precedence over these weak definitions\r
66 //\r
67 // *****************************************************************************\r
68 void ResetISR(void);\r
69 WEAK void NMI_Handler(void);\r
70 WEAK void HardFault_Handler(void);\r
71 WEAK void MemManage_Handler(void);\r
72 WEAK void BusFault_Handler(void);\r
73 WEAK void UsageFault_Handler(void);\r
74 WEAK void SVC_Handler(void);\r
75 WEAK void DebugMon_Handler(void);\r
76 WEAK void PendSV_Handler(void);\r
77 WEAK void SysTick_Handler(void);\r
78 WEAK void IntDefaultHandler(void);\r
79 \r
80 //*****************************************************************************\r
81 //\r
82 // Forward declaration of the specific IRQ handlers. These are aliased\r
83 // to the IntDefaultHandler, which is a 'forever' loop. When the application\r
84 // defines a handler (with the same name), this will automatically take\r
85 // precedence over these weak definitions\r
86 //\r
87 //*****************************************************************************\r
88 void DAC_IRQHandler(void) ALIAS(IntDefaultHandler);\r
89 void MX_CORE_IRQHandler(void) ALIAS(IntDefaultHandler);\r
90 void DMA_IRQHandler(void) ALIAS(IntDefaultHandler);\r
91 void FLASHEEPROM_IRQHandler(void) ALIAS(IntDefaultHandler);\r
92 void ETH_IRQHandler(void) ALIAS(IntDefaultHandler);\r
93 void SDIO_IRQHandler(void) ALIAS(IntDefaultHandler);\r
94 void LCD_IRQHandler(void) ALIAS(IntDefaultHandler);\r
95 void USB0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
96 void USB1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
97 void SCT_IRQHandler(void) ALIAS(IntDefaultHandler);\r
98 void RIT_IRQHandler(void) ALIAS(IntDefaultHandler);\r
99 void TIMER0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
100 void TIMER1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
101 void TIMER2_IRQHandler(void) ALIAS(IntDefaultHandler);\r
102 void TIMER3_IRQHandler(void) ALIAS(IntDefaultHandler);\r
103 void MCPWM_IRQHandler(void) ALIAS(IntDefaultHandler);\r
104 void ADC0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
105 void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
106 void I2C1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
107 void SPI_IRQHandler (void) ALIAS(IntDefaultHandler);\r
108 void ADC1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
109 void SSP0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
110 void SSP1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
111 void UART0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
112 void UART1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
113 void UART2_IRQHandler(void) ALIAS(IntDefaultHandler);\r
114 void UART3_IRQHandler(void) ALIAS(IntDefaultHandler);\r
115 void I2S0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
116 void I2S1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
117 void SPIFI_IRQHandler(void) ALIAS(IntDefaultHandler);\r
118 void SGPIO_IRQHandler(void) ALIAS(IntDefaultHandler);\r
119 void GPIO0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
120 void GPIO1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
121 void GPIO2_IRQHandler(void) ALIAS(IntDefaultHandler);\r
122 void GPIO3_IRQHandler(void) ALIAS(IntDefaultHandler);\r
123 void GPIO4_IRQHandler(void) ALIAS(IntDefaultHandler);\r
124 void GPIO5_IRQHandler(void) ALIAS(IntDefaultHandler);\r
125 void GPIO6_IRQHandler(void) ALIAS(IntDefaultHandler);\r
126 void GPIO7_IRQHandler(void) ALIAS(IntDefaultHandler);\r
127 void GINT0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
128 void GINT1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
129 void EVRT_IRQHandler(void) ALIAS(IntDefaultHandler);\r
130 void CAN1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
131 void ATIMER_IRQHandler(void) ALIAS(IntDefaultHandler);\r
132 void RTC_IRQHandler(void) ALIAS(IntDefaultHandler);\r
133 void WDT_IRQHandler(void) ALIAS(IntDefaultHandler);\r
134 void CAN0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
135 void QEI_IRQHandler(void) ALIAS(IntDefaultHandler);\r
136 \r
137 //*****************************************************************************\r
138 //\r
139 // The entry point for the application.\r
140 // __main() is the entry point for Redlib based applications\r
141 // main() is the entry point for Newlib based applications\r
142 //\r
143 //*****************************************************************************\r
144 #if defined (__REDLIB__)\r
145 extern void __main(void);\r
146 #endif\r
147 extern int main(void);\r
148 //*****************************************************************************\r
149 //\r
150 // External declaration for the pointer to the stack top from the Linker Script\r
151 //\r
152 //*****************************************************************************\r
153 extern void _vStackTop(void);\r
154 \r
155 //*****************************************************************************\r
156 #if defined (__cplusplus)\r
157 } // extern "C"\r
158 #endif\r
159 //*****************************************************************************\r
160 //\r
161 // The vector table.\r
162 // This relies on the linker script to place at correct location in memory.\r
163 //\r
164 // *****************************************************************************\r
165 extern void(*const g_pfnVectors[]) (void);\r
166 __attribute__ ((section(".isr_vector")))\r
167 void(*const g_pfnVectors[]) (void) = {\r
168         // Core Level - CM4/CM3\r
169         &_vStackTop,                    // The initial stack pointer\r
170         ResetISR,                                               // The reset handler\r
171         NMI_Handler,                                    // The NMI handler\r
172         HardFault_Handler,                              // The hard fault handler\r
173         MemManage_Handler,                              // The MPU fault handler\r
174         BusFault_Handler,                               // The bus fault handler\r
175         UsageFault_Handler,                             // The usage fault handler\r
176         0,                                                              // Reserved\r
177         0,                                                              // Reserved\r
178         0,                                                              // Reserved\r
179         0,                                                              // Reserved\r
180         SVC_Handler,                                    // SVCall handler\r
181         DebugMon_Handler,                               // Debug monitor handler\r
182         0,                                                              // Reserved\r
183         PendSV_Handler,                                 // The PendSV handler\r
184         SysTick_Handler,                                // The SysTick handler\r
185 \r
186         // Chip Level - LPC18xx/43xx\r
187         DAC_IRQHandler,                                 // 16 D/A Converter\r
188         MX_CORE_IRQHandler,                             // 17 CortexM4/M0 (LPC43XX ONLY)\r
189         DMA_IRQHandler,                                 // 18 General Purpose DMA\r
190         0,                                                              // 19 Reserved\r
191         FLASHEEPROM_IRQHandler,                 // 20 ORed flash Bank A, flash Bank B, EEPROM interrupts\r
192         ETH_IRQHandler,                                 // 21 Ethernet\r
193         SDIO_IRQHandler,                                // 22 SD/MMC\r
194         LCD_IRQHandler,                                 // 23 LCD\r
195         USB0_IRQHandler,                                // 24 USB0\r
196         USB1_IRQHandler,                                // 25 USB1\r
197         SCT_IRQHandler,                                 // 26 State Configurable Timer\r
198         RIT_IRQHandler,                                 // 27 Repetitive Interrupt Timer\r
199         TIMER0_IRQHandler,                              // 28 Timer0\r
200         TIMER1_IRQHandler,                              // 29 Timer 1\r
201         TIMER2_IRQHandler,                              // 30 Timer 2\r
202         TIMER3_IRQHandler,                              // 31 Timer 3\r
203         MCPWM_IRQHandler,                               // 32 Motor Control PWM\r
204         ADC0_IRQHandler,                                // 33 A/D Converter 0\r
205         I2C0_IRQHandler,                                // 34 I2C0\r
206         I2C1_IRQHandler,                                // 35 I2C1\r
207         SPI_IRQHandler,                                 // 36 SPI (LPC43XX ONLY)\r
208         ADC1_IRQHandler,                                // 37 A/D Converter 1\r
209         SSP0_IRQHandler,                                // 38 SSP0 \r
210         SSP1_IRQHandler,                                // 39 SSP1\r
211         UART0_IRQHandler,                               // 40 UART0\r
212         UART1_IRQHandler,                               // 41 UART1\r
213         UART2_IRQHandler,                               // 42 UART2\r
214         UART3_IRQHandler,                               // 43 USRT3\r
215         I2S0_IRQHandler,                                // 44 I2S0\r
216         I2S1_IRQHandler,                                // 45 I2S1\r
217         SPIFI_IRQHandler,                               // 46 SPI Flash Interface\r
218         SGPIO_IRQHandler,                               // 47 SGPIO (LPC43XX ONLY)\r
219         GPIO0_IRQHandler,                               // 48 GPIO0\r
220         GPIO1_IRQHandler,                               // 49 GPIO1\r
221         GPIO2_IRQHandler,                               // 50 GPIO2\r
222         GPIO3_IRQHandler,                               // 51 GPIO3 \r
223         GPIO4_IRQHandler,                               // 52 GPIO4\r
224         GPIO5_IRQHandler,                               // 53 GPIO5\r
225         GPIO6_IRQHandler,                               // 54 GPIO6\r
226         GPIO7_IRQHandler,                               // 55 GPIO7\r
227         GINT0_IRQHandler,                               // 56 GINT0\r
228         GINT1_IRQHandler,                               // 57 GINT1\r
229         EVRT_IRQHandler,                                // 58 Event Router\r
230         CAN1_IRQHandler,                                // 59 C_CAN1\r
231         0,                                                              // 60 Reserved\r
232         0,                                              // 61 Reserved \r
233         ATIMER_IRQHandler,                              // 62 ATIMER\r
234         RTC_IRQHandler,                                 // 63 RTC\r
235         0,                                                              // 64 Reserved\r
236         WDT_IRQHandler,                                 // 65 WDT\r
237         0,                                                              // 66 Reserved\r
238         CAN0_IRQHandler,                                // 67 C_CAN0\r
239         QEI_IRQHandler,                                 // 68 QEI\r
240 };\r
241 \r
242 //*****************************************************************************\r
243 // Functions to carry out the initialization of RW and BSS data sections. These\r
244 // are written as separate functions rather than being inlined within the\r
245 // ResetISR() function in order to cope with MCUs with multiple banks of\r
246 // memory.\r
247 //*****************************************************************************\r
248 __attribute__ ((section(".after_vectors")))\r
249 void data_init(unsigned int romstart, unsigned int start, unsigned int len) {\r
250         unsigned int *pulDest = (unsigned int*) start;\r
251         unsigned int *pulSrc = (unsigned int*) romstart;\r
252         unsigned int loop;\r
253         for (loop = 0; loop < len; loop = loop + 4)\r
254                 *pulDest++ = *pulSrc++;\r
255 }\r
256 \r
257 __attribute__ ((section(".after_vectors")))\r
258 void bss_init(unsigned int start, unsigned int len) {\r
259         unsigned int *pulDest = (unsigned int*) start;\r
260         unsigned int loop;\r
261         for (loop = 0; loop < len; loop = loop + 4)\r
262                 *pulDest++ = 0;\r
263 }\r
264 \r
265 //*****************************************************************************\r
266 // The following symbols are constructs generated by the linker, indicating\r
267 // the location of various points in the "Global Section Table". This table is\r
268 // created by the linker via the Code Red managed linker script mechanism. It\r
269 // contains the load address, execution address and length of each RW data\r
270 // section and the execution and length of each BSS (zero initialized) section.\r
271 //*****************************************************************************\r
272 extern unsigned int __data_section_table;\r
273 extern unsigned int __data_section_table_end;\r
274 extern unsigned int __bss_section_table;\r
275 extern unsigned int __bss_section_table_end;\r
276 \r
277 //*****************************************************************************\r
278 // Reset entry point for your code.\r
279 // Sets up a simple runtime environment and initializes the C/C++\r
280 // library.\r
281 //\r
282 //*****************************************************************************\r
283 void\r
284 ResetISR(void) {\r
285 \r
286 // *************************************************************\r
287 // The following conditional block of code manually resets as\r
288 // much of the peripheral set of the LPC18 as possible. This is\r
289 // done because the LPC18 does not provide a means of triggering\r
290 // a full system reset under debugger control, which can cause\r
291 // problems in certain circumstances when debugging.\r
292 //\r
293 // You can prevent this code block being included if you require\r
294 // (for example when creating a final executable which you will\r
295 // not debug) by setting the define 'DONT_RESET_ON_RESTART'.\r
296 //\r
297 #ifndef DONT_RESET_ON_RESTART\r
298 \r
299         // Disable interrupts\r
300         __asm volatile ("cpsid i");\r
301         // equivalent to CMSIS '__disable_irq()' function\r
302 \r
303         unsigned int *RESET_CONTROL = (unsigned int *) 0x40053100;\r
304         // LPC_RGU->RESET_CTRL0 @ 0x40053100\r
305         // LPC_RGU->RESET_CTRL1 @ 0x40053104\r
306         // Note that we do not use the CMSIS register access mechanism,\r
307         // as there is no guarantee that the project has been configured\r
308         // to use CMSIS.\r
309 \r
310         // Write to LPC_RGU->RESET_CTRL0\r
311         *(RESET_CONTROL+0) = 0x10DF0000;\r
312         // GPIO_RST|AES_RST|ETHERNET_RST|SDIO_RST|DMA_RST|\r
313         // USB1_RST|USB0_RST|LCD_RST\r
314 \r
315         // Write to LPC_RGU->RESET_CTRL1\r
316         *(RESET_CONTROL+1) = 0x00DFF7FF;\r
317         // CAN0_RST|CAN1_RST|I2S_RST|SSP1_RST|SSP0_RST|\r
318         // I2C1_RST|I2C0_RST|UART3_RST|UART1_RST|UART1_RST|UART0_RST|\r
319         // DAC_RST|ADC1_RST|ADC0_RST|QEI_RST|MOTOCONPWM_RST|SCT_RST|\r
320         // RITIMER_RST|TIMER3_RST|TIMER2_RST|TIMER1_RST|TIMER0_RST\r
321 \r
322         // Clear all pending interrupts in the NVIC\r
323         volatile unsigned int *NVIC_ICPR = (unsigned int *) 0xE000E280;\r
324         unsigned int irqpendloop;\r
325         for (irqpendloop = 0; irqpendloop < 8; irqpendloop++) {\r
326                 *(NVIC_ICPR+irqpendloop)= 0xFFFFFFFF;\r
327         }\r
328 \r
329         // Reenable interrupts\r
330         __asm volatile ("cpsie i");\r
331         // equivalent to CMSIS '__enable_irq()' function\r
332 \r
333 #endif  // ifndef DONT_RESET_ON_RESTART\r
334 // *************************************************************\r
335 \r
336 \r
337     //\r
338     // Copy the data sections from flash to SRAM.\r
339     //\r
340         unsigned int LoadAddr, ExeAddr, SectionLen;\r
341         unsigned int *SectionTableAddr;\r
342 \r
343         // Load base address of Global Section Table\r
344         SectionTableAddr = &__data_section_table;\r
345 \r
346     // Copy the data sections from flash to SRAM.\r
347         while (SectionTableAddr < &__data_section_table_end) {\r
348                 LoadAddr = *SectionTableAddr++;\r
349                 ExeAddr = *SectionTableAddr++;\r
350                 SectionLen = *SectionTableAddr++;\r
351                 data_init(LoadAddr, ExeAddr, SectionLen);\r
352         }\r
353         // At this point, SectionTableAddr = &__bss_section_table;\r
354         // Zero fill the bss segment\r
355         while (SectionTableAddr < &__bss_section_table_end) {\r
356                 ExeAddr = *SectionTableAddr++;\r
357                 SectionLen = *SectionTableAddr++;\r
358                 bss_init(ExeAddr, SectionLen);\r
359         }\r
360 \r
361         // ******************************\r
362         // Check to see if we are running the code from a non-zero\r
363         // address (eg RAM, external flash), in which case we need\r
364         // to modify the VTOR register to tell the CPU that the\r
365         // vector table is located at a non-0x0 address.\r
366 \r
367         // Note that we do not use the CMSIS register access mechanism,\r
368         // as there is no guarantee that the project has been configured\r
369         // to use CMSIS.\r
370         unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08;\r
371         if ((unsigned int *)g_pfnVectors!=(unsigned int *) 0x00000000) {\r
372                 // CMSIS : SCB->VTOR = <address of vector table>\r
373                 *pSCB_VTOR = (unsigned int)g_pfnVectors;\r
374         }\r
375 \r
376 #ifdef __USE_CMSIS\r
377         SystemInit();\r
378 #endif\r
379 \r
380 #if defined (__cplusplus)\r
381         //\r
382         // Call C++ library initialisation\r
383         //\r
384         __libc_init_array();\r
385 #endif\r
386 \r
387 #if defined (__REDLIB__)\r
388         // Call the Redlib library, which in turn calls main()\r
389         __main() ;\r
390 #else\r
391         main();\r
392 #endif\r
393 \r
394         //\r
395         // main() shouldn't return, but if it does, we'll just enter an infinite loop\r
396         //\r
397         while (1) {\r
398                 ;\r
399         }\r
400 }\r
401 \r
402 //*****************************************************************************\r
403 // Default exception handlers. Override the ones here by defining your own\r
404 // handler routines in your application code.\r
405 //*****************************************************************************\r
406 __attribute__ ((section(".after_vectors")))\r
407 void NMI_Handler(void)\r
408 {\r
409     while(1)\r
410     {\r
411     }\r
412 }\r
413 __attribute__ ((section(".after_vectors")))\r
414 void HardFault_Handler(void)\r
415 {\r
416     __asm volatile\r
417     (\r
418         " tst lr, #4                                                \n"\r
419         " ite eq                                                    \n"\r
420         " mrseq r0, msp                                             \n"\r
421         " mrsne r0, psp                                             \n"\r
422         " ldr r1, [r0, #24]                                         \n"\r
423         " ldr r2, handler2_address_const                            \n"\r
424         " bx r2                                                     \n"\r
425         " handler2_address_const: .word prvGetRegistersFromStack    \n"\r
426     );\r
427 }\r
428 \r
429 __attribute__ ((section(".after_vectors")))\r
430 void MemManage_Handler(void)\r
431 {\r
432     while(1)\r
433     {\r
434     }\r
435 }\r
436 __attribute__ ((section(".after_vectors")))\r
437 void BusFault_Handler(void)\r
438 {\r
439     while(1)\r
440     {\r
441     }\r
442 }\r
443 __attribute__ ((section(".after_vectors")))\r
444 void UsageFault_Handler(void)\r
445 {\r
446     while(1)\r
447     {\r
448     }\r
449 }\r
450 __attribute__ ((section(".after_vectors")))\r
451 void SVCall_Handler(void)\r
452 {\r
453     while(1)\r
454     {\r
455     }\r
456 }\r
457 __attribute__ ((section(".after_vectors")))\r
458 void DebugMon_Handler(void)\r
459 {\r
460     while(1)\r
461     {\r
462     }\r
463 }\r
464 __attribute__ ((section(".after_vectors")))\r
465 void PendSV_Handler(void)\r
466 {\r
467     while(1)\r
468     {\r
469     }\r
470 }\r
471 __attribute__ ((section(".after_vectors")))\r
472 void SysTick_Handler(void)\r
473 {\r
474     while(1)\r
475     {\r
476     }\r
477 }\r
478 \r
479 //*****************************************************************************\r
480 //\r
481 // Processor ends up here if an unexpected interrupt occurs or a specific\r
482 // handler is not present in the application code.\r
483 //\r
484 //*****************************************************************************\r
485 __attribute__ ((section(".after_vectors")))\r
486 void IntDefaultHandler(void)\r
487 {\r
488     while(1)\r
489     {\r
490     }\r
491 }\r
492 \r
493 /* Debug functions. */\r
494 void prvGetRegistersFromStack( uint32_t *pulFaultStackAddress )\r
495 {\r
496 /* These are volatile to try and prevent the compiler/linker optimising them\r
497 away as the variables never actually get used.  If the debugger won't show the\r
498 values of the variables, make them global my moving their declaration outside\r
499 of this function. */\r
500 volatile uint32_t r0;\r
501 volatile uint32_t r1;\r
502 volatile uint32_t r2;\r
503 volatile uint32_t r3;\r
504 volatile uint32_t r12;\r
505 volatile uint32_t lr; /* Link register. */\r
506 volatile uint32_t pc; /* Program counter. */\r
507 volatile uint32_t psr;/* Program status register. */\r
508 \r
509     r0 = pulFaultStackAddress[ 0 ];\r
510     r1 = pulFaultStackAddress[ 1 ];\r
511     r2 = pulFaultStackAddress[ 2 ];\r
512     r3 = pulFaultStackAddress[ 3 ];\r
513 \r
514     r12 = pulFaultStackAddress[ 4 ];\r
515     lr = pulFaultStackAddress[ 5 ];\r
516     pc = pulFaultStackAddress[ 6 ];\r
517     psr = pulFaultStackAddress[ 7 ];\r
518 \r
519     /* When the following line is hit, the variables contain the register values. */\r
520     for( ;; )\r
521     {\r
522         ( void ) r0;\r
523         ( void ) r1;\r
524         ( void ) r2;\r
525         ( void ) r3;\r
526         ( void ) r12;\r
527         ( void ) lr;\r
528         ( void ) pc;\r
529         ( void ) psr;\r
530     };\r
531 }\r