舒伯特玫瑰 发表于 2023-4-28 00:59

小华半导体芯片启动文件详细讲解

本文的源码文件名为:startup_hcf460.S,是一个纯汇编文件。


首先要掌握一些基础的汇编语法,主要用到的列表标出(参考stm32相关资料):

https://img-blog.csdnimg.cn/9d1227ccdabc415a90ad88a3d2dd2a98.jpeg因为和stm32不同,华大芯片的sram3区域有点特殊,参考华大芯片用户手册。


舒伯特玫瑰 发表于 2023-4-28 00:59

启动文件中使用STR指令,STR指令的格式为:
STR{条件}源寄存器,<存储器地址>
STR指令用亍从源寄存器中将一个32位的字数据传送到存储器中。该指令在程序设计中比较常
用,丏寻址方式灵活多样,使用方式可参考指令LDR。

舒伯特玫瑰 发表于 2023-4-28 00:59

指令示例:
STR R0,,#8             ;将R0中的字数据写入以R1为地址的存储器中,并将新地址R1+8写入R1。
STR R0,             ;将R0中的字数据写入以R1+8为地址的存储器中。”
str   r1,                      ;将r1寄存器的值,传送到地址值为r0的(存储器)内存中

注意分号;在汇编里面是注释的标识,类似C++ 的//。

舒伯特玫瑰 发表于 2023-4-28 00:59

1. 栈区域
Stack_Size      EQU   0x00000400

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

舒伯特玫瑰 发表于 2023-4-28 01:00

开辟栈的大小为0x00000400(1k B),名字为STACK,NOINIT即不初始化,可读可写,8(23)字节对齐。栈是用于局部变量、函数调用、函数形参等的开销,栈的大小不能超过内部SRAM的大小。如果编写的程序比较大,定义的局部变量很多,那么就需要修改栈的大小。如果某一天,你写的程序出现了莫名奇怪的错误,并进入了硬fault,这时就要考虑下是不是栈不够大,溢出了。EQU:宏定义的伪指令,相当于等于,类似于C中的define。

舒伯特玫瑰 发表于 2023-4-28 01:00

AREA:告诉汇编器汇编一个新的代码段或者数据段。

STACK表示段名,这个可以任意命名;NOINIT表示不初始化;READWRITE表示可读可写,ALIGN=3,表示按照2^3对齐,即8字节对齐。

SPACE:用于分配一定大小的内存空间,单位为字节。这里指定大小等于Stack_Size。标号__initial_sp紧挨着SPACE语句放置,表示栈的结束地址,即栈顶地址(栈是由高向低生长的)。

舒伯特玫瑰 发表于 2023-4-28 01:00

2. 堆区域Heap_Size       EQU   0x00000200

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem      SPACE   Heap_Size
__heap_limit

舒伯特玫瑰 发表于 2023-4-28 01:01

开辟堆的大小为0x00000200(512字节),名字为HEAP,NOINIT即不初始化,可读可写,8(2^3)字节对齐。__heap_base表示堆的起始地址,__heap_limit表示堆的结束地址(堆是由低向高生长的,与栈的生长方向相反)。堆主要用于动态内存的分配,像malloc()函数申请的内存就在堆上面。
                PRESERVE8
                THUMB

舒伯特玫瑰 发表于 2023-4-28 01:01

PRESERVE8:指定当前文件的堆栈按照8字节对齐。

THUMB:表示后面指令兼容THUMB指令。

THUBM是ARM以前的指令集,16位。现在Cortex-M系列都使用THUMB-2指令集,THUMB-2是32位的,兼容16位和32位的指令,是THUMB的超集。

舒伯特玫瑰 发表于 2023-4-28 01:01

3. 向量表
                AREA    RESET, DATA, READONLY
                EXPORT__Vectors
                EXPORT__Vectors_End
                EXPORT__Vectors_Size

舒伯特玫瑰 发表于 2023-4-28 01:01

定义一个数据段,名字为RESET,可读,并声明__Vectors、__Vectors_End和__Vectors_Size这3个标号具有全局属性,可供外部的文件调用。

舒伯特玫瑰 发表于 2023-4-28 01:01

EXPORT:声明一个标号可被外部的文件使用,使标号具有全局属性。如果是IAR编译器,则使用GLOBAL这个指令。当内核响应了一个发生的异常后,对应的异常服务例程(ESR)就会执行。为了决定ESR的入口地址,内核使用了“向量表查表机制”。这里使用一张向量表,见下表。向量表其实是一个WORD(32位整数)数组,每个下标对应一种异常,该下标元素的值则是该ESR的入口地址。向量表在地址空间中的位置是可以设置的,通过NVIC中的一个重定位寄存器来指出向量表的地址。在复位后,该寄存器的值为0。因此,在地址0(即Flash地址0)处必须包含一张向量表,用于初始时的异常分配。要注意的是,这里有个另类:0号类型并不是什么入口地址,而是给出了复位后MSP的初值。

中断向量表可以参考用户手册,注意的是,官网上面已经更新了driver库,用户手册也更新了。

舒伯特玫瑰 发表于 2023-4-28 01:02

舒伯特玫瑰 发表于 2023-4-28 01:02

向量表的代码比较长,占据了启动代码的大部分篇幅。__Vectors       DCD   __initial_sp            ; Top of Stack
                DCD   Reset_Handler             ; Reset Handler
                DCD   NMI_Handler               ; NMI Handler
                DCD   HardFault_Handler         ; Hard Fault Handler
                DCD   MemManage_Handler         ; MPU Fault Handler
                DCD   BusFault_Handler          ; Bus Fault Handler
                DCD   UsageFault_Handler      ; Usage Fault Handler
                DCD   0                         ; Reserved
                DCD   0                         ; Reserved
                DCD   0                         ; Reserved
                DCD   0                         ; Reserved
                DCD   SVC_Handler               ; SVCall Handler
                DCD   DebugMon_Handler          ; Debug Monitor Handler
                DCD   0                         ; Reserved
                DCD   PendSV_Handler            ; PendSV Handler
                DCD   SysTick_Handler         ; SysTick Handler

                ; Peripheral Interrupts
                DCD   IRQ000_Handler      ; IRQ000_Handler
                DCD   IRQ001_Handler      ; IRQ001_Handler
                DCD   IRQ002_Handler      ; IRQ002_Handler
                DCD   IRQ003_Handler      ; IRQ003_Handler
                DCD   IRQ004_Handler      ; IRQ004_Handler
                DCD   IRQ005_Handler      ; IRQ005_Handler
                DCD   IRQ006_Handler      ; IRQ006_Handler
                DCD   IRQ007_Handler      ; IRQ007_Handler
                DCD   IRQ008_Handler      ; IRQ008_Handler
                DCD   IRQ009_Handler      ; IRQ009_Handler
                DCD   IRQ010_Handler      ; IRQ010_Handler
                DCD   IRQ011_Handler      ; IRQ011_Handler
                DCD   IRQ012_Handler      ; IRQ012_Handler
                DCD   IRQ013_Handler      ; IRQ013_Handler
                DCD   IRQ014_Handler      ; IRQ014_Handler
                DCD   IRQ015_Handler      ; IRQ015_Handler
                DCD   IRQ016_Handler      ; IRQ016_Handler
                DCD   IRQ017_Handler      ; IRQ017_Handler
                DCD   IRQ018_Handler      ; IRQ018_Handler
                DCD   IRQ019_Handler      ; IRQ019_Handler
                DCD   IRQ020_Handler      ; IRQ020_Handler
                DCD   IRQ021_Handler      ; IRQ021_Handler
                DCD   IRQ022_Handler      ; IRQ022_Handler
                DCD   IRQ023_Handler      ; IRQ023_Handler
                DCD   IRQ024_Handler      ; IRQ024_Handler
                DCD   IRQ025_Handler      ; IRQ025_Handler
                DCD   IRQ026_Handler      ; IRQ026_Handler
                DCD   IRQ027_Handler      ; IRQ027_Handler
                DCD   IRQ028_Handler      ; IRQ028_Handler
                DCD   IRQ029_Handler      ; IRQ029_Handler
                DCD   IRQ030_Handler      ; IRQ030_Handler
                DCD   IRQ031_Handler      ; IRQ031_Handler
                DCD   IRQ032_Handler      ; IRQ032_Handler
                DCD   IRQ033_Handler      ; IRQ033_Handler
                DCD   IRQ034_Handler      ; IRQ034_Handler
                DCD   IRQ035_Handler      ; IRQ035_Handler
                DCD   IRQ036_Handler      ; IRQ036_Handler
                DCD   IRQ037_Handler      ; IRQ037_Handler
                DCD   IRQ038_Handler      ; IRQ038_Handler
                DCD   IRQ039_Handler      ; IRQ039_Handler
                DCD   IRQ040_Handler      ; IRQ040_Handler
                DCD   IRQ041_Handler      ; IRQ041_Handler
                DCD   IRQ042_Handler      ; IRQ042_Handler
                DCD   IRQ043_Handler      ; IRQ043_Handler
                DCD   IRQ044_Handler      ; IRQ044_Handler
                DCD   IRQ045_Handler      ; IRQ045_Handler
                DCD   IRQ046_Handler      ; IRQ046_Handler
                DCD   IRQ047_Handler      ; IRQ047_Handler
                DCD   IRQ048_Handler      ; IRQ048_Handler
                DCD   IRQ049_Handler      ; IRQ049_Handler
                DCD   IRQ050_Handler      ; IRQ050_Handler
                DCD   IRQ051_Handler      ; IRQ051_Handler
                DCD   IRQ052_Handler      ; IRQ052_Handler
                DCD   IRQ053_Handler      ; IRQ053_Handler
                DCD   IRQ054_Handler      ; IRQ054_Handler
                DCD   IRQ055_Handler      ; IRQ055_Handler
                DCD   IRQ056_Handler      ; IRQ056_Handler
                DCD   IRQ057_Handler      ; IRQ057_Handler
                DCD   IRQ058_Handler      ; IRQ058_Handler
                DCD   IRQ059_Handler      ; IRQ059_Handler
                DCD   IRQ060_Handler      ; IRQ060_Handler
                DCD   IRQ061_Handler      ; IRQ061_Handler
                DCD   IRQ062_Handler      ; IRQ062_Handler
                DCD   IRQ063_Handler      ; IRQ063_Handler
                DCD   IRQ064_Handler      ; IRQ064_Handler
                DCD   IRQ065_Handler      ; IRQ065_Handler
                DCD   IRQ066_Handler      ; IRQ066_Handler
                DCD   IRQ067_Handler      ; IRQ067_Handler
                DCD   IRQ068_Handler      ; IRQ068_Handler
                DCD   IRQ069_Handler      ; IRQ069_Handler
                DCD   IRQ070_Handler      ; IRQ070_Handler
                DCD   IRQ071_Handler      ; IRQ071_Handler
                DCD   IRQ072_Handler      ; IRQ072_Handler
                DCD   IRQ073_Handler      ; IRQ073_Handler
                DCD   IRQ074_Handler      ; IRQ074_Handler
                DCD   IRQ075_Handler      ; IRQ075_Handler
                DCD   IRQ076_Handler      ; IRQ076_Handler
                DCD   IRQ077_Handler      ; IRQ077_Handler
                DCD   IRQ078_Handler      ; IRQ078_Handler
                DCD   IRQ079_Handler      ; IRQ079_Handler
                DCD   IRQ080_Handler      ; IRQ080_Handler
                DCD   IRQ081_Handler      ; IRQ081_Handler
                DCD   IRQ082_Handler      ; IRQ082_Handler
                DCD   IRQ083_Handler      ; IRQ083_Handler
                DCD   IRQ084_Handler      ; IRQ084_Handler
                DCD   IRQ085_Handler      ; IRQ085_Handler
                DCD   IRQ086_Handler      ; IRQ086_Handler
                DCD   IRQ087_Handler      ; IRQ087_Handler
                DCD   IRQ088_Handler      ; IRQ088_Handler
                DCD   IRQ089_Handler      ; IRQ089_Handler
                DCD   IRQ090_Handler      ; IRQ090_Handler
                DCD   IRQ091_Handler      ; IRQ091_Handler
                DCD   IRQ092_Handler      ; IRQ092_Handler
                DCD   IRQ093_Handler      ; IRQ093_Handler
                DCD   IRQ094_Handler      ; IRQ094_Handler
                DCD   IRQ095_Handler      ; IRQ095_Handler
                DCD   IRQ096_Handler      ; IRQ096_Handler
                DCD   IRQ097_Handler      ; IRQ097_Handler
                DCD   IRQ098_Handler      ; IRQ098_Handler
                DCD   IRQ099_Handler      ; IRQ099_Handler
                DCD   IRQ100_Handler      ; IRQ100_Handler
                DCD   IRQ101_Handler      ; IRQ101_Handler
                DCD   IRQ102_Handler      ; IRQ102_Handler
                DCD   IRQ103_Handler      ; IRQ103_Handler
                DCD   IRQ104_Handler      ; IRQ104_Handler
                DCD   IRQ105_Handler      ; IRQ105_Handler
                DCD   IRQ106_Handler      ; IRQ106_Handler
                DCD   IRQ107_Handler      ; IRQ107_Handler
                DCD   IRQ108_Handler      ; IRQ108_Handler
                DCD   IRQ109_Handler      ; IRQ109_Handler
                DCD   IRQ110_Handler      ; IRQ110_Handler
                DCD   IRQ111_Handler      ; IRQ111_Handler
                DCD   IRQ112_Handler      ; IRQ112_Handler
                DCD   IRQ113_Handler      ; IRQ113_Handler
                DCD   IRQ114_Handler      ; IRQ114_Handler
                DCD   IRQ115_Handler      ; IRQ115_Handler
                DCD   IRQ116_Handler      ; IRQ116_Handler
                DCD   IRQ117_Handler      ; IRQ117_Handler
                DCD   IRQ118_Handler      ; IRQ118_Handler
                DCD   IRQ119_Handler      ; IRQ119_Handler
                DCD   IRQ120_Handler      ; IRQ120_Handler
                DCD   IRQ121_Handler      ; IRQ121_Handler
                DCD   IRQ122_Handler      ; IRQ122_Handler
                DCD   IRQ123_Handler      ; IRQ123_Handler
                DCD   IRQ124_Handler      ; IRQ124_Handler
                DCD   IRQ125_Handler      ; IRQ125_Handler
                DCD   IRQ126_Handler      ; IRQ126_Handler
                DCD   IRQ127_Handler      ; IRQ127_Handler
                DCD   IRQ128_Handler      ; IRQ128_Handler
                DCD   IRQ129_Handler      ; IRQ129_Handler
                DCD   IRQ130_Handler      ; IRQ130_Handler
                DCD   IRQ131_Handler      ; IRQ131_Handler
                DCD   IRQ132_Handler      ; IRQ132_Handler
                DCD   IRQ133_Handler      ; IRQ133_Handler
                DCD   IRQ134_Handler      ; IRQ134_Handler
                DCD   IRQ135_Handler      ; IRQ135_Handler
                DCD   IRQ136_Handler      ; IRQ136_Handler
                DCD   IRQ137_Handler      ; IRQ137_Handler
                DCD   IRQ138_Handler      ; IRQ138_Handler
                DCD   IRQ139_Handler      ; IRQ139_Handler
                DCD   IRQ140_Handler      ; IRQ140_Handler
                DCD   IRQ141_Handler      ; IRQ141_Handler
                DCD   IRQ142_Handler      ; IRQ142_Handler
                DCD   IRQ143_Handler      ; IRQ143_Handler

__Vectors_End

__Vectors_SizeEQU   __Vectors_End - __Vectors

舒伯特玫瑰 发表于 2023-4-28 01:02

__Vectors为向量表起始地址,__Vectors_End为向量表结束地址,两个相减即可算出向量表大小。向量表从Flash的0地址开始放置,以4个字节为一个单位,地址0存放的是栈顶地址,0x04存放的是复位程序的地址,以此类推。从代码上看,向量表中存放的都是中断服务函数的函数名,可我们知道C语言中的函数名就是一个地址。DCD:分配一个或者多个以字为单位的内存,以4字节对齐,并要求初始化这些内存。在向量表中,DCD分配了一堆内存,并且以ESR的入口地址初始化它们。

舒伯特玫瑰 发表于 2023-4-28 01:02

4. 复位程序

AREA    |.text|, CODE, READONLY

舒伯特玫瑰 发表于 2023-4-28 01:02

定义一个名称为.text的代码段,只读。

舒伯特玫瑰 发表于 2023-4-28 01:02

Reset_Handler   PROC
                EXPORTReset_Handler            
                IMPORTSystemInit
                IMPORT__main
SET_SRAM3_WAIT
                LDR   R0, =0x40050804
                MOV   R1, #0x77
                STR   R1,

                LDR   R0, =0x4005080C
                MOV   R1, #0x77
                STR   R1,

                LDR   R0, =0x40050800
                MOV   R1, #0x1100
                STR   R1,

                LDR   R0, =0x40050804
                MOV   R1, #0x76
                STR   R1,

                LDR   R0, =0x4005080C
                MOV   R1, #0x76
                STR   R1,

                LDR   R0, =SystemInit
                BLX   R0
                LDR   R0, =__main
                BX      R0
                ENDP

舒伯特玫瑰 发表于 2023-4-28 01:03

复位子程序是系统上电后第一个执行的程序,调用System Init函数初始化系统时钟,然后调用C库函数_mian,最终调用main函数进入C语言世界。

舒伯特玫瑰 发表于 2023-4-28 01:03

WEAK:表示弱定义,如果外部文件优先定义了该标号,则首先引用该标号,如果外部文件没有声明,也不会出错。这里表示复位子程序可以由用户在其他文件中重新实现,这里并不是唯一的。IMPORT:表示该标号来自外部文件,与C语言中的EXTERN关键字类似。这里表示System Init和__main这两个函数均来自外部的文件。
页: [1] 2 3
查看完整版本: 小华半导体芯片启动文件详细讲解