首页 > 其他分享 >startup_ch32v00x.S启动文件分析(上)

startup_ch32v00x.S启动文件分析(上)

时间:2023-08-09 23:00:17浏览次数:48  
标签:ch32v00x word 启动 weak startup t0 IRQHandler DMA1 1b

引言

CH32系列MCU是由南京沁恒(WCH)公司推出的一系列处理器芯片。引自官网:

CH32V、CH32X、CH32L系列MCU采用自研的青稞RISC-V内核,基于蓬勃发展的RISC-V开源指令集架构,针对低功耗和高速响应等应用优化扩展,免费配套IDE等开发工具软件,免除第三方内核技术的授权费和提成费,通过内置和组合USB、PD、低功耗蓝牙、以太网等专业接口外设,构建了既有全球未来生态又能自主可控、且极具长期竞争力的MCU产品线。

产品页 - 青稞RISC-V通用系列

本文通过对 CH32V003 芯片所使用的启动文件 startup_ch32v00x.S 进行分析,梳理RISC-V芯片的启动过程。

文件内容预览

点击跳转查看

逐句分析

Part1 - Init

从代码第一行看起。

.section .init, "ax", @progbits

  • .section 标明本句为对段的定义。
  • .init是该段的名字。
  • "ax"标识段的权限,a代表运行时载入内存,x代表可执行。
  • @progbits标识了段的类型,表示“Section contains either initialized data and instructions or instructions only."。

.section完整语法文档

.globl _start

定义_start位置全局可见,用于作程序的起始地址。

.align 2

定义下一条指令/数据对齐方式。可确保下一条指令的地址为“2的x次方”的倍数。此处,2的2次方为4,因此下一条指令的地址将顺推至4的倍数。

注意与.balign伪指令的区分,其用于将下一条指令地址顺推至x的倍数。即.align 2等效于.balign 4。

_start:

程序起始位置。

.option norvc;

rvc、norvc是RISC-V架构特有的选项:

  • “.option rvc”伪操作表示接下来的汇编程序可以被汇编生成16位宽的压缩指令。
  • “.option norvc”伪操作表示接下来的汇编程序不可以被汇编生成16位宽的压缩指令

j handle_reset

跳转至 handle_reset 处。

Part2 - Reset

从代码106行开始看起。

.section .text.handle_reset, "ax", @progbits

对段的定义,不再赘述。

handle_reset:

由上一部分跳转至此,随后顺序执行。

.option push

  • “.option push”伪操作暂时将当前的选项设置保存起来,从而允许之后使用.option伪操作指定新的选项;而“.option pop”伪操作将最近保存的选项设置恢复出来重新生效。
  • 通过“.option push”和“.option pop”的组合,便可以在汇编程序中在不影响全局选项设置的情况下,为其中嵌入的某一段代码特别地设置不同的选项。

.option norelax

la gp, __global_pointer$

将ld文件中的标签__global_pointer所处的地址值赋给gp寄存器

.option pop

恢复option。

启动部分

把启动部分一起,通过注释进行解释。该部分用到的各类预设地址,均来自于ld链接脚本文件Link.ld。

1:
	la sp, _eusrstack               /* 将ld文件中的标签_eusrstack所处的地址值赋给sp寄存器 */
2:
	/* Load data section from flash to RAM */
	la a0, _data_lma                /* Flash中的data段地址 */
	la a1, _data_vma                /* 物理RAM地址 */
	la a2, _edata                   /* data段尾地址 */
	bgeu a1, a2, 2f                 /* a1 greater/equal a2时,跳转到下一个2标签 */
1:
	lw t0, (a0)
	sw t0, (a1)
	addi a0, a0, 4
	addi a1, a1, 4
	bltu a1, a2, 1b                 /* a1 less than a2时,跳转到上一个1标签 */
2:
    /* clear bss section */
    la a0, _sbss                    /* bss起始地址 */
    la a1, _ebss                    /* bss结尾地址 */
    bgeu a0, a1, 2f                 /* a0 greater/equal a1时,跳转到下一个2标签 */
1:
    sw zero, (a0)
    addi a0, a0, 4
    bltu a0, a1, 1b                 /* a0 less than a1时,跳转到上一个1标签 */
2:
    li t0, 0x80                     /* 立即数0x80 */
    csrw mstatus, t0                /* 写入mstatus寄存器 */
  
    li t0, 0x3                      /* 立即数0x3 */
    csrw 0x804, t0                  /* 写入intsyscr寄存器 */
  
    la t0, _start                   /* _start地址 */
    ori t0, t0, 3                   /* t0 = t0 | 3 */
    csrw mtvec, t0                  /* 写入mtvec寄存器 */
  
    jal   SystemInit                /* 跳转至SystemInit,随后函数返回 */
    la t0, main                     /* main函数地址 */
    csrw mepc, t0                   /* 写入mepc寄存器 */
    mret                            /* 退出机器模式,进入用户模式。 */

Part3 - INT vectors

剩余部分,为中断向量的设置,与MCU所提供的具体功能相关,不再赘述。

源代码

	.section  .init, "ax", @progbits
	.globl  _start
	.align  2
_start:
	.option   norvc;
    j       handle_reset
    .word   0
    .word   NMI_Handler                  /* NMI Handler */
    .word   HardFault_Handler            /* Hard Fault Handler */
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .word   0
    .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   FLASH_IRQHandler        	/* Flash */
    .word   RCC_IRQHandler          	/* RCC */
    .word   EXTI7_0_IRQHandler       	/* EXTI Line 7..0 */
    .word   AWU_IRQHandler              /* AWU */
    .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_IRQHandler          	/* ADC1 */
    .word   I2C1_EV_IRQHandler         	/* I2C1 Event */
    .word   I2C1_ER_IRQHandler         	/* I2C1 Error */
    .word   USART1_IRQHandler          	/* USART1 */
    .word   SPI1_IRQHandler            	/* SPI1 */
    .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 */

	.option rvc;
	.section  .text.vector_handler, "ax", @progbits
	.weak   NMI_Handler
	.weak   HardFault_Handler
	.weak   SysTick_Handler
	.weak   SW_Handler
	.weak   WWDG_IRQHandler
	.weak   PVD_IRQHandler
	.weak   FLASH_IRQHandler
	.weak   RCC_IRQHandler
	.weak   EXTI7_0_IRQHandler
	.weak   AWU_IRQHandler
	.weak   DMA1_Channel1_IRQHandler
	.weak   DMA1_Channel2_IRQHandler
	.weak   DMA1_Channel3_IRQHandler
	.weak   DMA1_Channel4_IRQHandler
	.weak   DMA1_Channel5_IRQHandler
	.weak   DMA1_Channel6_IRQHandler
	.weak   DMA1_Channel7_IRQHandler
	.weak   ADC1_IRQHandler
	.weak   I2C1_EV_IRQHandler
	.weak   I2C1_ER_IRQHandler
	.weak   USART1_IRQHandler
	.weak   SPI1_IRQHandler
	.weak   TIM1_BRK_IRQHandler
	.weak   TIM1_UP_IRQHandler
	.weak   TIM1_TRG_COM_IRQHandler
	.weak   TIM1_CC_IRQHandler
	.weak   TIM2_IRQHandler

NMI_Handler:              1: j 1b
HardFault_Handler:        1: j 1b
SysTick_Handler:          1: j 1b
SW_Handler:               1: j 1b
WWDG_IRQHandler:          1: j 1b
PVD_IRQHandler:           1: j 1b
FLASH_IRQHandler:         1: j 1b
RCC_IRQHandler:           1: j 1b
EXTI7_0_IRQHandler:       1: j 1b
AWU_IRQHandler:           1: j 1b
DMA1_Channel1_IRQHandler: 1: j 1b
DMA1_Channel2_IRQHandler: 1: j 1b
DMA1_Channel3_IRQHandler: 1: j 1b
DMA1_Channel4_IRQHandler: 1: j 1b
DMA1_Channel5_IRQHandler: 1: j 1b
DMA1_Channel6_IRQHandler: 1: j 1b
DMA1_Channel7_IRQHandler: 1: j 1b
ADC1_IRQHandler:          1: j 1b
I2C1_EV_IRQHandler:       1: j 1b
I2C1_ER_IRQHandler:       1: j 1b
USART1_IRQHandler:        1: j 1b
SPI1_IRQHandler:          1: j 1b
TIM1_BRK_IRQHandler:      1: j 1b
TIM1_UP_IRQHandler:       1: j 1b
TIM1_TRG_COM_IRQHandler:  1: j 1b
TIM1_CC_IRQHandler:       1: j 1b
TIM2_IRQHandler:          1: j 1b


	.section  .text.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
2:
	/* Load data section from flash to RAM */
	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, 0x80
    csrw mstatus, t0
  
    li t0, 0x3
    csrw 0x804, t0
  
    la t0, _start
    ori t0, t0, 3
    csrw mtvec, t0
  
    jal   SystemInit
    la t0, main
    csrw mepc, t0
    mret

点击返回

标签:ch32v00x,word,启动,weak,startup,t0,IRQHandler,DMA1,1b
From: https://www.cnblogs.com/3V4NZ/p/17619103.html

相关文章

  • Spring Boot 启动流程追踪(第一篇)
    1、初始化SpringApplication publicSpringApplication(ResourceLoaderresourceLoader,Class<?>...primarySources){ this.resourceLoader=resourceLoader; Assert.notNull(primarySources,"PrimarySourcesmustnotbenull"); this.primarySourc......
  • hadoop的相关启动
    1、先退回到hadoop主路径(也就是我上一篇中的hadoop-3.0.0)cd../..2、启动服务命令start-all.sh3、输入jps判断是否启动成功启动成功啦!......
  • 分析 Tomcat startup.bat 启动脚本
    分析Tomcatstartup.bat启动脚本闲来无事,平常容器多使用tomcat,所以今天就想打开tomcat启动脚本看看。都说tomcat是纯Java的,这东西只有自己打开看看才能知道。呵呵!      说来tomcat的脚本确实不难,启动脚本更是没有几行,以下是我解释的tomcatstartup.bat脚本。rem......
  • 服务器重启 docker服务自启动
    docker服务自启动容器还没运行时,可以加入dockerrun--restart=always容器已经运行时:dockerupdate--restart=always容器ID或者容器名##重启docker立即生效(systemctlrestartdocker)停止自启动:dockerupdate--restart=no容器ID或者容器名##重启docker立即......
  • SpringBoot启动项目失败但不报错
    新建的SpringBoot项目,点击启动,项目没有启动成功,但是不报错。如下:._________/\\/___'_____(_)______\\\\(()\___|'_|'_||'_\/_`|\\\\\\/___)||_)|||||||(_||))))'|____......
  • docker 启动redis 7.0.12
    1.拉取镜像 dockerpullredis:7.0.122.去官网下载对应的包,解压拿到redis.conf,下载地址:https://redis.io/download/bind127.0.0.1#注释掉这部分,使redis可以外部访问daemonizeno#用守护线程的方式启动requirepass你的密码#给redis设置密码appendonlyyes#r......
  • go 程序在windows 下已管理员方式启动
    funcAmAdmin()bool{ _,err:=os.Open("\\\\.\\PHYSICALDRIVE0") iferr!=nil{ fmt.Println("adminno") returnfalse } fmt.Println("adminyes") returntrue}funcRunMeElevated(){ verb:="runas"......
  • springboot不使用端口的方式启动
    SpringBoot项目不占用端口启动现在很多互联网公司或者项目,都使用SpringBoot+SpringCloud,以微服务的形式来提供后台服务。而且既然是微服务,所涉及到的项目就会很多,服务器端口资源就会相当紧张。而且,其实有些项目,如定时任务等,是不需要对外提供服务,也就不需要占用服务器端口的。......
  • 【代码块】-Helper-开机启动
    整理代码块代码块整理后存储,供后期使用usingMicrosoft.Win32;/*这段代码可以用于将一个程序设置为开机启动项,或者从开机启动项中移除*/publicclassStartupHelper{///<summary>///设置开机启动项///</summary>///<paramname="enabled">是否......
  • oobabooga-text-generation-webui可能是最好的语言模型启动器(包含手把手安装教程)
    https://www.bilibili.com/read/cv24006101/引言:问:oobabooga是什么?oobabooga-text-generation-webui是一个用于运行类似Chatglm、RWKV-Raven、Vicuna、MOSS、LLaMA、llama.cpp、GPT-J、Pythia、OPT和GALACTICA等大型语言模型的GradioWeb用户界面。它的目标是成为文本生成的AUT......