RISC-V MCU启动文件分析

启动文件由汇编语言编写,是MCU上电复位后第一个执行的程序。主要执行以下内容:

  • 初始化gp(global pointer)全局指针寄存器、sp(stack pointer)栈指针寄存器
  • 将data数据从flash中加载至RAM中
  • 清空bss段数据
  • 初始化中断向量表
  • 配置系统时钟
  • 从Machine模式切换到User模式,进入main函数运行

CH32V103启动文件如下:

复制代码
  1 /********************************** (C) COPYRIGHT *******************************
  2 * File Name          : startup_ch32v10x.s
  3 * Author             : WCH
  4 * Version            : V1.0.0
  5 * Date               : 2020/04/30
  6 * Description        : CH32V10x vector table for eclipse toolchain.
  7 *******************************************************************************/
  8  
  9     .section    .init,"ax",@progbits     /* 声明section 为 .init */
 10     .global    _start                       /* 指明标签_start的属性为全局性的 */
 11     .align    1
 12 _start:                                  /* 标签_start处 */
 13     j    handle_reset                     /* 跳转至 handle_reset处 */
 14     .word 0x00000013                     /* 内核设计需要,不用关注 */
 15     .word 0x00000013
 16     .word 0x00000013
 17     .word 0x00000013
 18     .word 0x00000013
 19     .word 0x00000013
 20     .word 0x00000013
 21     .word 0x00000013
 22     .word 0x00000013
 23     .word 0x00000013
 24     .word 0x00000013
 25     .word 0x00000013
 26     .word 0x00100073
 27     .section    .vector,"ax",@progbits
 28     .align  1
 29 _vector_base:                           /* 中断向量表  */
 30     .option norvc;
 31         j   _start
 32     .word   0
 33         j   NMI_Handler                 /* NMI Handler */
 34         j   HardFault_Handler           /* Hard Fault Handler */
 35     .word   0
 36     .word   0
 37     .word   0
 38     .word   0
 39     .word   0
 40     .word   0
 41     .word   0
 42     .word   0
 43         j   SysTick_Handler            /* SysTick Handler */
 44     .word   0
 45         j   SW_handler                 /* SW Handler */
 46     .word   0
 47     /* External Interrupts */
 48         j   WWDG_IRQHandler            /* Window Watchdog */
 49         j   PVD_IRQHandler             /* PVD through EXTI Line detect */
 50         j   TAMPER_IRQHandler          /* TAMPER */
 51         j   RTC_IRQHandler             /* RTC */
 52         j   FLASH_IRQHandler           /* Flash */
 53         j   RCC_IRQHandler             /* RCC */
 54         j   EXTI0_IRQHandler           /* EXTI Line 0 */
 55         j   EXTI1_IRQHandler           /* EXTI Line 1 */
 56         j   EXTI2_IRQHandler           /* EXTI Line 2 */
 57         j   EXTI3_IRQHandler           /* EXTI Line 3 */
 58         j   EXTI4_IRQHandler           /* EXTI Line 4 */
 59         j   DMA1_Channel1_IRQHandler   /* DMA1 Channel 1 */
 60         j   DMA1_Channel2_IRQHandler   /* DMA1 Channel 2 */
 61         j   DMA1_Channel3_IRQHandler   /* DMA1 Channel 3 */
 62         j   DMA1_Channel4_IRQHandler   /* DMA1 Channel 4 */
 63         j   DMA1_Channel5_IRQHandler   /* DMA1 Channel 5 */
 64         j   DMA1_Channel6_IRQHandler   /* DMA1 Channel 6 */
 65         j   DMA1_Channel7_IRQHandler   /* DMA1 Channel 7 */
 66         j   ADC1_2_IRQHandler          /* ADC1_2 */
 67         .word   0
 68         .word   0
 69         .word   0
 70         .word   0
 71         j   EXTI9_5_IRQHandler         /* EXTI Line 9..5 */
 72         j   TIM1_BRK_IRQHandler        /* TIM1 Break */
 73         j   TIM1_UP_IRQHandler         /* TIM1 Update */
 74         j   TIM1_TRG_COM_IRQHandler    /* TIM1 Trigger and Commutation */
 75         j   TIM1_CC_IRQHandler         /* TIM1 Capture Compare */
 76         j   TIM2_IRQHandler            /* TIM2 */
 77         j   TIM3_IRQHandler            /* TIM3 */
 78         j   TIM4_IRQHandler            /* TIM4 */
 79         j   I2C1_EV_IRQHandler         /* I2C1 Event */
 80         j   I2C1_ER_IRQHandler         /* I2C1 Error */
 81         j   I2C2_EV_IRQHandler         /* I2C2 Event */
 82         j   I2C2_ER_IRQHandler         /* I2C2 Error */
 83         j   SPI1_IRQHandler            /* SPI1 */
 84         j   SPI2_IRQHandler            /* SPI2 */
 85         j   USART1_IRQHandler          /* USART1 */
 86         j   USART2_IRQHandler          /* USART2 */
 87         j   USART3_IRQHandler          /* USART3 */
 88         j   EXTI15_10_IRQHandler       /* EXTI Line 15..10 */
 89         j   RTCAlarm_IRQHandler        /* RTC Alarm through EXTI Line */
 90         j   USBWakeUp_IRQHandler       /* USB Wakeup from suspend */
 91         j   USBHD_IRQHandler           /* USBHD */
 92  
 93     .option rvc;
 94  
 95     .section    .text.  , "ax", @progbits     /* 中断服务程序弱定义  */
 96     .weak   NMI_Handler
 97     .weak   HardFault_Handler
 98     .weak   SysTick_Handler
 99     .weak   SW_handler
100     .weak   WWDG_IRQHandler
101     .weak   PVD_IRQHandler
102     .weak   TAMPER_IRQHandler
103     .weak   RTC_IRQHandler
104     .weak   FLASH_IRQHandler
105     .weak   RCC_IRQHandler
106     .weak   EXTI0_IRQHandler
107     .weak   EXTI1_IRQHandler
108     .weak   EXTI2_IRQHandler
109     .weak   EXTI3_IRQHandler
110     .weak   EXTI4_IRQHandler
111     .weak   DMA1_Channel1_IRQHandler
112     .weak   DMA1_Channel2_IRQHandler
113     .weak   DMA1_Channel3_IRQHandler
114     .weak   DMA1_Channel4_IRQHandler
115     .weak   DMA1_Channel5_IRQHandler
116     .weak   DMA1_Channel6_IRQHandler
117     .weak   DMA1_Channel7_IRQHandler
118     .weak   ADC1_2_IRQHandler
119     .weak   EXTI9_5_IRQHandler
120     .weak   TIM1_BRK_IRQHandler
121     .weak   TIM1_UP_IRQHandler
122     .weak   TIM1_TRG_COM_IRQHandler
123     .weak   TIM1_CC_IRQHandler
124     .weak   TIM2_IRQHandler
125     .weak   TIM3_IRQHandler
126     .weak   TIM4_IRQHandler
127     .weak   I2C1_EV_IRQHandler
128     .weak   I2C1_ER_IRQHandler
129     .weak   I2C2_EV_IRQHandler
130     .weak   I2C2_ER_IRQHandler
131     .weak   SPI1_IRQHandler
132     .weak   SPI2_IRQHandler
133     .weak   USART1_IRQHandler
134     .weak   USART2_IRQHandler
135     .weak   USART3_IRQHandler
136     .weak   EXTI15_10_IRQHandler
137     .weak   RTCAlarm_IRQHandler
138     .weak   USBWakeUp_IRQHandler
139     .weak   USBHD_IRQHandler
140  
141     .section    .text.handle_reset,"ax",@progbits
142     .weak    handle_reset
143     .align    1
144 handle_reset:                     /*  handle_reset起始位置 */
145 .option push 
146 .option    norelax 
147     la gp, __global_pointer$       /* 将ld文件中的标签__global_pointer所处的地址值赋给gp寄存器 */
148 .option    pop 
149 1:
150     la sp, _eusrstack              /* 将ld文件中的标签_eusrstack所处的地址值赋给sp寄存器 */
151 2:
152     /* Load data section from flash to RAM */
153     la a0, _data_lma
154     la a1, _data_vma
155     la a2, _edata
156     bgeu a1, a2, 2f
157 1:
158     lw t0, (a0)
159     sw t0, (a1)
160     addi a0, a0, 4
161     addi a1, a1, 4
162     bltu a1, a2, 1b
163 2:
164     /* clear bss section */
165     la a0, _sbss
166     la a1, _ebss
167     bgeu a0, a1, 2f
168 1:
169     sw zero, (a0)
170     addi a0, a0, 4
171     bltu a0, a1, 1b
172 2:
173     /* enable all interrupt */  /* csrs ,根据寄存器中每个为1的位,把CSR寄存器对应位置位 */
174   li t0, 0x88
175   csrs mstatus, t0         /* 状态寄存器mstatus赋值为0x88,打开所有中断,设置MPP值为00 */
176     la t0, _vector_base
177   ori t0, t0, 1
178     csrw mtvec, t0         /* 将中断向量表的首地址赋值给mtvec寄存器(中断发生时PC的地址) */
179  
180   jal  SystemInit          /* 设置MCU系统时钟 */
181     la t0, main
182     csrw mepc, t0  
183     mret
184  
185 /*
186 mret返回指令(M模式特有的指令),调用该指令会进行如下操作:
187  
188 - 将PC指针设置为mepc的值
189 - 将mstatus的MPIE域复制到MIE来恢复之前的中断使能
190 - 将权限模式设置为mstatus的MPP域中的值。
191  
192 芯片上电默认进入的是机器模式,通过将mstatus中的MPP值设置为00(00: User, 01: Supervisor, 11: Machine),
193 并将main函数的地址赋值给mepc,调用mret,使得用户在进入main函数运行时,芯片由机器模式切换为用户模式。
194 */
复制代码

 

posted @   Zhu_zzzzzz  阅读(190)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示