Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module startup;
- version(GNU)
- {
- static import gcc.attribute; // we need this to get the section, weak and alias attributes
- void wfi(){ version(ALLOW_WFI){ asm{ "wfi"; } } }
- }
- else version(LDC)
- {
- import ldc.llvmasm;
- void wfi(){ version(ALLOW_WFI){ __asm("wfi"); } }
- }
- import core.stdc.config; // we need this for c_ulong, so we can get symbols from the linker-script
- import core.stdc.stdint; // these are the types normally used on microcontrollers
- // Create convenience enums and aliases for the weak and alias attributes:
- enum isr_vector = gcc.attribute.attribute("section",".isr_vector.ro");
- enum naked = gcc.attribute.attribute("naked");
- enum weak = gcc.attribute.attribute("weak");
- alias Tuple(A...) = A;
- alias weakalias(string A) = Tuple!(weak, gcc.attribute.attribute("alias", A));
- // The following symbols are provided by our linker-script:
- extern(C) extern __gshared c_ulong _stack; // initial stack address
- extern(C) extern __gshared c_ulong _siccmram; // pointer to read-only data that needs to be copied to CCMRAM
- extern(C) extern __gshared c_ulong _sccmram; // start address of .ccmram section (somewhere within CCMRAM)
- extern(C) extern __gshared c_ulong _eccmram; // end address of .ccmram section (somewhere within CCMRAM)
- extern(C) extern __gshared c_ulong _sirelocated; // pointer to read-only data that needs to be copied to normal SRAM
- extern(C) extern __gshared c_ulong _srelocated; // start address of .relocated section (somewhere within SRAM)
- extern(C) extern __gshared c_ulong _erelocated; // end address of .relocated section (somewhere within SRAM)
- extern(C) extern __gshared c_ulong _szeroed; // start address of .zeroed section (somewhere within SRAM or CCMRAM)
- extern(C) extern __gshared c_ulong _ezeroed; // end address of .zeroed section (somewhere within SRAM or CCMRAM)
- // Create a convenience alias for our vector functions:
- //alias extern(C) const void function() VectorFunc; // currently, this won't work for me
- alias extern(C) const void *VectorFunc; // so I'm using a void* instead.
- @property VectorFuncs(string dsl)() {
- static struct A {
- struct PTR { string n; @property s() {return `cast(VectorFunc)&`~n;} }
- struct PAD { string n; @property s() {return `cast(VectorFunc)null`;} }
- struct VAL { string n; @property s() {return `cast(VectorFunc)`~n;} }
- struct EXC { string n = `defaultExceptionHandler`; @property s() {return null;} }
- mixin(dsl);
- }
- string code;
- foreach(I, M; A.init.tupleof)
- static if(is(typeof(M)==A.EXC))
- code ~= `@weakalias!"`~M.n~`" extern (C) void ` ~ __traits(identifier, A.tupleof[I]) ~ "();\n";
- code ~= "\n@isr_vector VectorFunc[" ~ A.tupleof.length.stringof ~ "] g_pfnVectors = [\n";
- foreach(I, M; A.init.tupleof)
- code ~= " " ~ (M.s?M.s:"&"~__traits(identifier, A.tupleof[I])) ~ ",\n";
- code ~= "];\n";
- return code;
- }
- mixin(VectorFuncs!(q{
- PTR stack = {`_stack`}; /* -16 $0000 Initial Stack Pointer */
- EXC Reset_Handler = {`defaultResetHandler`}; /* -15 $0004 Reset Vector */
- EXC NMI_Handler; /* -14 $0008 Non Maskable Interrupt Vector */
- EXC HardFault_Handler; /* -13 $000c Hard Fault Vector */
- EXC MemManage_Handler; /* -12 $0010 Memory Protection Unit Fault Vector */
- EXC BusFault_Handler; /* -11 $0014 Bus Fault Vector */
- EXC UsageFault_Handler; /* -10 $0018 Usage Fault Vector */
- PAD pad01; /* -9 $001c Reserved */
- PAD pad02; /* -8 $0020 Reserved */
- PAD pad03; /* -7 $0024 Reserved */
- PAD pad04; /* -6 $0028 Reserved */
- EXC SVC_Handler; /* -5 $002c SuperVisor Call Vector */
- EXC DebugMon_Handler; /* -4 $0030 Debug Monitor Vector */
- PAD pad05; /* -3 $0034 Reserved */
- EXC PendSV_Handler; /* -2 $0038 Pending SuperVisor Vector */
- EXC SysTick_Handler; /* -1 $003c System Tick Vector */
- EXC WWDG_IRQHandler; /* 0 $0040 Windowed WatchDog */
- EXC PVD_IRQHandler; /* 1 $0044 PVD through EXTI Line detection */
- EXC TAMP_STAMP_IRQHandler; /* 2 $0048 Tamper and TimeStamps through the EXTI line */
- EXC RTC_WKUP_IRQHandler; /* 3 $004c RTC Wakeup through the EXTI line */
- EXC FLASH_IRQHandler; /* 4 $0050 FLASH */
- EXC RCC_IRQHandler; /* 5 $0054 RCC */
- EXC EXTI0_IRQHandler; /* 6 $0058 EXTI Line0 */
- EXC EXTI1_IRQHandler; /* 7 $005c EXTI Line1 */
- EXC EXTI2_IRQHandler; /* 8 $0060 EXTI Line2 */
- EXC EXTI3_IRQHandler; /* 9 $0064 EXTI Line3 */
- EXC EXTI4_IRQHandler; /* 10 $0068 EXTI Line4 */
- EXC DMA1_Stream0_IRQHandler; /* 11 $006c DMA1 Stream 0 */
- EXC DMA1_Stream1_IRQHandler; /* 12 $0070 DMA1 Stream 1 */
- EXC DMA1_Stream2_IRQHandler; /* 13 $0074 DMA1 Stream 2 */
- EXC DMA1_Stream3_IRQHandler; /* 14 $0078 DMA1 Stream 3 */
- EXC DMA1_Stream4_IRQHandler; /* 15 $007c DMA1 Stream 4 */
- EXC DMA1_Stream5_IRQHandler; /* 16 $0080 DMA1 Stream 5 */
- EXC DMA1_Stream6_IRQHandler; /* 17 $0084 DMA1 Stream 6 */
- EXC ADC_IRQHandler; /* 18 $0088 ADC1, ADC2 and ADC3s */
- EXC CAN1_TX_IRQHandler; /* 19 $008c CAN1 TX */
- EXC CAN1_RX0_IRQHandler; /* 20 $0090 CAN1 RX0 */
- EXC CAN1_RX1_IRQHandler; /* 21 $0094 CAN1 RX1 */
- EXC CAN1_SCE_IRQHandler; /* 22 $0098 CAN1 SCE */
- EXC EXTI9_5_IRQHandler; /* 23 $009c External Line[9:5]s */
- EXC TIM1_BRK_TIM9_IRQHandler; /* 24 $00a0 TIM1 Break and TIM9 */
- EXC TIM1_UP_TIM10_IRQHandler; /* 25 $00a4 TIM1 Update and TIM10 */
- EXC TIM1_TRG_COM_TIM11_IRQHandler; /* 26 $00a8 TIM1 Trigger and Commutation and TIM11 */
- EXC TIM1_CC_IRQHandler; /* 27 $00ac TIM1 Capture Compare */
- EXC TIM2_IRQHandler; /* 28 $00b0 TIM2 */
- EXC TIM3_IRQHandler; /* 29 $00b4 TIM3 */
- EXC TIM4_IRQHandler; /* 30 $00b8 TIM4 */
- EXC I2C1_EV_IRQHandler; /* 31 $00bc I2C1 Event */
- EXC I2C1_ER_IRQHandler; /* 32 $00c0 I2C1 Error */
- EXC I2C2_EV_IRQHandler; /* 33 $00c4 I2C2 Event */
- EXC I2C2_ER_IRQHandler; /* 34 $00c8 I2C2 Error */
- EXC SPI1_IRQHandler; /* 35 $00cc SPI1 */
- EXC SPI2_IRQHandler; /* 36 $00d0 SPI2 */
- EXC USART1_IRQHandler; /* 37 $00d4 USART1 */
- EXC USART2_IRQHandler; /* 38 $00d8 USART2 */
- EXC USART3_IRQHandler; /* 39 $00dc USART3 */
- EXC EXTI15_10_IRQHandler; /* 40 $00e0 External Line[15:10]s */
- EXC RTC_Alarm_IRQHandler; /* 41 $00e4 RTC Alarm (A and B) through EXTI Line */
- EXC OTG_FS_WKUP_IRQHandler; /* 42 $00e8 USB OTG FS Wakeup through EXTI line */
- EXC TIM8_BRK_TIM12_IRQHandler; /* 43 $00ec TIM8 Break and TIM12 */
- EXC TIM8_UP_TIM13_IRQHandler; /* 44 $00f0 TIM8 Update and TIM13 */
- EXC TIM8_TRG_COM_TIM14_IRQHandler; /* 45 $00f4 TIM8 Trigger and Commutation and TIM14 */
- EXC TIM8_CC_IRQHandler; /* 46 $00f8 TIM8 Capture Compare */
- EXC DMA1_Stream7_IRQHandler; /* 47 $00fc DMA1 Stream7 */
- EXC FMC_IRQHandler; /* 48 $0100 FMC */
- EXC SDIO_IRQHandler; /* 49 $0104 SDIO */
- EXC TIM5_IRQHandler; /* 50 $0108 TIM5 */
- EXC SPI3_IRQHandler; /* 51 $010c SPI3 */
- EXC UART4_IRQHandler; /* 52 $0110 UART4 */
- EXC UART5_IRQHandler; /* 53 $0114 UART5 */
- EXC TIM6_DAC_IRQHandler; /* 54 $0118 TIM6 and DAC1&2 underrun errors */
- EXC TIM7_IRQHandler; /* 55 $011c TIM7 */
- EXC DMA2_Stream0_IRQHandler; /* 56 $0120 DMA2 Stream 0 */
- EXC DMA2_Stream1_IRQHandler; /* 57 $0124 DMA2 Stream 1 */
- EXC DMA2_Stream2_IRQHandler; /* 58 $0128 DMA2 Stream 2 */
- EXC DMA2_Stream3_IRQHandler; /* 59 $012c DMA2 Stream 3 */
- EXC DMA2_Stream4_IRQHandler; /* 60 $0130 DMA2 Stream 4 */
- EXC ETH_IRQHandler; /* 61 $0134 Ethernet */
- EXC ETH_WKUP_IRQHandler; /* 62 $0138 Ethernet Wakeup through EXTI line */
- EXC CAN2_TX_IRQHandler; /* 63 $013c CAN2 TX */
- EXC CAN2_RX0_IRQHandler; /* 64 $0140 CAN2 RX0 */
- EXC CAN2_RX1_IRQHandler; /* 65 $0144 CAN2 RX1 */
- EXC CAN2_SCE_IRQHandler; /* 66 $0148 CAN2 SCE */
- EXC OTG_FS_IRQHandler; /* 67 $014c USB OTG FS */
- EXC DMA2_Stream5_IRQHandler; /* 68 $0150 DMA2 Stream 5 */
- EXC DMA2_Stream6_IRQHandler; /* 69 $0154 DMA2 Stream 6 */
- EXC DMA2_Stream7_IRQHandler; /* 70 $0158 DMA2 Stream 7 */
- EXC USART6_IRQHandler; /* 71 $015c USART6 */
- EXC I2C3_EV_IRQHandler; /* 72 $0160 I2C3 event */
- EXC I2C3_ER_IRQHandler; /* 73 $0164 I2C3 error */
- EXC OTG_HS_EP1_OUT_IRQHandler; /* 74 $0168 USB OTG HS End Point 1 Out */
- EXC OTG_HS_EP1_IN_IRQHandler; /* 75 $016c USB OTG HS End Point 1 In */
- EXC OTG_HS_WKUP_IRQHandler; /* 76 $0170 USB OTG HS Wakeup through EXTI */
- EXC OTG_HS_IRQHandler; /* 77 $0174 USB OTG HS */
- EXC DCMI_IRQHandler; /* 78 $0178 DCMI */
- PAD pad06; /* 79 $017c Reserved */
- EXC HASH_RNG_IRQHandler; /* 80 $0180 Hash and Rng */
- EXC FPU_IRQHandler; /* 81 $0184 FPU */
- EXC UART7_IRQHandler; /* 82 $0188 UART7 */
- EXC UART8_IRQHandler; /* 83 $018c UART8 */
- EXC SPI4_IRQHandler; /* 84 $0190 SPI4 */
- EXC SPI5_IRQHandler; /* 85 $0194 SPI5 */
- EXC SPI6_IRQHandler; /* 86 $0198 SPI6 */
- EXC SAI1_IRQHandler; /* 87 $019c SAI1 */
- EXC LTDC_IRQHandler; /* 88 $01a0 LTDC */
- EXC LTDC_ER_IRQHandler; /* 89 $01a4 LTDC Error */
- EXC DMA2D_IRQHandler; /* 90 $01a8 DMA2D */
- }));
- @weak extern(C) void LowLevelInit();
- @weak extern(C) void SystemInit();
- @weak extern(C) void __libc_init_array();
- @weak extern(C) extern __gshared c_ulong SystemCoreClock;
- extern(C) void main();
- void copyBlock(const(void) *aSource, void *aDestination, void *aDestinationEnd)
- {
- const(uint32_t) *s = cast(const(uint32_t) *)aSource;
- uint32_t *d = cast(uint32_t *)aDestination;
- uint32_t *e = cast(uint32_t *)aDestinationEnd;
- while(d < e)
- {
- *d++ = *s++;
- }
- }
- void zeroBlock(void *aDestination, void *aDestinationEnd)
- {
- uint32_t *d = cast(uint32_t *)aDestination;
- uint32_t *e = cast(uint32_t *)aDestinationEnd;
- while(d < e)
- {
- *d++ = 0;
- }
- }
- @naked extern(C) void defaultResetHandler() /* we can mark this naked, as it never returns and should never save any registers on the stack */
- {
- uint32_t saveFreq;
- LowLevelInit();
- SystemInit();
- saveFreq = SystemCoreClock;
- copyBlock(&_siccmram, &_sccmram, &_eccmram);
- copyBlock(&_sirelocated, &_srelocated, &_erelocated);
- zeroBlock(&_szeroed, &_ezeroed);
- __libc_init_array();
- if(&SystemCoreClock) SystemCoreClock = saveFreq;
- main();
- defaultExceptionHandler();
- }
- @naked extern(C) void defaultExceptionHandler()
- {
- while(true)
- {
- wfi();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement