ARMEBS4  revision-26.06.2015
startup_stm32f4xx.c
Go to the documentation of this file.
1 /************************************************************************//**
2  * \file heivs/startup_stm32f4xx.c
3  * \brief startup file for stm32f4xx
4  *
5  * \author marc dot pignat at hevs dot ch
6  *
7  * ARM Holdings said there is no need for assembly with Cortex-Mx, so here is
8  * the startup code, entirely in C ;)
9  *
10  * \warning The only thing that is ready before Reset is the stack.
11  * .bss and .data sections aren't ready.
12  *
13  * \warning The syntax is GCC specific, but in any case the assembler syntax is
14  * not portable
15  *
16  * \warning This file is heavily dependent on the linker scrpit and on newlib
17  *
18  ***************************************************************************/
19 
20 #include <stdint.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include "stm32/system_stm32f4xx.h"
24 #include "stm32/stm32f4xx_misc.h"
25 #include "stm32/stm32f4xx_rcc.h"
26 #include "heivs/error.h"
27 #include "heivs/bsp.h"
28 #include "heivs/delay.h"
29 #include "heivs/config.h"
30 
31 #include <time.h>
32 #include <sys/time.h>
33 
34 #if USE_FREERTOS
35 #include "freertos/FreeRTOS.h"
36 #endif
37 
38 /************************************************************************//**
39  * \addtogroup init
40  * @{
41  ***************************************************************************/
42 
43 /**
44  * \brief CCM RAM initialization
45  *
46  * The CCM (Core Coupled Memory) is a RAM only available for the CPU.
47  * \warning It is not available for other AHB masters (DMA).
48  * \warning It can not hold executable code (data only).
49  *
50  * This function will copy .ccm_ram.data from flash and initialize .ccm_ram.bss
51  * sections.
52  */
53 static void init_ccm_ram(void)
54 {
55  // External values set by the linker
56  extern uint8_t __ccm_ram_bss_start; ///< .ccm_ram.bss start in CCM
57  extern uint8_t __ccm_ram_bss_end; ///< .ccm_ram.bss end in CCM
58 
59  extern uint8_t __ccm_ram_dst_start; ///< .ccm_ram.data start in flash
60  extern uint8_t __ccm_ram_dst_end; ///< .ccm_ram.data start in CCM
61  extern uint8_t __ccm_ram_src_start; ///< .ccm_ram.data end in CCM
62 
63  memset(&__ccm_ram_bss_start, 0x0, &__ccm_ram_bss_end - &__ccm_ram_bss_start);
64  memcpy(&__ccm_ram_dst_start,&__ccm_ram_src_start, &__ccm_ram_dst_end - & __ccm_ram_dst_start);
65 }
66 
67 
68 /**
69  * \brief Interrupts initializations
70  *
71  * Vectors are copied from flash to RAM, so they can be updated at runtime.
72  */
73 static void interrupts_init(void)
74 {
75  // External values set by the linker
76  extern uint8_t _vectors_flash_start; ///< vectors start in flash
77  extern uint8_t _vectors_flash_end; ///< vectors end in flash
78  extern uint8_t _vectors_ram_start; ///< vectors start in ram
79 
80  // Copy vectors from flash to RAM.
81  memcpy(&_vectors_ram_start, &_vectors_flash_start, &_vectors_flash_end - &_vectors_flash_start);
82 
83  // Tell the NVIC to use the new vectors
84  NVIC_SetVectorTable(SRAM_BASE, 0x00000000);
85 
86  // Set priority bits in NVIC
87  // The FreeRTOS port for stm32 depends on this value
88  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
89 }
90 
91 /**
92  * \brief Initialize newlib c++ runtime
93  */
94 static void libc_init_array(void)
95 {
96  //
97  // __libc_[init/fini]_array plays with the linker script to handle
98  // constructor and destructors outside functions
99  //
100 
101  #ifdef HAVE_INITFINI_ARRAY
102 
103  extern void __libc_init_array(void);
104  extern void __libc_fini_array(void);
105  atexit(__libc_fini_array);
106  __libc_init_array();
107  #endif
108 }
109 
110 /**
111  * \brief zeroes the .bss section
112  */
113 static void init_bss(void)
114 {
115  // External values set by the linker
116  extern uint8_t _sbss; ///< .bss section start
117  extern uint8_t _ebss; ///< .bss section end
118 
119  /**
120  * Use memset because it's fast
121  *
122  * \warning memset MUST not use .bss nor .data
123  */
124  memset(&_sbss, 0x0, &_ebss - &_sbss);
125 }
126 
127 /**
128  * \brief Initialize (copy from flash) the .data section
129  */
130 static void init_data(void)
131 {
132  // External values set by the linker
133  extern uint8_t _sidata; ///< .data section start in flash
134  extern uint8_t _sdata; ///< .data section start in RAM
135  extern uint8_t _edata; ///< .data section end in RAM
136 
137  /**
138  * Use memcpy because it's fast
139  *
140  * \warning memcpy MUST not use.data
141  */
142  memcpy(&_sdata, &_sidata, &_edata - &_sdata);
143 }
144 
145 /**
146  * Start the RTC at 2000-01-01 00:00:00 when RTC is not running
147  */
148 static void fix_rtc(void)
149 {
150  time_t t = time(NULL);
151 
152  if (t == 949363200) // RTC default date
153  {
154  struct timeval tv =
155  {
156  .tv_sec = 946684800,
157  .tv_usec = 0,
158  };
159 
160  settimeofday(&tv, NULL);
161  }
162 }
163 
164 /**
165  * \brief Workaround DFU problem
166  *
167  * The DFU USB bootloader disables the CCMDATARAMEN bit. This prevent booting
168  * from it, because we use the CCMRAM for the stack.
169  *
170  * This workaround restores the reset state of the AHB1ENR register
171  */
172 static void workaround_dfu_loader(void)
173 {
174  RCC->AHB1ENR = RCC_AHB1Periph_CCMDATARAMEN;
175 }
176 
177 #if USE_GCC_STACK_PROTECTOR
178 uint32_t __stack_chk_guard;
179 #endif
180 
181 /**
182  * \brief Program start (at reset)
183  * \see linker script ENTRY(Reset_Handler)
184  */
185 __attribute__ ((noreturn))
186 void Reset_Handler(void)
187 {
188  /**
189  * Here is the reset entry point, at this time, the only thing that is
190  * initialized is the stack.
191  */
192  status_e status; ///< heivs library status
193 
194  extern int main(int argc, char *argv[]); ///< Definition of main
195  char main_str[] = {"main"}; ///< argv[0]
196  char *argv[] = ///< argv[]
197  {
198  main_str,
199  };
200 
201  // Initialize the stack guard before calling any function
202  #if USE_GCC_STACK_PROTECTOR
203  __stack_chk_guard = 0xdeadBeef;
204  #endif /* USE_GCC_STACK_PROTECTOR */
205 
206  // Workaround DFU problem
208 
209  // Initialize clock as early/fast as possible, this will improve boot time
210  ClockInit();
211 
212  // Initialize .bss and .data sections
213  init_bss();
214  init_data();
215 
216  // Save the reset reason for later use
218 
219  //
220  // From now on standard C functions can be used (excluding stdios)
221  //
222 
223  // Update clock values, done here because now we've got .bss and .data
224  SystemCoreClockUpdate();
225 
226  // Interrupts initialization
227  interrupts_init();
228 
229  // CCM RAM initialization
230  init_ccm_ram();
231 
232  // Board initialization
233  status = bsp_init();
234  if (status != NO_ERROR)
235  {
236  /**
237  * Most likely a hardware failure, nothing more to do
238  */
239  bsp_fatal(status);
240  }
241 
242  //
243  // All RAM is initialized, and stdio functions are ready to use.
244  //
245 
246  // C++ runtime initialization
247  libc_init_array();
248 
249  // Make sure the RTC is running
250  fix_rtc();
251 
252  //
253  // C++ is ready
254  //
255 
256  #if USE_FREERTOS && configUSE_TRACE_FACILITY
257  {
258  char time_string[26];
259  const uint32_t rcc_csr = bsp_reset_reason_get();
260  traceLabel label;
261  time_t now;
262  struct tm tm;
263  time(&now);
264 
265  // Tracing initialization
266  vTraceInitTraceData();
267  if (!uiTraceStart())
268  {
270  }
271 
272  label = xTraceOpenLabel("Reset");
273 
274  // Log reset time
275  gmtime_r(&now, &tm);
276  asctime_r(&tm, time_string);
277  vTracePrintF(label, "Reset GMT time : %s", time_string);
278 
279  // Save the reset reason into the trace
280  if (rcc_csr == 0x0e000000)
281  {
282  vTracePrintF(label, "RCC->CSR =0x%08x (First reset after power on)", rcc_csr);
283  }
284  else if (rcc_csr == 0x04000000)
285  {
286  vTracePrintF(label, "RCC->CSR =0x%08x (Reset by reset pin)", rcc_csr);
287  }
288  else
289  {
290  vTracePrintF(label, "RCC->CSR =0x%08x (%s%s%s%s%s%s%s)",
291  rcc_csr,
292  rcc_csr & RCC_CSR_LPWRRSTF ? "LPWRRSTF " : " ",
293  rcc_csr & RCC_CSR_WWDGRSTF ? "WWDGRSTF " : " ",
294  rcc_csr & RCC_CSR_WDGRSTF ? "WDGRSTF " : " ",
295  rcc_csr & RCC_CSR_SFTRSTF ? "SFTRSTF " : " ",
296  rcc_csr & RCC_CSR_PORRSTF ? "PORRSTF " : " ",
297  rcc_csr & RCC_CSR_PADRSTF ? "PADRSTF " : " ",
298  rcc_csr & RCC_CSR_BORRSTF ? "BORRSTF " : " "
299  );
300  }
301 
303 
304  /**
305  * Workaround interrupt disabled by trace code
306  *
307  * We want the interrupts in the same state when tracing is enable and
308  * disable.
309  */
310  portENABLE_INTERRUPTS();
311  }
312  #endif /* USE_FREERTOS */
313 
314  // Call main with it's parameters
315  exit(main(ARRAY_SIZE(argv), argv));
316 }
317 
318 /************************************************************************//**
319  * @}
320  ***************************************************************************/
321 
322 /**
323  * Cortex-M4 vector table definition
324  */
326 {
327  // Mandatory vectors
328  void *stack_start;
329  void (*reset)(void);
330  void (*NMI)(void);
331  void (*HardFault)(void);
332  void (*MemManage)(void);
333  void (*BusFault)(void);
334  void (*UsageFault)(void);
335  uint32_t _reserved_1[4];
336  void (*SVC)(void);
337  void (*DebugMon)(void);
338  uint32_t _reserved_2[1];
339  void (*PendSV)(void);
340  void (*SysTick_)(void);
341 
342  // STM32f4x7 interrupts
343  void (*WWDG_IRQ)(void);
344  void (*PVD_IRQ)(void);
345  void (*TAMP_STAMP_IRQ)(void);
346  void (*RTC_WKUP_IRQ)(void);
347  void (*FLASH_IRQ)(void);
348  void (*RCC_IRQ)(void);
349  void (*EXTI0_IRQ)(void);
350  void (*EXTI1_IRQ)(void);
351  void (*EXTI2_IRQ)(void);
352  void (*EXTI3_IRQ)(void);
353  void (*EXTI4_IRQ)(void);
354  void (*DMA1_Stream0_IRQ)(void);
355  void (*DMA1_Stream1_IRQ)(void);
356  void (*DMA1_Stream2_IRQ)(void);
357  void (*DMA1_Stream3_IRQ)(void);
358  void (*DMA1_Stream4_IRQ)(void);
359  void (*DMA1_Stream5_IRQ)(void);
360  void (*DMA1_Stream6_IRQ)(void);
361  void (*ADC_IRQ)(void);
362  void (*CAN1_TX_IRQ)(void);
363  void (*CAN1_RX0_IRQ)(void);
364  void (*CAN1_RX1_IRQ)(void);
365  void (*CAN1_SCE_IRQ)(void);
366  void (*EXTI9_5_IRQ)(void);
367  void (*TIM1_BRK_TIM9_IRQ)(void);
368  void (*TIM1_UP_TIM10_IRQ)(void);
369  void (*TIM1_TRG_COM_TIM11_IRQ)(void);
370  void (*TIM1_CC_IRQ)(void);
371  void (*TIM2_IRQ)(void);
372  void (*TIM3_IRQ)(void);
373  void (*TIM4_IRQ)(void);
374  void (*I2C1_EV_IRQ)(void);
375  void (*I2C1_ER_IRQ)(void);
376  void (*I2C2_EV_IRQ)(void);
377  void (*I2C2_ER_IRQ)(void);
378  void (*SPI1_IRQ)(void);
379  void (*SPI2_IRQ)(void);
380  void (*USART1_IRQ)(void);
381  void (*USART2_IRQ)(void);
382  void (*USART3_IRQ)(void);
383  void (*EXTI15_10_IRQ)(void);
384  void (*RTC_Alarm_IRQ)(void);
385  void (*OTG_FS_WKUP_IRQ)(void);
386  void (*TIM8_BRK_TIM12_IRQ)(void);
387  void (*TIM8_UP_TIM13_IRQ)(void);
388  void (*TIM8_TRG_COM_TIM14_IRQ)(void);
389  void (*TIM8_CC_IRQ)(void);
390  void (*DMA1_Stream7_IRQ)(void);
391  void (*FSMC_IRQ)(void);
392  void (*SDIO_IRQ)(void);
393  void (*TIM5_IRQ)(void);
394  void (*SPI3_IRQ)(void);
395  void (*UART4_IRQ)(void);
396  void (*UART5_IRQ)(void);
397  void (*TIM6_DAC_IRQ)(void);
398  void (*TIM7_IRQ)(void);
399  void (*DMA2_Stream0_IRQ)(void);
400  void (*DMA2_Stream1_IRQ)(void);
401  void (*DMA2_Stream2_IRQ)(void);
402  void (*DMA2_Stream3_IRQ)(void);
403  void (*DMA2_Stream4_IRQ)(void);
404  void (*ETH_IRQ)(void);
405  void (*ETH_WKUP_IRQ)(void);
406  void (*CAN2_TX_IRQ)(void);
407  void (*CAN2_RX0_IRQ)(void);
408  void (*CAN2_RX1_IRQ)(void);
409  void (*CAN2_SCE_IRQ)(void);
410  void (*OTG_FS_IRQ)(void);
411  void (*DMA2_Stream5_IRQ)(void);
412  void (*DMA2_Stream6_IRQ)(void);
413  void (*DMA2_Stream7_IRQ)(void);
414  void (*USART6_IRQ)(void);
415  void (*I2C3_EV_IRQ)(void);
416  void (*I2C3_ER_IRQ)(void);
417  void (*OTG_HS_EP1_OUT_IRQ)(void);
418  void (*OTG_HS_EP1_IN_IRQ)(void);
419  void (*OTG_HS_WKUP_IRQ)(void);
420  void (*OTG_HS_IRQ)(void);
421  void (*DCMI_IRQ)(void);
422  void (*CRYP_IRQ)(void);
423  void (*HASH_RNG_IRQ)(void);
424  void (*FPU_IRQ)(void);
425 };
426 
427 
428 __attribute__ ((weak)) void NMI_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
429 
430 struct hardfault_regs_t
431 {
432  uint32_t r0;
433  uint32_t r1;
434  uint32_t r2;
435  uint32_t r3;
436  uint32_t r12;
437  uint32_t lr;
438  uint32_t pc;
439  uint32_t psr;
440 };
441 
442 /**
443  * Default *weak* handlers for all interrupts and exceptions.
444  *
445  * Real handlers will be set by NVIC_Init()
446  */
447 
448 void HardFaultHelper(volatile struct hardfault_regs_t *regs_when_hardfault)
449 {
450  /**
451  * _.-^^---....,,--
452  * _-- --_
453  * < >)
454  * | HardFault ! |
455  * \._ _./
456  * ```--. . , ; .--'''
457  * | | |
458  * .-=|| | |=-.
459  * `-=#$%&%$#=-'
460  * | ; :|
461  * _____.,-#%&$@%#&#~,._____
462  *
463  * Something very wrong happened, and unfortunately, your MCU has no MMU
464  * (Memory Management Unit). So here it goes, your MCU has crashed
465  * and you're stuck in the HardFault handler.
466  *
467  * Now you can read the full ARM documentation or try to watch the
468  * "regs_when_hardfault" parameter in your favorite debugger. This is a
469  * copy of the MCU registers when it failed, the most interesting part is
470  * regs_when_hardfault->lr. It shows where the PC (Program Counter) was
471  * when the fault appended (more or less).
472  *
473  * Copy the value of the LR into the assembly view and you should see where
474  * it is in the code.
475  * Another way is to copy it into the PC of the processor do a single step.
476  *
477  * Remember that depending on the type of fault the LR can be some
478  * instructions further that the instructions because of the pipeline.
479  *
480  * Now you can see where the program was when it has crashed, and you can
481  * start the analysis.
482  *
483  * Most likely causes:
484  * * dereferencing of a null pointer (malloc failed?)
485  * * most recent change(s)
486  * * stack overflow
487  * * ...
488  */
489  (void)regs_when_hardfault;
490  if (debugger_is_connected())
491  {
492  breakpoint();
493  }
494 
496 }
497 
498 __attribute__ ((weak, naked)) void HardFault_Handler(void)
499 {
500  asm volatile
501  (
502  " tst lr, #4 \n"
503  " ite eq \n"
504  " mrseq r0, msp \n"
505  " mrsne r0, psp \n"
506  " ldr r1, [r0, #24] \n"
507  " ldr r2, HardFaultHelper_addr \n"
508  " bx r2 \n"
509  " \n"
510  "HardFaultHelper_addr: .word HardFaultHelper \n"
511  );
512 };
513 __attribute__ ((weak)) void MemManage_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
514 __attribute__ ((weak)) void BusFault_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
515 __attribute__ ((weak)) void UsageFault_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
516 __attribute__ ((weak)) void SVC_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
517 __attribute__ ((weak)) void DebugMon_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
518 __attribute__ ((weak)) void PendSV_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
519 __attribute__ ((weak)) void SysTick_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
520 __attribute__ ((weak)) void WWDG_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
521 __attribute__ ((weak)) void PVD_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
522 __attribute__ ((weak)) void TAMP_STAMP_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
523 __attribute__ ((weak)) void RTC_WKUP_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
524 __attribute__ ((weak)) void FLASH_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
525 __attribute__ ((weak)) void RCC_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
526 __attribute__ ((weak)) void EXTI0_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
527 __attribute__ ((weak)) void EXTI1_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
528 __attribute__ ((weak)) void EXTI2_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
529 __attribute__ ((weak)) void EXTI3_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
530 __attribute__ ((weak)) void EXTI4_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
531 __attribute__ ((weak)) void DMA1_Stream0_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
532 __attribute__ ((weak)) void DMA1_Stream1_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
533 __attribute__ ((weak)) void DMA1_Stream2_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
534 __attribute__ ((weak)) void DMA1_Stream3_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
535 __attribute__ ((weak)) void DMA1_Stream4_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
536 __attribute__ ((weak)) void DMA1_Stream5_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
537 __attribute__ ((weak)) void DMA1_Stream6_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
538 __attribute__ ((weak)) void ADC_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
539 __attribute__ ((weak)) void CAN1_TX_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
540 __attribute__ ((weak)) void CAN1_RX0_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
541 __attribute__ ((weak)) void CAN1_RX1_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
542 __attribute__ ((weak)) void CAN1_SCE_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
543 __attribute__ ((weak)) void EXTI9_5_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
544 __attribute__ ((weak)) void TIM1_BRK_TIM9_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
545 __attribute__ ((weak)) void TIM1_UP_TIM10_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
546 __attribute__ ((weak)) void TIM1_TRG_COM_TIM11_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
547 __attribute__ ((weak)) void TIM1_CC_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
548 __attribute__ ((weak)) void TIM2_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
549 __attribute__ ((weak)) void TIM3_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
550 __attribute__ ((weak)) void TIM4_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
551 __attribute__ ((weak)) void I2C1_EV_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
552 __attribute__ ((weak)) void I2C1_ER_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
553 __attribute__ ((weak)) void I2C2_EV_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
554 __attribute__ ((weak)) void I2C2_ER_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
555 __attribute__ ((weak)) void SPI1_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
556 __attribute__ ((weak)) void SPI2_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
557 __attribute__ ((weak)) void USART1_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
558 __attribute__ ((weak)) void USART2_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
559 __attribute__ ((weak)) void USART3_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
560 __attribute__ ((weak)) void EXTI15_10_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
561 __attribute__ ((weak)) void RTC_Alarm_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
562 __attribute__ ((weak)) void OTG_FS_WKUP_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
563 __attribute__ ((weak)) void TIM8_BRK_TIM12_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
564 __attribute__ ((weak)) void TIM8_UP_TIM13_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
565 __attribute__ ((weak)) void TIM8_TRG_COM_TIM14_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
566 __attribute__ ((weak)) void TIM8_CC_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
567 __attribute__ ((weak)) void DMA1_Stream7_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
568 __attribute__ ((weak)) void FSMC_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
569 __attribute__ ((weak)) void SDIO_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
570 __attribute__ ((weak)) void TIM5_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
571 __attribute__ ((weak)) void SPI3_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
572 __attribute__ ((weak)) void UART4_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
573 __attribute__ ((weak)) void UART5_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
574 __attribute__ ((weak)) void TIM6_DAC_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
575 __attribute__ ((weak)) void TIM7_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
576 __attribute__ ((weak)) void DMA2_Stream0_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
577 __attribute__ ((weak)) void DMA2_Stream1_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
578 __attribute__ ((weak)) void DMA2_Stream2_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
579 __attribute__ ((weak)) void DMA2_Stream3_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
580 __attribute__ ((weak)) void DMA2_Stream4_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
581 __attribute__ ((weak)) void ETH_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
582 __attribute__ ((weak)) void ETH_WKUP_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
583 __attribute__ ((weak)) void CAN2_TX_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
584 __attribute__ ((weak)) void CAN2_RX0_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
585 __attribute__ ((weak)) void CAN2_RX1_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
586 __attribute__ ((weak)) void CAN2_SCE_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
587 __attribute__ ((weak)) void OTG_FS_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
588 __attribute__ ((weak)) void DMA2_Stream5_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
589 __attribute__ ((weak)) void DMA2_Stream6_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
590 __attribute__ ((weak)) void DMA2_Stream7_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
591 __attribute__ ((weak)) void USART6_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
592 __attribute__ ((weak)) void I2C3_EV_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
593 __attribute__ ((weak)) void I2C3_ER_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
594 __attribute__ ((weak)) void OTG_HS_EP1_OUT_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
595 __attribute__ ((weak)) void OTG_HS_EP1_IN_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
596 __attribute__ ((weak)) void OTG_HS_WKUP_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
597 __attribute__ ((weak)) void OTG_HS_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
598 __attribute__ ((weak)) void DCMI_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
599 __attribute__ ((weak)) void CRYP_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
600 __attribute__ ((weak)) void HASH_RNG_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
601 __attribute__ ((weak)) void FPU_IRQ_Handler(void){if (debugger_is_connected()) breakpoint(); bsp_fatal(ERROR_IRQ_NOT_HANDLED);};
602 
603 extern uint32_t _stack_start; ///< Stack base, set by the linker script
604 
605 /**
606  * \brief The vector table, placed in the .isr_vector section
607  *
608  * This table will be placed by the linker at the beginning of the flash, which
609  * is mapped to address 0x00000000 when the boot0 pin is at zero.
610  */
611 const struct vector_table_t gVectors __attribute__ (( section(".isr_vector"))) =
612 {
613  .stack_start = &_stack_start,
614  .reset = Reset_Handler,
615  .NMI = NMI_Handler,
616  .HardFault = HardFault_Handler,
617  .MemManage = MemManage_Handler,
618  .BusFault = BusFault_Handler,
619  .UsageFault = UsageFault_Handler,
620  ._reserved_1 = {0},
621  .SVC = SVC_Handler,
622  .DebugMon = DebugMon_Handler,
623  ._reserved_2 = {0},
624  .PendSV = PendSV_Handler,
625  .SysTick_ = SysTick_Handler,
626 
627  /* External Interrupts */
628  .WWDG_IRQ = WWDG_IRQ_Handler,
629  .PVD_IRQ = PVD_IRQ_Handler,
630  .TAMP_STAMP_IRQ = TAMP_STAMP_IRQ_Handler,
631  .RTC_WKUP_IRQ = RTC_WKUP_IRQ_Handler,
632  .FLASH_IRQ = FLASH_IRQ_Handler,
633  .RCC_IRQ = RCC_IRQ_Handler,
634  .EXTI0_IRQ = EXTI0_IRQ_Handler,
635  .EXTI1_IRQ = EXTI1_IRQ_Handler,
636  .EXTI2_IRQ = EXTI2_IRQ_Handler,
637  .EXTI3_IRQ = EXTI3_IRQ_Handler,
638  .EXTI4_IRQ = EXTI4_IRQ_Handler,
639  .DMA1_Stream0_IRQ = DMA1_Stream0_IRQ_Handler,
640  .DMA1_Stream1_IRQ = DMA1_Stream1_IRQ_Handler,
641  .DMA1_Stream2_IRQ = DMA1_Stream2_IRQ_Handler,
642  .DMA1_Stream3_IRQ = DMA1_Stream3_IRQ_Handler,
643  .DMA1_Stream4_IRQ = DMA1_Stream4_IRQ_Handler,
644  .DMA1_Stream5_IRQ = DMA1_Stream5_IRQ_Handler,
645  .DMA1_Stream6_IRQ = DMA1_Stream6_IRQ_Handler,
646  .ADC_IRQ = ADC_IRQ_Handler,
647  .CAN1_TX_IRQ = CAN1_TX_IRQ_Handler,
648  .CAN1_RX0_IRQ = CAN1_RX0_IRQ_Handler,
649  .CAN1_RX1_IRQ = CAN1_RX1_IRQ_Handler,
650  .CAN1_SCE_IRQ = CAN1_SCE_IRQ_Handler,
651  .EXTI9_5_IRQ = EXTI9_5_IRQ_Handler,
652  .TIM1_BRK_TIM9_IRQ = TIM1_BRK_TIM9_IRQ_Handler,
653  .TIM1_UP_TIM10_IRQ = TIM1_UP_TIM10_IRQ_Handler,
654  .TIM1_TRG_COM_TIM11_IRQ = TIM1_TRG_COM_TIM11_IRQ_Handler,
655  .TIM1_CC_IRQ = TIM1_CC_IRQ_Handler,
656  .TIM2_IRQ = TIM2_IRQ_Handler,
657  .TIM3_IRQ = TIM3_IRQ_Handler,
658  .TIM4_IRQ = TIM4_IRQ_Handler,
659  .I2C1_EV_IRQ = I2C1_EV_IRQ_Handler,
660  .I2C1_ER_IRQ = I2C1_ER_IRQ_Handler,
661  .I2C2_EV_IRQ = I2C2_EV_IRQ_Handler,
662  .I2C2_ER_IRQ = I2C2_ER_IRQ_Handler,
663  .SPI1_IRQ = SPI1_IRQ_Handler,
664  .SPI2_IRQ = SPI2_IRQ_Handler,
665  .USART1_IRQ = USART1_IRQ_Handler,
666  .USART2_IRQ = USART2_IRQ_Handler,
667  .USART3_IRQ = USART3_IRQ_Handler,
668  .EXTI15_10_IRQ = EXTI15_10_IRQ_Handler,
669  .RTC_Alarm_IRQ = RTC_Alarm_IRQ_Handler,
670  .OTG_FS_WKUP_IRQ = OTG_FS_WKUP_IRQ_Handler,
671  .TIM8_BRK_TIM12_IRQ = TIM8_BRK_TIM12_IRQ_Handler,
672  .TIM8_UP_TIM13_IRQ = TIM8_UP_TIM13_IRQ_Handler,
673  .TIM8_TRG_COM_TIM14_IRQ = TIM8_TRG_COM_TIM14_IRQ_Handler,
674  .TIM8_CC_IRQ = TIM8_CC_IRQ_Handler,
675  .DMA1_Stream7_IRQ = DMA1_Stream7_IRQ_Handler,
676  .FSMC_IRQ = FSMC_IRQ_Handler,
677  .SDIO_IRQ = SDIO_IRQ_Handler,
678  .TIM5_IRQ = TIM5_IRQ_Handler,
679  .SPI3_IRQ = SPI3_IRQ_Handler,
680  .UART4_IRQ = UART4_IRQ_Handler,
681  .UART5_IRQ = UART5_IRQ_Handler,
682  .TIM6_DAC_IRQ = TIM6_DAC_IRQ_Handler,
683  .TIM7_IRQ = TIM7_IRQ_Handler,
684  .DMA2_Stream0_IRQ = DMA2_Stream0_IRQ_Handler,
685  .DMA2_Stream1_IRQ = DMA2_Stream1_IRQ_Handler,
686  .DMA2_Stream2_IRQ = DMA2_Stream2_IRQ_Handler,
687  .DMA2_Stream3_IRQ = DMA2_Stream3_IRQ_Handler,
688  .DMA2_Stream4_IRQ = DMA2_Stream4_IRQ_Handler,
689  .ETH_IRQ = ETH_IRQ_Handler,
690  .ETH_WKUP_IRQ = ETH_WKUP_IRQ_Handler,
691  .CAN2_TX_IRQ = CAN2_TX_IRQ_Handler,
692  .CAN2_RX0_IRQ = CAN2_RX0_IRQ_Handler,
693  .CAN2_RX1_IRQ = CAN2_RX1_IRQ_Handler,
694  .CAN2_SCE_IRQ = CAN2_SCE_IRQ_Handler,
695  .OTG_FS_IRQ = OTG_FS_IRQ_Handler,
696  .DMA2_Stream5_IRQ = DMA2_Stream5_IRQ_Handler,
697  .DMA2_Stream6_IRQ = DMA2_Stream6_IRQ_Handler,
698  .DMA2_Stream7_IRQ = DMA2_Stream7_IRQ_Handler,
699  .USART6_IRQ = USART6_IRQ_Handler,
700  .I2C3_EV_IRQ = I2C3_EV_IRQ_Handler,
701  .I2C3_ER_IRQ = I2C3_ER_IRQ_Handler,
702  .OTG_HS_EP1_OUT_IRQ = OTG_HS_EP1_OUT_IRQ_Handler,
703  .OTG_HS_EP1_IN_IRQ = OTG_HS_EP1_IN_IRQ_Handler,
704  .OTG_HS_WKUP_IRQ = OTG_HS_WKUP_IRQ_Handler,
705  .OTG_HS_IRQ = OTG_HS_IRQ_Handler,
706  .DCMI_IRQ = DCMI_IRQ_Handler,
707  .CRYP_IRQ = CRYP_IRQ_Handler,
708  .HASH_RNG_IRQ = HASH_RNG_IRQ_Handler,
709  .FPU_IRQ = FPU_IRQ_Handler,
710 };
711 
712 
713 
This file contains all the functions prototypes for the RCC firmware library.
#define NVIC_PriorityGroup_4
BSP - Board Support Package.
void bsp_reset_reason_clear(void)
Reset reason clear.
Definition: bsp.c:185
simple time abstraction
static void workaround_dfu_loader(void)
Workaround DFU problem.
static void init_ccm_ram(void)
CCM RAM initialization.
#define breakpoint()
Breakpoint (from code)
Definition: utils.h:74
void * memcpy(void *dest, const void *src, size_t n)
void * memset(void *dest, int n, size_t n)
libheivs configuration file
void bsp_fatal(status_e status)
fatal error
Definition: bsp.c:123
Function called at bad time.
Definition: error.h:67
Errors definitions.
static void interrupts_init(void)
Interrupts initializations.
static void libc_init_array(void)
Initialize newlib c++ runtime.
void exit(int status)
No comment.
Definition: error.h:91
const struct vector_table_t gVectors
The vector table, placed in the .isr_vector section.
Default interrupt handler fired.
Definition: error.h:71
void HardFaultHelper(volatile struct hardfault_regs_t *regs_when_hardfault)
void Reset_Handler(void)
Program start (at reset)
int main(int argc, char *argv[])
Main function.
static void init_data(void)
Initialize (copy from flash) the .data section.
static void init_bss(void)
zeroes the .bss section
uint32_t bsp_reset_reason_get(void)
Reset reason get.
Definition: bsp.c:180
simple delays
static void fix_rtc(void)
void bsp_reset_reason_init(void)
Reset reason initialization.
Definition: bsp.c:175
#define debugger_is_connected()
Detect is debugger is connected.
Definition: utils.h:67
status_e
Known errors.
Definition: error.h:21
#define ARRAY_SIZE(x)
Number of elements in the array.
Definition: utils.h:19
No error.
Definition: error.h:28
status_e bsp_init(void)
Initialize the whole board.
Definition: bsp_armebs4.c:525
CMSIS Cortex-M4 Device System Source File for STM32F4xx devices.
uint32_t _stack_start
Stack base, set by the linker script.