]> git.sur5r.net Git - freertos/blob - Demo/CORTEX_MPU_LPC1768_GCC_RedSuite/src/cr_startup_lpc17.c
First Red Suite project for FreeRTOS MPU.
[freertos] / Demo / CORTEX_MPU_LPC1768_GCC_RedSuite / src / cr_startup_lpc17.c
1 //*****************************************************************************\r
2 //   +--+       \r
3 //   | ++----+   \r
4 //   +-++    |  \r
5 //     |     |  \r
6 //   +-+--+  |   \r
7 //   | +--+--+  \r
8 //   +----+    Copyright (c) 2009 Code Red Technologies Ltd. \r
9 //\r
10 // Microcontroller Startup code for use with Red Suite\r
11 //\r
12 // Software License Agreement\r
13 // \r
14 // The software is owned by Code Red Technologies and/or its suppliers, and is \r
15 // protected under applicable copyright laws.  All rights are reserved.  Any \r
16 // use in violation of the foregoing restrictions may subject the user to criminal \r
17 // sanctions under applicable laws, as well as to civil liability for the breach \r
18 // of the terms and conditions of this license.\r
19 // \r
20 // THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
21 // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
22 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
23 // USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT\r
24 // TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH\r
25 // CODE RED TECHNOLOGIES LTD. \r
26 //\r
27 //*****************************************************************************\r
28 #define WEAK __attribute__ ((weak))\r
29 #define ALIAS(f) __attribute__ ((weak, alias (#f)))\r
30 \r
31 //*****************************************************************************\r
32 //\r
33 // Forward declaration of the default handlers.\r
34 //\r
35 //*****************************************************************************\r
36 void Reset_Handler(void);\r
37 void ResetISR(void) ALIAS(Reset_Handler);\r
38 static void NMI_Handler(void);\r
39 static void HardFault_Handler(void);\r
40 static void MemManage_Handler(void) __attribute__((naked));\r
41 static void BusFault_Handler(void) __attribute__((naked));\r
42 static void UsageFault_Handler(void) __attribute__((naked));\r
43 static void DebugMon_Handler(void);\r
44 \r
45 //*****************************************************************************\r
46 //\r
47 // Forward declaration of the specific IRQ handlers. These are aliased\r
48 // to the IntDefaultHandler, which is a 'forever' loop. When the application\r
49 // defines a handler (with the same name), this will automatically take \r
50 // precedence over these weak definitions\r
51 //\r
52 //*****************************************************************************\r
53 void WDT_IRQHandler(void) ALIAS(IntDefaultHandler);\r
54 void TIMER0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
55 void TIMER1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
56 void TIMER2_IRQHandler(void) ALIAS(IntDefaultHandler);\r
57 void TIMER3_IRQHandler(void) ALIAS(IntDefaultHandler);\r
58 void UART0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
59 void UART1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
60 void UART2_IRQHandler(void) ALIAS(IntDefaultHandler);\r
61 void UART3_IRQHandler(void) ALIAS(IntDefaultHandler);\r
62 void PWM1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
63 void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
64 void I2C1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
65 void I2C2_IRQHandler(void) ALIAS(IntDefaultHandler);\r
66 void SPI_IRQHandler(void) ALIAS(IntDefaultHandler);\r
67 void SSP0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
68 void SSP1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
69 void PLL0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
70 void RTC_IRQHandler(void) ALIAS(IntDefaultHandler);\r
71 void EINT0_IRQHandler(void) ALIAS(IntDefaultHandler);\r
72 void EINT1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
73 void EINT2_IRQHandler(void) ALIAS(IntDefaultHandler);\r
74 void EINT3_IRQHandler(void) ALIAS(IntDefaultHandler);\r
75 void ADC_IRQHandler(void) ALIAS(IntDefaultHandler);\r
76 void BOD_IRQHandler(void) ALIAS(IntDefaultHandler);\r
77 void USB_IRQHandler(void) ALIAS(IntDefaultHandler);\r
78 void CAN_IRQHandler(void) ALIAS(IntDefaultHandler);\r
79 void DMA_IRQHandler(void) ALIAS(IntDefaultHandler);\r
80 void I2S_IRQHandler(void) ALIAS(IntDefaultHandler);\r
81 void ENET_IRQHandler(void) ALIAS(IntDefaultHandler);\r
82 void RIT_IRQHandler(void) ALIAS(IntDefaultHandler);\r
83 void MCPWM_IRQHandler(void) ALIAS(IntDefaultHandler);\r
84 void QEI_IRQHandler(void) ALIAS(IntDefaultHandler);\r
85 void PLL1_IRQHandler(void) ALIAS(IntDefaultHandler);\r
86 \r
87 extern void xPortSysTickHandler(void);\r
88 extern void xPortPendSVHandler(void);\r
89 extern void vPortSVCHandler( void );\r
90 \r
91 \r
92 //*****************************************************************************\r
93 //\r
94 // The entry point for the C++ library startup\r
95 //\r
96 //*****************************************************************************\r
97 extern WEAK void __libc_init_array(void);\r
98 \r
99 //*****************************************************************************\r
100 //\r
101 // The entry point for the application.\r
102 // __main() is the entry point for redlib based applications\r
103 // main() is the entry point for newlib based applications\r
104 //\r
105 //*****************************************************************************\r
106 extern WEAK void __main(void);\r
107 extern WEAK void main(void);\r
108 //*****************************************************************************\r
109 //\r
110 // External declaration for the pointer to the stack top from the Linker Script\r
111 //\r
112 //*****************************************************************************\r
113 extern void _vStackTop;\r
114 \r
115 //*****************************************************************************\r
116 //\r
117 // The vector table.\r
118 // This relies on the linker script to place at correct location in memory.\r
119 //\r
120 //*****************************************************************************\r
121 __attribute__ ((section(".isr_vector")))\r
122 void (* const g_pfnVectors[])(void) =\r
123 {\r
124         // Core Level - CM3\r
125         (void *)&_vStackTop,                                    // The initial stack pointer\r
126         Reset_Handler,                                                  // The reset handler\r
127         NMI_Handler,                                                    // The NMI handler\r
128         HardFault_Handler,                                              // The hard fault handler\r
129         MemManage_Handler,                                              // The MPU fault handler\r
130         BusFault_Handler,                                               // The bus fault handler\r
131         UsageFault_Handler,                                             // The usage fault handler\r
132         0,                                                                              // Reserved\r
133         0,                                                                              // Reserved\r
134         0,                                                                              // Reserved\r
135         0,                                                                              // Reserved\r
136         vPortSVCHandler,                        // SVCall handler\r
137         DebugMon_Handler,                                               // Debug monitor handler\r
138         0,                                                                              // Reserved\r
139         xPortPendSVHandler,                     // The PendSV handler\r
140         xPortSysTickHandler,                    // The SysTick handler\r
141 \r
142         // Chip Level - LPC17\r
143         WDT_IRQHandler,                                                 // 16, 0x40 - WDT\r
144         TIMER0_IRQHandler,                                              // 17, 0x44 - TIMER0\r
145         TIMER1_IRQHandler,                                              // 18, 0x48 - TIMER1\r
146         TIMER2_IRQHandler,                                              // 19, 0x4c - TIMER2\r
147         TIMER3_IRQHandler,                                              // 20, 0x50 - TIMER3\r
148         UART0_IRQHandler,                                               // 21, 0x54 - UART0\r
149         UART1_IRQHandler,                                               // 22, 0x58 - UART1\r
150         UART2_IRQHandler,                                               // 23, 0x5c - UART2\r
151         UART3_IRQHandler,                                               // 24, 0x60 - UART3\r
152         PWM1_IRQHandler,                                                // 25, 0x64 - PWM1\r
153         I2C0_IRQHandler,                                                // 26, 0x68 - I2C0\r
154         I2C1_IRQHandler,                                                // 27, 0x6c - I2C1\r
155         I2C2_IRQHandler,                                                // 28, 0x70 - I2C2\r
156         SPI_IRQHandler,                                                 // 29, 0x74 - SPI\r
157         SSP0_IRQHandler,                                                // 30, 0x78 - SSP0\r
158         SSP1_IRQHandler,                                                // 31, 0x7c - SSP1\r
159         PLL0_IRQHandler,                                                // 32, 0x80 - PLL0 (Main PLL)\r
160         RTC_IRQHandler,                                                 // 33, 0x84 - RTC\r
161         EINT0_IRQHandler,                                               // 34, 0x88 - EINT0\r
162         EINT1_IRQHandler,                                               // 35, 0x8c - EINT1\r
163         EINT2_IRQHandler,                                               // 36, 0x90 - EINT2\r
164         EINT3_IRQHandler,                                               // 37, 0x94 - EINT3\r
165         ADC_IRQHandler,                                                 // 38, 0x98 - ADC\r
166         BOD_IRQHandler,                                                 // 39, 0x9c - BOD\r
167         USB_IRQHandler,                                                 // 40, 0xA0 - USB\r
168         CAN_IRQHandler,                                                 // 41, 0xa4 - CAN\r
169         DMA_IRQHandler,                                                 // 42, 0xa8 - GP DMA\r
170         I2S_IRQHandler,                                                 // 43, 0xac - I2S\r
171         ENET_IRQHandler,                                // Ethernet.\r
172         RIT_IRQHandler,                                                 // 45, 0xb4 - RITINT\r
173         MCPWM_IRQHandler,                                               // 46, 0xb8 - Motor Control PWM\r
174         QEI_IRQHandler,                                                 // 47, 0xbc - Quadrature Encoder\r
175         PLL1_IRQHandler,                                                // 48, 0xc0 - PLL1 (USB PLL)\r
176 };\r
177 \r
178 //*****************************************************************************\r
179 //\r
180 // The following are constructs created by the linker, indicating where the\r
181 // the "data" and "bss" segments reside in memory.  The initializers for the\r
182 // for the "data" segment resides immediately following the "text" segment.\r
183 //\r
184 //*****************************************************************************\r
185 extern unsigned long _etext;\r
186 extern unsigned long _data;\r
187 extern unsigned long _edata;\r
188 extern unsigned long _bss;\r
189 extern unsigned long _ebss;\r
190 \r
191 //*****************************************************************************\r
192 // Reset entry point for your code.\r
193 // Sets up a simple runtime environment and initializes the C/C++\r
194 // library.\r
195 //\r
196 //*****************************************************************************\r
197 void Reset_Handler(void)\r
198 {\r
199     unsigned long *pulSrc, *pulDest;\r
200 \r
201     //\r
202     // Copy the data segment initializers from flash to SRAM.\r
203     //\r
204     pulSrc = &_etext;\r
205     for(pulDest = &_data; pulDest < &_edata; )\r
206     {\r
207         *pulDest++ = *pulSrc++;\r
208     }\r
209 \r
210     //\r
211     // Zero fill the bss segment.  This is done with inline assembly since this\r
212     // will clear the value of pulDest if it is not kept in a register.\r
213     //\r
214     __asm("    ldr     r0, =_bss\n"\r
215           "    ldr     r1, =_ebss\n"\r
216           "    mov     r2, #0\n"\r
217           "    .thumb_func\n"\r
218           "zero_loop:\n"\r
219           "        cmp     r0, r1\n"\r
220           "        it      lt\n"\r
221           "        strlt   r2, [r0], #4\n"\r
222           "        blt     zero_loop");\r
223 \r
224     //\r
225     // Call C++ library initilisation, if present\r
226     //\r
227         if (__libc_init_array)\r
228                 __libc_init_array() ;\r
229 \r
230         //\r
231         // Call the application's entry point.\r
232         // __main() is the entry point for redlib based applications (which calls main())\r
233         // main() is the entry point for newlib based applications\r
234         //\r
235         if (__main)\r
236                 __main() ;\r
237         else\r
238                 main() ;\r
239 \r
240         //\r
241         // main() shouldn't return, but if it does, we'll just enter an infinite loop \r
242         //\r
243         while (1) {\r
244                 ;\r
245         }\r
246 }\r
247 \r
248 //*****************************************************************************\r
249 //\r
250 // This is the code that gets called when the processor receives a NMI.  This\r
251 // simply enters an infinite loop, preserving the system state for examination\r
252 // by a debugger.\r
253 //\r
254 //*****************************************************************************\r
255 static void NMI_Handler(void)\r
256 {\r
257     while(1)\r
258     {\r
259     }\r
260 }\r
261 \r
262 static void HardFault_Handler(void)\r
263 {\r
264         for( ;; );\r
265 }\r
266 \r
267 void pop_registers_from_fault_stack(unsigned int * hardfault_args)\r
268 {\r
269 unsigned int stacked_r0;\r
270 unsigned int stacked_r1;\r
271 unsigned int stacked_r2;\r
272 unsigned int stacked_r3;\r
273 unsigned int stacked_r12;\r
274 unsigned int stacked_lr;\r
275 unsigned int stacked_pc;\r
276 unsigned int stacked_psr;\r
277 \r
278         stacked_r0 = ((unsigned long) hardfault_args[0]);\r
279         stacked_r1 = ((unsigned long) hardfault_args[1]);\r
280         stacked_r2 = ((unsigned long) hardfault_args[2]);\r
281         stacked_r3 = ((unsigned long) hardfault_args[3]);\r
282 \r
283         stacked_r12 = ((unsigned long) hardfault_args[4]);\r
284         stacked_lr = ((unsigned long) hardfault_args[5]);\r
285         stacked_pc = ((unsigned long) hardfault_args[6]);\r
286         stacked_psr = ((unsigned long) hardfault_args[7]);\r
287 \r
288         /* Inspect stacked_pc to locate the offending instruction. */\r
289         for( ;; );\r
290 }\r
291 \r
292 static void MemManage_Handler(void)\r
293 {\r
294         __asm volatile\r
295         (\r
296                 " tst lr, #4                                                                            \n"\r
297                 " ite eq                                                                                        \n"\r
298                 " mrseq r0, msp                                                                         \n"\r
299                 " mrsne r0, psp                                                                         \n"\r
300                 " ldr r1, [r0, #24]                                                                     \n"\r
301                 " ldr r2, handler2_address_const                                                \n"\r
302                 " bx r2                                                                                         \n"\r
303                 " handler2_address_const: .word pop_registers_from_fault_stack  \n"\r
304         );\r
305 }\r
306 \r
307 static void BusFault_Handler(void)\r
308 {\r
309         __asm volatile\r
310         (\r
311                 " tst lr, #4                                                                            \n"\r
312                 " ite eq                                                                                        \n"\r
313                 " mrseq r0, msp                                                                         \n"\r
314                 " mrsne r0, psp                                                                         \n"\r
315                 " ldr r1, [r0, #24]                                                                     \n"\r
316                 " ldr r2, handler3_address_const                                                \n"\r
317                 " bx r2                                                                                         \n"\r
318                 " handler3_address_const: .word pop_registers_from_fault_stack  \n"\r
319         );\r
320 }\r
321 \r
322 static void UsageFault_Handler(void)\r
323 {\r
324         __asm volatile\r
325         (\r
326                 " tst lr, #4                                                                            \n"\r
327                 " ite eq                                                                                        \n"\r
328                 " mrseq r0, msp                                                                         \n"\r
329                 " mrsne r0, psp                                                                         \n"\r
330                 " ldr r1, [r0, #24]                                                                     \n"\r
331                 " ldr r2, handler4_address_const                                                \n"\r
332                 " bx r2                                                                                         \n"\r
333                 " handler4_address_const: .word pop_registers_from_fault_stack  \n"\r
334         );\r
335 }\r
336 \r
337 static void DebugMon_Handler(void)\r
338 {\r
339     while(1)\r
340     {\r
341     }\r
342 }\r
343 \r
344 //*****************************************************************************\r
345 //\r
346 // Processor ends up here if an unexpected interrupt occurs or a handler\r
347 // is not present in the application code.\r
348 //\r
349 //*****************************************************************************\r
350 static void IntDefaultHandler(void)\r
351 {\r
352     //\r
353     // Go into an infinite loop.\r
354     //\r
355     while(1)\r
356     {\r
357     }\r
358 }\r