#include "CH32V20xxx.h" typedef __SIZE_TYPE__ size_t; extern "C" { extern void handle_reset () __attribute__((naked,nothrow,used)); extern void user_prog () __attribute__((used)); extern int main () __attribute__((used)); extern void SystemInit() __attribute__((used)); // This is required to allow pure virtual functions to be defined. extern void __cxa_pure_virtual() { while (1); } // These magic symbols are provided by the linker. extern uint32_t _sbss; extern uint32_t _ebss; extern uint32_t _data_lma; extern uint32_t _data_vma; extern uint32_t _edata; extern void (*__preinit_array_start[]) (void) __attribute__((weak)); extern void (*__preinit_array_end[]) (void) __attribute__((weak)); extern void (*__init_array_start[]) (void) __attribute__((weak)); extern void (*__init_array_end[]) (void) __attribute__((weak)); static void __init_array () { uint32_t * dst, * end; /* Zero fill the bss section */ dst = &_sbss; end = &_ebss; while (dst < end) * dst++ = 0U; /* Copy data section from flash to RAM */ uint32_t * src; src = &_data_lma; dst = &_data_vma; end = &_edata; if (src != dst) { while (dst < end) * dst++ = * src++; } size_t count; /* Pro Cortex-Mx bylo toto zbytečné, lze předpokládat, že je to tak i zde. count = __preinit_array_end - __preinit_array_start; for (unsigned i = 0; i < count; i++) __preinit_array_start[i](); */ count = __init_array_end - __init_array_start; for (unsigned i = 0; i < count; i++) __init_array_start[i](); } // If you don't override a specific handler, it will just spin forever. void DefaultIRQHandler( void ) { // Infinite Loop for (;;); } void NMI_RCC_CSS_IRQHandler( void ) { RCC.INTR.B.CSSC = RESET; // clear the clock security int flag } #define ALIAS(f) __attribute__((nothrow,weak,alias(#f),used)) void Ecall_M_Mode_Handler( void ) ALIAS(DefaultIRQHandler); void Ecall_U_Mode_Handler( void ) ALIAS(DefaultIRQHandler); void Break_Point_Handler( void ) ALIAS(DefaultIRQHandler); void NMI_Handler( void ) ALIAS(NMI_RCC_CSS_IRQHandler); void HardFault_Handler( void ) ALIAS(DefaultIRQHandler); void SysTick_Handler( void ) ALIAS(DefaultIRQHandler); void SW_Handler( void ) ALIAS(DefaultIRQHandler); void WWDG_IRQHandler (void) ALIAS(DefaultIRQHandler); void PVD_IRQHandler (void) ALIAS(DefaultIRQHandler); void TAMPER_IRQHandler (void) ALIAS(DefaultIRQHandler); void RTC_IRQHandler (void) ALIAS(DefaultIRQHandler); void FLASH_IRQHandler (void) ALIAS(DefaultIRQHandler); void RCC_IRQHandler (void) ALIAS(DefaultIRQHandler); void EXTI0_IRQHandler (void) ALIAS(DefaultIRQHandler); void EXTI1_IRQHandler (void) ALIAS(DefaultIRQHandler); void EXTI2_IRQHandler (void) ALIAS(DefaultIRQHandler); void EXTI3_IRQHandler (void) ALIAS(DefaultIRQHandler); void EXTI4_IRQHandler (void) ALIAS(DefaultIRQHandler); void DMA1_Channel1_IRQHandler (void) ALIAS(DefaultIRQHandler); void DMA1_Channel2_IRQHandler (void) ALIAS(DefaultIRQHandler); void DMA1_Channel3_IRQHandler (void) ALIAS(DefaultIRQHandler); void DMA1_Channel4_IRQHandler (void) ALIAS(DefaultIRQHandler); void DMA1_Channel5_IRQHandler (void) ALIAS(DefaultIRQHandler); void DMA1_Channel6_IRQHandler (void) ALIAS(DefaultIRQHandler); void DMA1_Channel7_IRQHandler (void) ALIAS(DefaultIRQHandler); void DMA1_Channel8_IRQHandler (void) ALIAS(DefaultIRQHandler); void ADC1_2_IRQHandler (void) ALIAS(DefaultIRQHandler); void USB_HP_CAN1_TX_IRQHandler (void) ALIAS(DefaultIRQHandler); void USB_LP_CAN1_RX0_IRQHandler (void) ALIAS(DefaultIRQHandler); void CAN1_RX1_IRQHandler (void) ALIAS(DefaultIRQHandler); void CAN1_SCE_IRQHandler (void) ALIAS(DefaultIRQHandler); void EXTI9_5_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM1_BRK_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM1_UP_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM1_TRG_COM_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM1_CC_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM2_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM3_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM4_IRQHandler (void) ALIAS(DefaultIRQHandler); void I2C1_EV_IRQHandler (void) ALIAS(DefaultIRQHandler); void I2C1_ER_IRQHandler (void) ALIAS(DefaultIRQHandler); void I2C2_EV_IRQHandler (void) ALIAS(DefaultIRQHandler); void I2C2_ER_IRQHandler (void) ALIAS(DefaultIRQHandler); void SPI1_IRQHandler (void) ALIAS(DefaultIRQHandler); void SPI2_IRQHandler (void) ALIAS(DefaultIRQHandler); void USART1_IRQHandler (void) ALIAS(DefaultIRQHandler); void USART2_IRQHandler (void) ALIAS(DefaultIRQHandler); void USART3_IRQHandler (void) ALIAS(DefaultIRQHandler); void EXTI15_10_IRQHandler (void) ALIAS(DefaultIRQHandler); void RTCAlarm_IRQHandler (void) ALIAS(DefaultIRQHandler); void USBWakeUp_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM8_BRK_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM8_UP__IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM8_TRG_COM_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM8_CC_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM5_IRQHandler (void) ALIAS(DefaultIRQHandler); void SPI3_IRQHandler (void) ALIAS(DefaultIRQHandler); void UART4_IRQHandler (void) ALIAS(DefaultIRQHandler); void UART5_IRQHandler (void) ALIAS(DefaultIRQHandler); void ETH_IRQHandler (void) ALIAS(DefaultIRQHandler); void ETH_WKUP_IRQHandler (void) ALIAS(DefaultIRQHandler); void OTG_FS_IRQHandler (void) ALIAS(DefaultIRQHandler); void USBHDWakeUp_IRQHandler (void) ALIAS(DefaultIRQHandler); void USBHD_IRQHandler (void) ALIAS(DefaultIRQHandler); void UART6_IRQHandler (void) ALIAS(DefaultIRQHandler); void UART7_IRQHandler (void) ALIAS(DefaultIRQHandler); void UART8_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM9_BRK_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM9_UP__IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM9_TRG_COM_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM9_CC_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM10_BRK_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM10_UP__IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM10_TRG_COM_IRQHandler (void) ALIAS(DefaultIRQHandler); void TIM10_CC_IRQHandler (void) ALIAS(DefaultIRQHandler); void ETHWakeUp_IRQHandler( void ) ALIAS(DefaultIRQHandler); void OSC32KCal_IRQHandler( void ) ALIAS(DefaultIRQHandler); void OSCWakeUp_IRQHandler( void ) ALIAS(DefaultIRQHandler); void Init() __attribute__((used,section(".init"))); /* Tohle je patrně nedomyšlené, sekce .vector není definována. void InterruptVector() __attribute__((nothrow,naked,section(".vector"),weak,alias("InterruptVectorDefault"))); void InterruptVectorDefault() __attribute__((nothrow,naked,section(".vector"))); */ typedef void (*pHandler) (void); extern const pHandler InterruptVector [] __attribute__((section(".text.vector"),aligned(8))); }; const pHandler InterruptVector [] = { Init, 0, NMI_Handler, /* NMI */ HardFault_Handler, /* Hard Fault */ 0, Ecall_M_Mode_Handler, /* Ecall M Mode */ 0,0, Ecall_U_Mode_Handler, /* Ecall U Mode */ Break_Point_Handler, /* Break Point */ 0,0, SysTick_Handler, /* SysTick Handler */ 0, SW_Handler, /* SW Handler */ 0, /* External Interrupts */ WWDG_IRQHandler, /* Window Watchdog */ PVD_IRQHandler, /* PVD through EXTI Line detect */ TAMPER_IRQHandler, /* TAMPER */ RTC_IRQHandler, /* RTC */ FLASH_IRQHandler, /* Flash */ RCC_IRQHandler, /* RCC */ EXTI0_IRQHandler, /* EXTI Line 0 */ EXTI1_IRQHandler, /* EXTI Line 1 */ EXTI2_IRQHandler, /* EXTI Line 2 */ EXTI3_IRQHandler, /* EXTI Line 3 */ EXTI4_IRQHandler, /* EXTI Line 4 */ DMA1_Channel1_IRQHandler, /* DMA1 Channel 1 */ DMA1_Channel2_IRQHandler, /* DMA1 Channel 2 */ DMA1_Channel3_IRQHandler, /* DMA1 Channel 3 */ DMA1_Channel4_IRQHandler, /* DMA1 Channel 4 */ DMA1_Channel5_IRQHandler, /* DMA1 Channel 5 */ DMA1_Channel6_IRQHandler, /* DMA1 Channel 6 */ DMA1_Channel7_IRQHandler, /* DMA1 Channel 7 */ ADC1_2_IRQHandler, /* ADC1_2 */ USB_HP_CAN1_TX_IRQHandler, /* USB HP and CAN1 TX */ USB_LP_CAN1_RX0_IRQHandler, /* USB LP and CAN1RX0 */ CAN1_RX1_IRQHandler, /* CAN1 RX1 */ CAN1_SCE_IRQHandler, /* CAN1 SCE */ EXTI9_5_IRQHandler, /* EXTI Line 9..5 */ TIM1_BRK_IRQHandler, /* TIM1 Break */ TIM1_UP_IRQHandler, /* TIM1 Update */ TIM1_TRG_COM_IRQHandler, /* TIM1 Trigger and Commutation */ TIM1_CC_IRQHandler, /* TIM1 Capture Compare */ TIM2_IRQHandler, /* TIM2 */ TIM3_IRQHandler, /* TIM3 */ TIM4_IRQHandler, /* TIM4 */ I2C1_EV_IRQHandler, /* I2C1 Event */ I2C1_ER_IRQHandler, /* I2C1 Error */ I2C2_EV_IRQHandler, /* I2C2 Event */ I2C2_ER_IRQHandler, /* I2C2 Error */ SPI1_IRQHandler, /* SPI1 */ SPI2_IRQHandler, /* SPI2 */ USART1_IRQHandler, /* USART1 */ USART2_IRQHandler, /* USART2 */ USART3_IRQHandler, /* USART3 */ EXTI15_10_IRQHandler, /* EXTI Line 15..10 */ RTCAlarm_IRQHandler, /* RTC Alarm through EXTI Line */ USBWakeUp_IRQHandler, /* USB Wake up from suspend */ USBHD_IRQHandler, /* USBHD Break */ USBHDWakeUp_IRQHandler, /* USBHD Wake up from suspend */ ETH_IRQHandler, /* ETH global */ ETHWakeUp_IRQHandler, /* ETH Wake up */ 0, /* BLE BB */ 0, /* BLE LLE */ TIM5_IRQHandler, /* TIM5 */ UART4_IRQHandler, /* UART4 */ DMA1_Channel8_IRQHandler, /* DMA1 Channel8 */ OSC32KCal_IRQHandler, /* OSC32KCal */ OSCWakeUp_IRQHandler, /* OSC Wake Up */ }; #if 0 void InterruptVectorDefault() noexcept { asm volatile( R"---( .align 1 .option norvc; .word Init .word 0 .word NMI_Handler /* NMI */ .word HardFault_Handler /* Hard Fault */ .word 0 .word Ecall_M_Mode_Handler /* Ecall M Mode */ .word 0 .word 0 .word Ecall_U_Mode_Handler /* Ecall U Mode */ .word Break_Point_Handler /* Break Point */ .word 0 .word 0 .word SysTick_Handler /* SysTick Handler */ .word 0 .word SW_Handler /* SW Handler */ .word 0 /* External Interrupts */ .word WWDG_IRQHandler /* Window Watchdog */ .word PVD_IRQHandler /* PVD through EXTI Line detect */ .word TAMPER_IRQHandler /* TAMPER */ .word RTC_IRQHandler /* RTC */ .word FLASH_IRQHandler /* Flash */ .word RCC_IRQHandler /* RCC */ .word EXTI0_IRQHandler /* EXTI Line 0 */ .word EXTI1_IRQHandler /* EXTI Line 1 */ .word EXTI2_IRQHandler /* EXTI Line 2 */ .word EXTI3_IRQHandler /* EXTI Line 3 */ .word EXTI4_IRQHandler /* EXTI Line 4 */ .word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */ .word DMA1_Channel2_IRQHandler /* DMA1 Channel 2 */ .word DMA1_Channel3_IRQHandler /* DMA1 Channel 3 */ .word DMA1_Channel4_IRQHandler /* DMA1 Channel 4 */ .word DMA1_Channel5_IRQHandler /* DMA1 Channel 5 */ .word DMA1_Channel6_IRQHandler /* DMA1 Channel 6 */ .word DMA1_Channel7_IRQHandler /* DMA1 Channel 7 */ .word ADC1_2_IRQHandler /* ADC1_2 */ .word USB_HP_CAN1_TX_IRQHandler /* USB HP and CAN1 TX */ .word USB_LP_CAN1_RX0_IRQHandler /* USB LP and CAN1RX0 */ .word CAN1_RX1_IRQHandler /* CAN1 RX1 */ .word CAN1_SCE_IRQHandler /* CAN1 SCE */ .word EXTI9_5_IRQHandler /* EXTI Line 9..5 */ .word TIM1_BRK_IRQHandler /* TIM1 Break */ .word TIM1_UP_IRQHandler /* TIM1 Update */ .word TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */ .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ .word TIM2_IRQHandler /* TIM2 */ .word TIM3_IRQHandler /* TIM3 */ .word TIM4_IRQHandler /* TIM4 */ .word I2C1_EV_IRQHandler /* I2C1 Event */ .word I2C1_ER_IRQHandler /* I2C1 Error */ .word I2C2_EV_IRQHandler /* I2C2 Event */ .word I2C2_ER_IRQHandler /* I2C2 Error */ .word SPI1_IRQHandler /* SPI1 */ .word SPI2_IRQHandler /* SPI2 */ .word USART1_IRQHandler /* USART1 */ .word USART2_IRQHandler /* USART2 */ .word USART3_IRQHandler /* USART3 */ .word EXTI15_10_IRQHandler /* EXTI Line 15..10 */ .word RTCAlarm_IRQHandler /* RTC Alarm through EXTI Line */ .word USBWakeUp_IRQHandler /* USB Wake up from suspend */ .word USBHD_IRQHandler /* USBHD Break */ .word USBHDWakeUp_IRQHandler /* USBHD Wake up from suspend */ .word ETH_IRQHandler /* ETH global */ .word ETHWakeUp_IRQHandler /* ETH Wake up */ .word 0 /* BLE BB */ .word 0 /* BLE LLE */ .word TIM5_IRQHandler /* TIM5 */ .word UART4_IRQHandler /* UART4 */ .word DMA1_Channel8_IRQHandler /* DMA1 Channel8 */ .word OSC32KCal_IRQHandler /* OSC32KCal */ .word OSCWakeUp_IRQHandler /* OSC Wake Up */ )---"); } #endif void Init() { asm volatile( R"---( .align 1 _start: j handle_reset .rept 12 .word 0x00000013 .endr .word 0x00100073 )---"); } void handle_reset() noexcept { asm volatile(R"---( .option push .option norelax la gp, __global_pointer$ .option pop la sp, _eusrstack )---" #if __GNUC__ > 10 ".option arch, +zicsr\n" #endif // Setup the interrupt vector, processor status and INTSYSCR. R"---( li t0, 0x1f csrw 0xbc0, t0 /* Enabled nested and hardware stack */ li t0, 0x88 csrs mstatus, t0 la t0, InterruptVector ori t0, t0, 3 csrw mtvec, t0 /* Takhle RISC-V přejde do uživatelského programu. */ csrw mepc, %[user] mret )---" : : [user]"r"(user_prog)/*, "InterruptVector" (InterruptVector)*/ : "t0", "memory" ); } void user_prog () { SystemInit (); __init_array(); main(); for (;;); }