/********************************** (C) COPYRIGHT ******************************* * File Name : startup_ch57x.s * Author : WCH * Version : V1.0.1 * Date : 2020/04/30 * Description : ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ .section .init,"ax",@progbits .global _start .align 1 _start: j handle_reset .section .vector,"ax",@progbits .align 1 _vector_base: .option norvc; .word 0 .word 0 j NMI_Handler /* NMI Handler */ j HardFault_Handler /* Hard Fault Handler */ .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 j SysTick_Handler /* SysTick Handler */ .word 0 j SW_Handler /* SW Handler */ .word 0 /* External Interrupts */ j TMR0_IRQHandler /* 0: TMR0 */ j GPIOA_IRQHandler /* GPIOA */ j GPIOB_IRQHandler /* GPIOB */ j SPI0_IRQHandler /* SPI0 */ j BB_IRQHandler /* BLEB */ j LLE_IRQHandler /* BLEL */ j USB_IRQHandler /* USB */ .word 0 j TMR1_IRQHandler /* TMR1 */ j TMR2_IRQHandler /* TMR2 */ j UART0_IRQHandler /* UART0 */ j UART1_IRQHandler /* UART1 */ j RTC_IRQHandler /* RTC */ j ADC_IRQHandler /* ADC */ .word 0 j PWMX_IRQHandler /* PWMX */ j TMR3_IRQHandler /* TMR3 */ j UART2_IRQHandler /* UART2 */ j UART3_IRQHandler /* UART3 */ j WDOG_BAT_IRQHandler /* WDOG_BAT */ .option rvc; .section .vector_handler, "ax", @progbits .weak NMI_Handler .weak HardFault_Handler .weak SysTick_Handler .weak SW_Handler .weak TMR0_IRQHandler .weak GPIOA_IRQHandler .weak GPIOB_IRQHandler .weak SPI0_IRQHandler .weak BB_IRQHandler .weak LLE_IRQHandler .weak USB_IRQHandler .weak TMR1_IRQHandler .weak TMR2_IRQHandler .weak UART0_IRQHandler .weak UART1_IRQHandler .weak RTC_IRQHandler .weak ADC_IRQHandler .weak PWMX_IRQHandler .weak TMR3_IRQHandler .weak UART2_IRQHandler .weak UART3_IRQHandler .weak WDOG_BAT_IRQHandler NMI_Handler: 1: j 1b HardFault_Handler: 1: j 1b SysTick_Handler: 1: j 1b SW_Handler: 1: j 1b TMR0_IRQHandler: 1: j 1b GPIOA_IRQHandler: 1: j 1b GPIOB_IRQHandler: 1: j 1b SPI0_IRQHandler: 1: j 1b BB_IRQHandler: 1: j 1b LLE_IRQHandler: 1: j 1b USB_IRQHandler: 1: j 1b TMR1_IRQHandler: 1: j 1b TMR2_IRQHandler: 1: j 1b UART0_IRQHandler: 1: j 1b UART1_IRQHandler: 1: j 1b RTC_IRQHandler: 1: j 1b ADC_IRQHandler: 1: j 1b PWMX_IRQHandler: 1: j 1b TMR3_IRQHandler: 1: j 1b UART2_IRQHandler: 1: j 1b UART3_IRQHandler: 1: j 1b WDOG_BAT_IRQHandler: 1: j 1b .section .handle_reset,"ax",@progbits .weak handle_reset .align 1 handle_reset: .option push .option norelax la gp, __global_pointer$ .option pop 1: la sp, _eusrstack /* Load highcode code section from flash to RAM */ 2: la a0, _highcode_lma la a1, _highcode_vma_start la a2, _highcode_vma_end bgeu a1, a2, 2f 1: lw t0, (a0) sw t0, (a1) addi a0, a0, 4 addi a1, a1, 4 bltu a1, a2, 1b /* Load data section from flash to RAM */ 2: la a0, _data_lma la a1, _data_vma 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, _sbss la a1, _ebss bgeu a0, a1, 2f 1: sw zero, (a0) addi a0, a0, 4 bltu a0, a1, 1b 2: li t0, 0x88 csrs mstatus, t0 la t0, _vector_base ori t0, t0, 1 csrw mtvec, t0 lui a4,0x40001 li a5,87 sb a5,64(a4) li a5,-88 sb a5,64(a4) fence.i lw a5,72(a4) lui a3,0xfa000 addi a3,a3,-8 and a5,a5,a3 lui a3,0x6000 addi a3,a3,5 or a5,a5,a3 sw a5,72(a4) la t0, main csrw mepc, t0 /* enable vector relocation li t0, 0xE000ED14 li t1, 1 sw t1, 0(t0)*/ mret 上面的代码时ch571单片机的启动文件,帮我注释一下这个文件,并详细解释
时间: 2025-07-07 20:10:35 浏览: 12
这段代码是CH571单片机的启动文件(startup_ch57x.s),主要负责初始化硬件环境并跳转到C语言的main函数。下面是详细的注释和解释:
```assembly
.section .init,"ax",@progbits
.global _start
.align 1
_start:
j handle_reset // 程序入口,跳转到 handle_reset 标签处执行
.section .vector,"ax",@progbits
.align 1
_vector_base: // 中断向量表定义
.option norvc; // 关闭压缩指令模式
.word 0 // 预留空间
.word 0 // 堆栈指针初始值(通常在链接脚本中定义)
j NMI_Handler /* NMI Handler */
j HardFault_Handler /* Hard Fault Handler */
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
j SysTick_Handler /* SysTick Handler */
.word 0
j SW_Handler /* SW Handler */
.word 0
/* External Interrupts */
j TMR0_IRQHandler /* 0: TMR0 */
j GPIOA_IRQHandler /* GPIOA */
j GPIOB_IRQHandler /* GPIOB */
j SPI0_IRQHandler /* SPI0 */
j BB_IRQHandler /* BLEB */
j LLE_IRQHandler /* BLEL */
j USB_IRQHandler /* USB */
.word 0
j TMR1_IRQHandler /* TMR1 */
j TMR2_IRQHandler /* TMR2 */
j UART0_IRQHandler /* UART0 */
j UART1_IRQHandler /* UART1 */
j RTC_IRQHandler /* RTC */
j ADC_IRQHandler /* ADC */
.word 0
j PWMX_IRQHandler /* PWMX */
j TMR3_IRQHandler /* TMR3 */
j UART2_IRQHandler /* UART2 */
j UART3_IRQHandler /* UART3 */
j WDOG_BAT_IRQHandler /* WDOG_BAT */
.option rvc; // 恢复使用压缩指令模式
.section .vector_handler, "ax", @progbits
.weak NMI_Handler
.weak HardFault_Handler
.weak SysTick_Handler
.weak SW_Handler
.weak TMR0_IRQHandler
.weak GPIOA_IRQHandler
.weak GPIOB_IRQHandler
.weak SPI0_IRQHandler
.weak BB_IRQHandler
.weak LLE_IRQHandler
.weak USB_IRQHandler
.weak TMR1_IRQHandler
.weak TMR2_IRQHandler
.weak UART0_IRQHandler
.weak UART1_IRQHandler
.weak RTC_IRQHandler
.weak ADC_IRQHandler
.weak PWMX_IRQHandler
.weak TMR3_IRQHandler
.weak UART2_IRQHandler
.weak UART3_IRQHandler
.weak WDOG_BAT_IRQHandler
// 所有中断服务程序默认为死循环
NMI_Handler: 1: j 1b
HardFault_Handler: 1: j 1b
SysTick_Handler: 1: j 1b
SW_Handler: 1: j 1b
TMR0_IRQHandler: 1: j 1b
GPIOA_IRQHandler: 1: j 1b
GPIOB_IRQHandler: 1: j 1b
SPI0_IRQHandler: 1: j 1b
BB_IRQHandler: 1: j 1b
LLE_IRQHandler: 1: j 1b
USB_IRQHandler: 1: j 1b
TMR1_IRQHandler: 1: j 1b
TMR2_IRQHandler: 1: j 1b
UART0_IRQHandler: 1: j 1b
UART1_IRQHandler: 1: j 1b
RTC_IRQHandler: 1: j 1b
ADC_IRQHandler: 1: j 1b
PWMX_IRQHandler: 1: j 1b
TMR3_IRQHandler: 1: j 1b
UART2_IRQHandler: 1: j 1b
UART3_IRQHandler: 1: j 1b
WDOG_BAT_IRQHandler: 1: j 1b
.section .handle_reset,"ax",@progbits
.weak handle_reset
.align 1
handle_reset:
.option push
.option norelax
la gp, __global_pointer$ // 加载全局指针寄存器gp
.option pop
1:
la sp, _eusrstack // 初始化堆栈指针sp
/* Load highcode code section from flash to RAM */
2:
la a0, _highcode_lma // 将highcode段从flash加载到RAM
la a1, _highcode_vma_start
la a2, _highcode_vma_end
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
/* Load data section from flash to RAM */
2:
la a0, _data_lma // 将data段从flash加载到RAM
la a1, _data_vma
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 */ // 清零bss段
la a0, _sbss
la a1, _ebss
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b
2:
li t0, 0x88 // 设置MSTATUS寄存器使能全局中断
csrs mstatus, t0
la t0, _vector_base // 设置中断向量基地址
ori t0, t0, 1
csrw mtvec, t0
lui a4,0x40001 // 特定于芯片的初始化操作
li a5,87
sb a5,64(a4)
li a5,-88
sb a5,64(a4)
fence.i
lw a5,72(a4)
lui a3,0xfa000
addi a3,a3,-8
and a5,a5,a3
lui a3,0x6000
addi a3,a3,5
or a5,a5,a3
sw a5,72(a4)
la t0, main // 跳转到main函数
csrw mepc, t0
/* enable vector relocation
li t0, 0xE000ED14
li t1, 1
sw t1, 0(t0)*/
mret // 返回到main函数执行
```
### 解释:
1. **程序入口:**
- `_start` 是程序的入口点,它会跳转到 `handle_reset` 标签。
2. **中断向量表:**
- 定义了所有异常和中断的服务程序入口地址。
- 使用 `.j` 指令将控制权转移到相应的中断处理程序。
- 默认情况下,未实现的中断处理程序是一个无限循环(`j 1b`)。
3. **内存初始化:**
- 初始化 `.highcode` 和 `.data` 段,这些数据通常存储在Flash中,在运行前需要复制到RAM中。
- 清除 `.bss` 段,确保未初始化的数据归零。
4. **设置寄存器:**
- 设置全局指针 `gp` 和堆栈指针 `sp`。
- 配置 MSTATUS 寄存器以启用全局中断。
- 设置中断向量基地址 `mtvec`。
5. **跳转到main函数:**
- 最后通过 `mret` 指令返回到 `main` 函数开始执行用户代码。
---
###
阅读全文