在GD官网上下载了固件工程GD32VF103_Demo_Suites_V1.2.0,使用eclipse编译工程,看代码启动文件start.s里只有调用到了main函数,没有调用_init()函数,_init()函数调用了系统时钟初始化SystemInit(),是哪里调用了我没发现吗?另外entry.s这个代码怎么理解?求解答,谢谢!
`void _init()
{
SystemInit();
//ECLIC init
eclic_init(ECLIC_NUM_INTERRUPTS);
eclic_mode_enable();
//printf("After ECLIC mode enabled, the mtvec value is %x \n\n\r", read_csr(mtvec));
// // It must be NOTED:
// // * In the RISC-V arch, if user mode and PMP supported, then by default if PMP is not configured
// // with valid entries, then user mode cannot access any memory, and cannot execute any instructions.
// // * So if switch to user-mode and still want to continue, then you must configure PMP first
//pmp_open_all_space();
//switch_m2u_mode();
/* Before enter into main, add the cycle/instret disable by default to save power,
only use them when needed to measure the cycle/instret */
disable_mcycle_minstret();
}`
start.s文件代码
`// See LICENSE for license details.
.section .init
.weak eclic_msip_handler
.weak eclic_mtip_handler
.weak eclic_bwei_handler
.weak eclic_pmovi_handler
.weak WWDGT_IRQHandler
.weak LVD_IRQHandler
.weak TAMPER_IRQHandler
.weak RTC_IRQHandler
.weak FMC_IRQHandler
.weak RCU_IRQHandler
.weak EXTI0_IRQHandler
.weak EXTI1_IRQHandler
.weak EXTI2_IRQHandler
.weak EXTI3_IRQHandler
.weak EXTI4_IRQHandler
.weak DMA0_Channel0_IRQHandler
.weak DMA0_Channel1_IRQHandler
.weak DMA0_Channel2_IRQHandler
.weak DMA0_Channel3_IRQHandler
.weak DMA0_Channel4_IRQHandler
.weak DMA0_Channel5_IRQHandler
.weak DMA0_Channel6_IRQHandler
.weak ADC0_1_IRQHandler
.weak CAN0_TX_IRQHandler
.weak CAN0_RX0_IRQHandler
.weak CAN0_RX1_IRQHandler
.weak CAN0_EWMC_IRQHandler
.weak EXTI5_9_IRQHandler
.weak TIMER0_BRK_IRQHandler
.weak TIMER0_UP_IRQHandler
.weak TIMER0_TRG_CMT_IRQHandler
.weak TIMER0_Channel_IRQHandler
.weak TIMER1_IRQHandler
.weak TIMER2_IRQHandler
.weak TIMER3_IRQHandler
.weak I2C0_EV_IRQHandler
.weak I2C0_ER_IRQHandler
.weak I2C1_EV_IRQHandler
.weak I2C1_ER_IRQHandler
.weak SPI0_IRQHandler
.weak SPI1_IRQHandler
.weak USART0_IRQHandler
.weak USART1_IRQHandler
.weak USART2_IRQHandler
.weak EXTI10_15_IRQHandler
.weak RTC_Alarm_IRQHandler
.weak USBFS_WKUP_IRQHandler
.weak TIMER4_IRQHandler
.weak SPI2_IRQHandler
.weak UART3_IRQHandler
.weak UART4_IRQHandler
.weak TIMER5_IRQHandler
.weak TIMER6_IRQHandler
.weak DMA1_Channel0_IRQHandler
.weak DMA1_Channel1_IRQHandler
.weak DMA1_Channel2_IRQHandler
.weak DMA1_Channel3_IRQHandler
.weak DMA1_Channel4_IRQHandler
.weak CAN1_TX_IRQHandler
.weak CAN1_RX0_IRQHandler
.weak CAN1_RX1_IRQHandler
.weak CAN1_EWMC_IRQHandler
.weak USBFS_IRQHandler
vector_base:
j _start
.align 2
.word 0
.word 0
.word eclic_msip_handler
.word 0
.word 0
.word 0
.word eclic_mtip_handler
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word eclic_bwei_handler
.word eclic_pmovi_handler
.word WWDGT_IRQHandler
.word LVD_IRQHandler
.word TAMPER_IRQHandler
.word RTC_IRQHandler
.word FMC_IRQHandler
.word RCU_IRQHandler
.word EXTI0_IRQHandler
.word EXTI1_IRQHandler
.word EXTI2_IRQHandler
.word EXTI3_IRQHandler
.word EXTI4_IRQHandler
.word DMA0_Channel0_IRQHandler
.word DMA0_Channel1_IRQHandler
.word DMA0_Channel2_IRQHandler
.word DMA0_Channel3_IRQHandler
.word DMA0_Channel4_IRQHandler
.word DMA0_Channel5_IRQHandler
.word DMA0_Channel6_IRQHandler
.word ADC0_1_IRQHandler
.word CAN0_TX_IRQHandler
.word CAN0_RX0_IRQHandler
.word CAN0_RX1_IRQHandler
.word CAN0_EWMC_IRQHandler
.word EXTI5_9_IRQHandler
.word TIMER0_BRK_IRQHandler
.word TIMER0_UP_IRQHandler
.word TIMER0_TRG_CMT_IRQHandler
.word TIMER0_Channel_IRQHandler
.word TIMER1_IRQHandler
.word TIMER2_IRQHandler
.word TIMER3_IRQHandler
.word I2C0_EV_IRQHandler
.word I2C0_ER_IRQHandler
.word I2C1_EV_IRQHandler
.word I2C1_ER_IRQHandler
.word SPI0_IRQHandler
.word SPI1_IRQHandler
.word USART0_IRQHandler
.word USART1_IRQHandler
.word USART2_IRQHandler
.word EXTI10_15_IRQHandler
.word RTC_Alarm_IRQHandler
.word USBFS_WKUP_IRQHandler
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word TIMER4_IRQHandler
.word SPI2_IRQHandler
.word UART3_IRQHandler
.word UART4_IRQHandler
.word TIMER5_IRQHandler
.word TIMER6_IRQHandler
.word DMA1_Channel0_IRQHandler
.word DMA1_Channel1_IRQHandler
.word DMA1_Channel2_IRQHandler
.word DMA1_Channel3_IRQHandler
.word DMA1_Channel4_IRQHandler
.word 0
.word 0
.word CAN1_TX_IRQHandler
.word CAN1_RX0_IRQHandler
.word CAN1_RX1_IRQHandler
.word CAN1_EWMC_IRQHandler
.word USBFS_IRQHandler
.globl _start
.type _start,@function
_start:
csrc CSR_MSTATUS, MSTATUS_MIE
/* Jump to logical address first to ensure correct operation of RAM region */
la a0, _start
li a1, 1
slli a1, a1, 29
bleu a1, a0, _start0800
srli a1, a1, 2
bleu a1, a0, _start0800
la a0, _start0800
add a0, a0, a1
jr a0
_start0800:
/* Set the the NMI base to share with mtvec by setting CSR_MMISC_CTL */
li t0, 0x200
csrs CSR_MMISC_CTL, t0
/* Intial the mtvt*/
la t0, vector_base
csrw CSR_MTVT, t0
/* Intial the mtvt2 and enable it*/
la t0, irq_entry
csrw CSR_MTVT2, t0
csrs CSR_MTVT2, 0x1
/* Intial the CSR MTVEC for the Trap and NMI base addr*/
la t0, trap_entry
csrw CSR_MTVEC, t0
/* Enable FPU */
li t0, MSTATUS_FS
csrs mstatus, t0
csrw fcsr, x0
.option push
.option norelax
la gp, __global_pointer$
.option pop
la sp, _sp
/* Load data section */
la a0, _data_lma
la a1, _data
la a2, _edata
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
2:
/ Clear bss section /
la a0, bss_start
la a1, _end
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b
2:
/enable mcycle_minstret/
csrci CSR_MCOUNTINHIBIT, 0x5
/ Call global constructors /
la a0, libc_fini_array
call atexit
call __libc_init_array
/* argc = argv = 0 */
li a0, 0
li a1, 0
call main
tail exit
1:
j 1b
.global disable_mcycle_minstret
disable_mcycle_minstret:
csrsi CSR_MCOUNTINHIBIT, 0x5
ret
.global enable_mcycle_minstret
enable_mcycle_minstret:
csrci CSR_MCOUNTINHIBIT, 0x5
ret
entry.s文件代码
// See LICENSE for license details
#
.macro DISABLE_MIE
csrc CSR_MSTATUS, MSTATUS_MIE
.endm
.macro SAVE_CONTEXT
addi sp, sp, -20*REGBYTES - 20*FPREGBYTES
addi sp, sp, -20*REGBYTES
addi sp, sp, -20*REGBYTES
STORE x1, 0REGBYTES(sp)
STORE x4, 1REGBYTES(sp)
STORE x5, 2REGBYTES(sp)
STORE x6, 3REGBYTES(sp)
STORE x7, 4REGBYTES(sp)
STORE x10, 5REGBYTES(sp)
STORE x11, 6REGBYTES(sp)
STORE x12, 7REGBYTES(sp)
STORE x13, 8REGBYTES(sp)
STORE x14, 9REGBYTES(sp)
STORE x15, 10*REGBYTES(sp)
STORE x16, 11REGBYTES(sp)
STORE x17, 12REGBYTES(sp)
STORE x28, 13REGBYTES(sp)
STORE x29, 14REGBYTES(sp)
STORE x30, 15REGBYTES(sp)
STORE x31, 16REGBYTES(sp)
FPSTORE f0, (20REGBYTES + 0FPREGBYTES)(sp)
FPSTORE f1, (20REGBYTES + 1FPREGBYTES)(sp)
FPSTORE f2, (20REGBYTES + 2FPREGBYTES)(sp)
FPSTORE f3, (20REGBYTES + 3FPREGBYTES)(sp)
FPSTORE f4, (20REGBYTES + 4FPREGBYTES)(sp)
FPSTORE f5, (20REGBYTES + 5FPREGBYTES)(sp)
FPSTORE f6, (20REGBYTES + 6FPREGBYTES)(sp)
FPSTORE f7, (20REGBYTES + 7FPREGBYTES)(sp)
FPSTORE f10, (20REGBYTES + 8FPREGBYTES)(sp)
FPSTORE f11, (20REGBYTES + 9FPREGBYTES)(sp)
FPSTORE f12, (20REGBYTES + 10FPREGBYTES)(sp)
FPSTORE f13, (20REGBYTES + 11FPREGBYTES)(sp)
FPSTORE f14, (20REGBYTES + 12FPREGBYTES)(sp)
FPSTORE f15, (20REGBYTES + 13FPREGBYTES)(sp)
FPSTORE f16, (20REGBYTES + 14FPREGBYTES)(sp)
FPSTORE f17, (20REGBYTES + 15FPREGBYTES)(sp)
FPSTORE f28, (20REGBYTES + 16FPREGBYTES)(sp)
FPSTORE f29, (20REGBYTES + 17FPREGBYTES)(sp)
FPSTORE f30, (20REGBYTES + 18FPREGBYTES)(sp)
FPSTORE f31, (20REGBYTES + 19FPREGBYTES)(sp)
.endm
.macro RESTORE_CONTEXT
LOAD x1, 0REGBYTES(sp)
LOAD x4, 1REGBYTES(sp)
LOAD x5, 2REGBYTES(sp)
LOAD x6, 3REGBYTES(sp)
LOAD x7, 4REGBYTES(sp)
LOAD x10, 5REGBYTES(sp)
LOAD x11, 6REGBYTES(sp)
LOAD x12, 7REGBYTES(sp)
LOAD x13, 8REGBYTES(sp)
LOAD x14, 9REGBYTES(sp)
LOAD x15, 10*REGBYTES(sp)
LOAD x16, 11REGBYTES(sp)
LOAD x17, 12REGBYTES(sp)
LOAD x28, 13REGBYTES(sp)
LOAD x29, 14REGBYTES(sp)
LOAD x30, 15REGBYTES(sp)
LOAD x31, 16REGBYTES(sp)
/ Restore fp caller registers /
FPLOAD f0, (20REGBYTES + 0FPREGBYTES)(sp)
FPLOAD f1, (20REGBYTES + 1FPREGBYTES)(sp)
FPLOAD f2, (20REGBYTES + 2FPREGBYTES)(sp)
FPLOAD f3, (20REGBYTES + 3FPREGBYTES)(sp)
FPLOAD f4, (20REGBYTES + 4FPREGBYTES)(sp)
FPLOAD f5, (20REGBYTES + 5FPREGBYTES)(sp)
FPLOAD f6, (20REGBYTES + 6FPREGBYTES)(sp)
FPLOAD f7, (20REGBYTES + 7FPREGBYTES)(sp)
FPLOAD f10, (20REGBYTES + 8FPREGBYTES)(sp)
FPLOAD f11, (20REGBYTES + 9FPREGBYTES)(sp)
FPLOAD f12, (20REGBYTES + 10FPREGBYTES)(sp)
FPLOAD f13, (20REGBYTES + 11FPREGBYTES)(sp)
FPLOAD f14, (20REGBYTES + 12FPREGBYTES)(sp)
FPLOAD f15, (20REGBYTES + 13FPREGBYTES)(sp)
FPLOAD f16, (20REGBYTES + 14FPREGBYTES)(sp)
FPLOAD f17, (20REGBYTES + 15FPREGBYTES)(sp)
FPLOAD f28, (20REGBYTES + 16FPREGBYTES)(sp)
FPLOAD f29, (20REGBYTES + 17FPREGBYTES)(sp)
FPLOAD f30, (20REGBYTES + 18FPREGBYTES)(sp)
FPLOAD f31, (20REGBYTES + 19FPREGBYTES)(sp)
addi sp, sp, 20*REGBYTES + 20*FPREGBYTES
addi sp, sp, 20*REGBYTES
// De-allocate the stack space
addi sp, sp, 20*REGBYTES
.endm
.macro RESTORE_CONTEXT_EXCPT_X5
LOAD x1, 0REGBYTES(sp)
LOAD x6, 2REGBYTES(sp)
LOAD x7, 3REGBYTES(sp)
LOAD x10, 4REGBYTES(sp)
LOAD x11, 5REGBYTES(sp)
LOAD x12, 6REGBYTES(sp)
LOAD x13, 7REGBYTES(sp)
LOAD x14, 8REGBYTES(sp)
LOAD x15, 9*REGBYTES(sp)
LOAD x16, 10REGBYTES(sp)
LOAD x17, 11REGBYTES(sp)
LOAD x28, 12REGBYTES(sp)
LOAD x29, 13REGBYTES(sp)
LOAD x30, 14REGBYTES(sp)
LOAD x31, 15REGBYTES(sp)
.endm
.macro RESTORE_CONTEXT_ONLY_X5
LOAD x5, 1*REGBYTES(sp)
.endm
#
.macro SAVE_EPC_STATUS
csrr x5, CSR_MEPC
STORE x5, 16REGBYTES(sp)
csrr x5, CSR_MSTATUS
STORE x5, 17REGBYTES(sp)
csrr x5, CSR_MSUBM
STORE x5, 18*REGBYTES(sp)
.endm
#
.macro RESTORE_EPC_STATUS
LOAD x5, 16REGBYTES(sp)
csrw CSR_MEPC, x5
LOAD x5, 17REGBYTES(sp)
csrw CSR_MSTATUS, x5
LOAD x5, 18*REGBYTES(sp)
csrw CSR_MSUBM, x5
.endm
// Trap entry point
//
.section .text.trap
.align 6// In CLIC mode, the trap entry must be 64bytes aligned
.global trap_entry
.weak trap_entry
trap_entry:
// Allocate the stack space
// addi sp, sp, -19*REGBYTES
// Save the caller saving registers (context)
SAVE_CONTEXT
// Save the MEPC/Mstatus/Msubm reg
SAVE_EPC_STATUS
// Set the function argument
csrr a0, mcause
mv a1, sp
// Call the function
call handle_trap
// Restore the MEPC/Mstatus/Msubm reg
RESTORE_EPC_STATUS
// Restore the caller saving registers (context)
RESTORE_CONTEXT
// De-allocate the stack space
// addi sp, sp, 19*REGBYTES
// Return to regular code
mret
// IRQ entry point
//
.section .text.irq
.align 2
.global irq_entry
.weak irq_entry
irq_entry: // ——————-> This label will be set to MTVT2 register
// Allocate the stack space
SAVE_CONTEXT// Save 16 regs
//———This special CSR read operation, which is actually use mcause as operand to directly store it to memory
csrrwi x0, CSR_PUSHMCAUSE, 17
//———This special CSR read operation, which is actually use mepc as operand to directly store it to memory
csrrwi x0, CSR_PUSHMEPC, 18
//———This special CSR read operation, which is actually use Msubm as operand to directly store it to memory
csrrwi x0, CSR_PUSHMSUBM, 19
service_loop:
//———This special CSR read/write operation, which is actually Claim the CLIC to find its pending highest
// ID, if the ID is not 0, then automatically enable the mstatus.MIE, and jump to its vector-entry-label, and
// update the link register
csrrw ra, CSR_JALMNXTI, ra
//RESTORE_CONTEXT_EXCPT_X5
DISABLE_MIE # Disable interrupts
LOAD x5, 19REGBYTES(sp)
csrw CSR_MSUBM, x5
LOAD x5, 18REGBYTES(sp)
csrw CSR_MEPC, x5
LOAD x5, 17*REGBYTES(sp)
csrw CSR_MCAUSE, x5
RESTORE_CONTEXT
// Return to regular code
mret