启动文件源码如下:

; Amount of memory (in bytes) allocated for Stack
; Tailor this value to your application needs
; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>;栈初始化
Stack_Size      EQU     0x00000400                          ;EQU定义栈空间的大小 1024字节,栈空间由编译器自动分配变量所占内存,该汇编语句等效于#define Stack_Size 0x00000400AREA    STACK, NOINIT, READWRITE, ALIGN=3     ;定义一个名为STACK的内存单元,它是可读写的,对齐方式为2^3=8字节对齐
Stack_Mem       SPACE   Stack_Size                          ;SPACE分配连续的栈存储空间,大小为0x00000400(1K),把首地址赋给Stack_Mem
__initial_sp                                                ;初始化堆栈指针,指向堆栈顶。; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>;堆初始化
Heap_Size       EQU     0x00000200                          ;EQU定义堆空间的大小,堆空间由人为手动分配变量所占内存,该汇编语句等效于#define Heap_Size 0x00000200AREA    HEAP, NOINIT, READWRITE, ALIGN=3   ;定义一个名为HEAP的内存单元,它是可读写的,对齐方式为2^3=8字节对齐
__heap_base                                                 ;堆起始地址
Heap_Mem        SPACE   Heap_Size                           ;SPACE分配连续的堆存储空间,大小为0x00000200(512Bytes),把首地址赋给Heap_Mem
__heap_limit                                                ;堆终止地址,与__heap_base配合限制堆的大小 PRESERVE8                                    ;告诉编译器以8字节对齐,命令指定当前文件保持栈的八字节对齐THUMB                                      ;告诉编译器使用THUMB指令集,THUMB 必须位于使用新语法的任何Thumb代码之前;定义复位段(中断向量表),并初始化;中断向量表定义
; Vector Table Mapped to Address 0 at Reset                 ;中断向量表默认从地址0开始,如果使用了向量表重定位,则从重定位地址开始。假设STM32从FLASH启动,则此中断向量表起始地址即为0x8000000。AREA    RESET, DATA, READONLY              ;定义一个名为RESET的数据段,它是只读类型的。EXPORT  __Vectors                           ;声明全局变量_Vectors,该标号可在其他文件中使用,表示中断向量表入口地址EXPORT  __Vectors_End                     ;向量表终止地址EXPORT  __Vectors_Size                      ;向量表空间大小__Vectors       DCD     __initial_sp               ; Top of Stack  Top of Stack 第一个表项是栈顶地址;该处物理地址值即为 __Vetors 标号所表示的值;该地址中存储__initial_sp所表示的地址值,
;大小为一个字(32bit) 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      总线错误中断,一般发生在数据访问异常,比如fsmc访问不当DCD     UsageFault_Handler         ; Usage Fault Handler     用法错误中断,一般是预取值,或者位置指令,数据处理等错误DCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     SVC_Handler                ; SVCall Handler        系统调用异常,主要是为了调用操作系统内核服务DCD     DebugMon_Handler           ; Debug Monitor Handler  调试监视异常DCD     0                          ; ReservedDCD     PendSV_Handler             ; PendSV Handler         挂起异常,此处可以用作RTOS的上下文切换异常,这是被推荐使用的,因为Cortex-M4会在异常发生时自动保存R0-R3,R12,R13(堆栈指针SP),R14(链接地址,也叫返回地址LR,在异常返回时使用),R15(程序计数器PC,为当前应用程序+4)和中断完成时自动恢复,我们只需保存R4-R11,大大减少了中断响应和上下文切换的时间。DCD     SysTick_Handler            ; SysTick Handler         滴答定时器,为操作系统内核时钟; External Interrupts                                         外部中断DCD     WWDG_IRQHandler            ; Window WatchdogDCD     PVD_IRQHandler             ; PVD through EXTI Line detectDCD     TAMPER_IRQHandler          ; TamperDCD     RTC_IRQHandler             ; RTCDCD     FLASH_IRQHandler           ; FlashDCD     RCC_IRQHandler             ; RCCDCD     EXTI0_IRQHandler           ; EXTI Line 0DCD     EXTI1_IRQHandler           ; EXTI Line 1DCD     EXTI2_IRQHandler           ; EXTI Line 2DCD     EXTI3_IRQHandler           ; EXTI Line 3DCD     EXTI4_IRQHandler           ; EXTI Line 4DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7DCD     ADC1_2_IRQHandler          ; ADC1 & ADC2DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TXDCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1DCD     CAN1_SCE_IRQHandler        ; CAN1 SCEDCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5DCD     TIM1_BRK_IRQHandler        ; TIM1 BreakDCD     TIM1_UP_IRQHandler         ; TIM1 UpdateDCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and CommutationDCD     TIM1_CC_IRQHandler         ; TIM1 Capture CompareDCD     TIM2_IRQHandler            ; TIM2DCD     TIM3_IRQHandler            ; TIM3DCD     TIM4_IRQHandler            ; TIM4DCD     I2C1_EV_IRQHandler         ; I2C1 EventDCD     I2C1_ER_IRQHandler         ; I2C1 ErrorDCD     I2C2_EV_IRQHandler         ; I2C2 EventDCD     I2C2_ER_IRQHandler         ; I2C2 ErrorDCD     SPI1_IRQHandler            ; SPI1DCD     SPI2_IRQHandler            ; SPI2DCD     USART1_IRQHandler          ; USART1DCD     USART2_IRQHandler          ; USART2DCD     USART3_IRQHandler          ; USART3DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10DCD     RTCAlarm_IRQHandler        ; RTC Alarm through EXTI LineDCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspendDCD     TIM8_BRK_IRQHandler        ; TIM8 BreakDCD     TIM8_UP_IRQHandler         ; TIM8 UpdateDCD     TIM8_TRG_COM_IRQHandler    ; TIM8 Trigger and CommutationDCD     TIM8_CC_IRQHandler         ; TIM8 Capture CompareDCD     ADC3_IRQHandler            ; ADC3DCD     FSMC_IRQHandler            ; FSMCDCD     SDIO_IRQHandler            ; SDIODCD     TIM5_IRQHandler            ; TIM5DCD     SPI3_IRQHandler            ; SPI3DCD     UART4_IRQHandler           ; UART4DCD     UART5_IRQHandler           ; UART5DCD     TIM6_IRQHandler            ; TIM6DCD     TIM7_IRQHandler            ; TIM7DCD     DMA2_Channel1_IRQHandler   ; DMA2 Channel1DCD     DMA2_Channel2_IRQHandler   ; DMA2 Channel2DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel3DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
__Vectors_End        ;向量表结束标志__Vectors_Size  EQU  __Vectors_End - __Vectors             ;得到向量表的大小 共76个中断向量,304个字节也就是0x130个字节;地址重映射及中断向量表的转移 AREA    |.text|, CODE, READONLY             ;定义一个代码段,可读,段名字是.text  段名若以数字开头,则该段名需用"|"括起来,如|1_test|。 |.text|  表示由 C 编译程序产生的代码段,或用于以某种方式与 C 库关联的代码段。         ;定义只读数据段,实际上是在CODE区,如果在FLASH区起动,则 中断向量起始地址为0X8000000;复位向量处理函数
; Reset handler
Reset_Handler   PROC                                        ;标记一个函数的开始;利用PROC、ENDP这一对伪指令把程序段分为若干个过程,使程序的结构加清晰EXPORT  Reset_Handler             [WEAK]    ;此处[WEAK]表示弱定义,优先执行其他文件的定义IMPORT  __main                             ;伪指令用于通知编译器要使用的标号在其他的源文件中定义IMPORT  SystemInitLDR     R0, =SystemInit                       ; 装载寄存器指令BLX     R0                                 ; 带链接的跳转,切换指令集。将处理器的工作状态由ARM状态切换到Thumb状态,该指令同时将PC的当前内容保存到寄存器R14中。因此,当子程序使用Thumb指令集,而调用者使用ARM指令集时,可以通过BLX指令实现子程序的调用和处理器工作状态的切换。同时,子程序的返回可以通过将寄存器R14值复制到PC中来完成。         LDR     R0, =__main                            ; 切换指令集,main函数不返回BX      R0                                 ;BX指令跳转到指令中所指定的目标地址,目标地址处的指令既可以是ARM指令,也可以是Thumb指令。ENDP;虚构的异常处理程序(可以修改的无限循环)
; Dummy Exception Handlers (infinite loops which can be modified)NMI_Handler     PROCEXPORT  NMI_Handler                [WEAK]B       .                                 ; 死循环ENDP
HardFault_Handler\PROCEXPORT  HardFault_Handler          [WEAK]B       .                                    ; 点“.”,它表示跳转到当前的指令地址处(即当前的 PC 值),也就是进入到当前的死循环中了。ENDP
MemManage_Handler\PROCEXPORT  MemManage_Handler          [WEAK]B       .ENDP
BusFault_Handler\PROCEXPORT  BusFault_Handler           [WEAK]B       .ENDP
UsageFault_Handler\PROCEXPORT  UsageFault_Handler         [WEAK]B       .ENDP
SVC_Handler     PROCEXPORT  SVC_Handler                [WEAK]B       .ENDP
DebugMon_Handler\PROCEXPORT  DebugMon_Handler           [WEAK]B       .ENDP
PendSV_Handler  PROCEXPORT  PendSV_Handler             [WEAK]B       .ENDP
SysTick_Handler PROCEXPORT  SysTick_Handler            [WEAK]B       .ENDPDefault_Handler PROC; 输出异常向量表标号,方便外部实现异常的具体功能 , [WEAK] 是弱定义的意思,如果外部定义了,优先执行外部定义,否则执行下面的函数定义EXPORT  WWDG_IRQHandler            [WEAK]EXPORT  PVD_IRQHandler             [WEAK]EXPORT  TAMPER_IRQHandler          [WEAK]EXPORT  RTC_IRQHandler             [WEAK]EXPORT  FLASH_IRQHandler           [WEAK]EXPORT  RCC_IRQHandler             [WEAK]EXPORT  EXTI0_IRQHandler           [WEAK]EXPORT  EXTI1_IRQHandler           [WEAK]EXPORT  EXTI2_IRQHandler           [WEAK]EXPORT  EXTI3_IRQHandler           [WEAK]EXPORT  EXTI4_IRQHandler           [WEAK]EXPORT  DMA1_Channel1_IRQHandler   [WEAK]EXPORT  DMA1_Channel2_IRQHandler   [WEAK]EXPORT  DMA1_Channel3_IRQHandler   [WEAK]EXPORT  DMA1_Channel4_IRQHandler   [WEAK]EXPORT  DMA1_Channel5_IRQHandler   [WEAK]EXPORT  DMA1_Channel6_IRQHandler   [WEAK]EXPORT  DMA1_Channel7_IRQHandler   [WEAK]EXPORT  ADC1_2_IRQHandler          [WEAK]EXPORT  USB_HP_CAN1_TX_IRQHandler  [WEAK]EXPORT  USB_LP_CAN1_RX0_IRQHandler [WEAK]EXPORT  CAN1_RX1_IRQHandler        [WEAK]EXPORT  CAN1_SCE_IRQHandler        [WEAK]EXPORT  EXTI9_5_IRQHandler         [WEAK]EXPORT  TIM1_BRK_IRQHandler        [WEAK]EXPORT  TIM1_UP_IRQHandler         [WEAK]EXPORT  TIM1_TRG_COM_IRQHandler    [WEAK]EXPORT  TIM1_CC_IRQHandler         [WEAK]EXPORT  TIM2_IRQHandler            [WEAK]EXPORT  TIM3_IRQHandler            [WEAK]EXPORT  TIM4_IRQHandler            [WEAK]EXPORT  I2C1_EV_IRQHandler         [WEAK]EXPORT  I2C1_ER_IRQHandler         [WEAK]EXPORT  I2C2_EV_IRQHandler         [WEAK]EXPORT  I2C2_ER_IRQHandler         [WEAK]EXPORT  SPI1_IRQHandler            [WEAK]EXPORT  SPI2_IRQHandler            [WEAK]EXPORT  USART1_IRQHandler          [WEAK]EXPORT  USART2_IRQHandler          [WEAK]EXPORT  USART3_IRQHandler          [WEAK]EXPORT  EXTI15_10_IRQHandler       [WEAK]EXPORT  RTCAlarm_IRQHandler        [WEAK]EXPORT  USBWakeUp_IRQHandler       [WEAK]EXPORT  TIM8_BRK_IRQHandler        [WEAK]EXPORT  TIM8_UP_IRQHandler         [WEAK]EXPORT  TIM8_TRG_COM_IRQHandler    [WEAK]EXPORT  TIM8_CC_IRQHandler         [WEAK]EXPORT  ADC3_IRQHandler            [WEAK]EXPORT  FSMC_IRQHandler            [WEAK]EXPORT  SDIO_IRQHandler            [WEAK]EXPORT  TIM5_IRQHandler            [WEAK]EXPORT  SPI3_IRQHandler            [WEAK]EXPORT  UART4_IRQHandler           [WEAK]EXPORT  UART5_IRQHandler           [WEAK]EXPORT  TIM6_IRQHandler            [WEAK]EXPORT  TIM7_IRQHandler            [WEAK]EXPORT  DMA2_Channel1_IRQHandler   [WEAK]EXPORT  DMA2_Channel2_IRQHandler   [WEAK]EXPORT  DMA2_Channel3_IRQHandler   [WEAK]EXPORT  DMA2_Channel4_5_IRQHandler [WEAK]
; 如下只是定义一个空函数,具体函数实现,需要用户在代码中实现。
WWDG_IRQHandler
PVD_IRQHandler
TAMPER_IRQHandler
RTC_IRQHandler
FLASH_IRQHandler
RCC_IRQHandler
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
DMA1_Channel1_IRQHandler
DMA1_Channel2_IRQHandler
DMA1_Channel3_IRQHandler
DMA1_Channel4_IRQHandler
DMA1_Channel5_IRQHandler
DMA1_Channel6_IRQHandler
DMA1_Channel7_IRQHandler
ADC1_2_IRQHandler
USB_HP_CAN1_TX_IRQHandler
USB_LP_CAN1_RX0_IRQHandler
CAN1_RX1_IRQHandler
CAN1_SCE_IRQHandler
EXTI9_5_IRQHandler
TIM1_BRK_IRQHandler
TIM1_UP_IRQHandler
TIM1_TRG_COM_IRQHandler
TIM1_CC_IRQHandler
TIM2_IRQHandler
TIM3_IRQHandler
TIM4_IRQHandler
I2C1_EV_IRQHandler
I2C1_ER_IRQHandler
I2C2_EV_IRQHandler
I2C2_ER_IRQHandler
SPI1_IRQHandler
SPI2_IRQHandler
USART1_IRQHandler
USART2_IRQHandler
USART3_IRQHandler
EXTI15_10_IRQHandler
RTCAlarm_IRQHandler
USBWakeUp_IRQHandler
TIM8_BRK_IRQHandler
TIM8_UP_IRQHandler
TIM8_TRG_COM_IRQHandler
TIM8_CC_IRQHandler
ADC3_IRQHandler
FSMC_IRQHandler
SDIO_IRQHandler
TIM5_IRQHandler
SPI3_IRQHandler
UART4_IRQHandler
UART5_IRQHandler
TIM6_IRQHandler
TIM7_IRQHandler
DMA2_Channel1_IRQHandler
DMA2_Channel2_IRQHandler
DMA2_Channel3_IRQHandler
DMA2_Channel4_5_IRQHandlerB       .ENDPALIGN                                        ; 默认是字对齐方式,也说明了代码是4字节对齐的     ;*******************************************************************************
; User Stack and Heap initialization      用户堆栈初始化
;*******************************************************************************IF      :DEF:__MICROLIB                     ;判断是否使用DEF:__MICROLIB(micro lib)在keil中选中 option--target--USE MicroLIBEXPORT  __initial_sp                     ;使用的话则将栈顶地址,堆始末地址赋予全局属性使外部程序可以使用EXPORT  __heap_base                      EXPORT  __heap_limitELSE                                        ;如果使用默认C库运行时IMPORT  __use_two_region_memory             ;定义全局标号__use_two_region_memoryEXPORT  __user_initial_stackheap          ;声明全局标号__user_initial_stackheap,这样外部程序也可调用此标号,进行堆栈和堆的赋值,在__main函数执行过程中调用__user_initial_stackheap                                   ;标号__user_initial_stackheap,表示用户堆栈初始化程序入口LDR     R0, =  Heap_Mem                    ;保存堆始地址LDR     R1, =(Stack_Mem + Stack_Size)      ;保存栈的大小LDR     R2, = (Heap_Mem +  Heap_Size)      ;保存堆的大小LDR     R3, = Stack_Mem                 ;保存栈顶指针BX      LR                                   ;LR连接寄存器,也就是R14,用于函数或者子程序调用返回地址的保存。 等同于 mov  pc,lr 即跳转到lr中存放的地址处ALIGN                                        ;设置对齐方式,在默认时,ELF(可执行连接文件)的代码段和数据段是按字对齐ENDIFEND;******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE*****

下面开始对关键代码逐行分析

栈初始化:

要理解这三行代码,首先要了解下这几条汇编指令的含义

1、EQU

EQU定义栈空间的大小,栈空间由编译器自动分配变量所占内存,该汇编语句等效于#define Stack_Size 0x00000400。也就是在此处首先定义了栈的空间大小为 0x400,也就是1024个字节。

2、AREA

所以第二行代码作用是 :定义一个名为STACK的的内存单元,它是可读写的,对齐方式为2^3=8字节对齐

3、SPACE

第三行代码的含义就是,将刚才定义的STACK内存空间,全部初始化为0.

4、最后一行代码 __initial_sp 含义是初始化堆栈指针,并指向栈顶。

堆初始化:

1、EQU定义堆空间的大小(512字节),堆空间由人为手动分配变量所占内存,该汇编语句等效于#define Heap_Size 0x00000200

2、定义一个名为HEAP的内存单元,它是可读写的,对齐方式为2^3=8字节对齐

3、设置堆起始地址

4、SPACE分配连续的堆存储空间,大小为0x00000200(512Bytes),把首地址赋给Heap_Mem

5、堆终止地址,与__heap_base配合限制堆的大小

6、告诉编译器以8字节对齐,命令指定当前文件保持栈的八字节对齐

7、告诉编译器下面代码开始使用THUMB指令集,THUMB 必须位于使用新语法的任何Thumb代码之前;定义复位段(中断向量表),并初始化。

中断向量表定义:

中断向量表默认从地址0开始,如果使用了向量表重定位,则从重定位地址开始。假设STM32从FLASH启动,则此中断向量表起始地址即为0x8000000。

1、定义一个名为RESET的数据段,它是只读类型的。

2、声明全局变量_Vectors,该标号可在其他文件中使用,表示中断向量表入口地址

3、向量表终止地址

4、向量表空间大小

中断向量表入口地址:

Top of Stack 第一个表项是栈顶地址;该处物理地址值即为 __Vetors 标号所表示的值;该地址中存储__initial_sp所表示的地址值。

依次给各个中断向量分配地址,分配后地址如下:

__Vectors_End 为向量表结束标志。

地址重映射及中断向量表的转移 :

定义一个代码段,可读,段名字是.text  段名若以数字开头,则该段名需用"|"括起来,如|1_test|。 |.text|  表示由 C 编译程序产生的代码段,或用于以某种方式与 C 库关联的代码段。定义只读数据段,实际上是在CODE区,如果在FLASH区起动,则 中断向量起始地址为0X8000000。

复位向量处理函数:

利用PROC、ENDP这一对伪指令把程序段分割,相当于C语言中的 {}作用。

利用EXPORT 声明全局变量Reset_Handler,此处[WEAK]表示弱定义,假如程序中定义了Reset_Handler函数,就会执行用户定义的Reset_Handler函数,如果用户没有定义Reset_Handler函数,就执行当前函数。弱定义的含义就是当两个函数名相同时,优先执行用户定义的函数。

这样是为了防止用户使能了中断而没有中断服务函数,从而造成程序崩溃。假设使能了中断,而用户又没有定义这个中断服务函数则会进入默认中断,默认中断为死循环。

利用IMPORT来声明main()函数和SystemInit()函数。

利用LDR命令,将函数SystemInit的地址加载到寄存器R0中。

通过BLX指令跳转到SystemInit()函数中。

接下来通过LDR指令装载main()函数地址。

通过BX指令,跳转到main()函数中。

虚构的异常处理程序:

输出异常向量表标号:

此处也使用了弱定义,如果外部定义了,优先执行外部定义,否则执行下面的函数定义。

实现弱定义函数:

实现各个中断函数,不过在这里中断函数都是空函数,没有具体实现,需要用户在代码中实现。

 用户堆栈初始化:

通过if和else来判断是否选择了微库

如果在keil中选择了USE MicroLIB 选项的话,就执行if语句,否则就执行else语句,使用默认的C库。

 IF      :DEF:__MICROLIB                     ;判断是否使用DEF:__MICROLIB(micro lib)在keil中选中 option--target--USE MicroLIBEXPORT  __initial_sp                     ;使用的话则将栈顶地址,堆始末地址赋予全局属性使外部程序可以使用EXPORT  __heap_base                      EXPORT  __heap_limitELSE                                        ;如果使用默认C库运行时IMPORT  __use_two_region_memory             ;定义全局标号__use_two_region_memoryEXPORT  __user_initial_stackheap          ;声明全局标号__user_initial_stackheap,这样外部程序也可调用此标号,进行堆栈和堆的赋值,在__main函数执行过程中调用__user_initial_stackheap                                   ;标号__user_initial_stackheap,表示用户堆栈初始化程序入口LDR     R0, =  Heap_Mem                    ;保存堆始地址LDR     R1, =(Stack_Mem + Stack_Size)      ;保存栈的大小LDR     R2, = (Heap_Mem +  Heap_Size)      ;保存堆的大小LDR     R3, = Stack_Mem                 ;保存栈顶指针BX      LR                                   ;LR连接寄存器,也就是R14,用于函数或者子程序调用返回地址的保存。 等同于 mov  pc,lr 即跳转到lr中存放的地址处ALIGN                                        ;设置对齐方式,在默认时,ELF(可执行连接文件)的代码段和数据段是按字对齐ENDIF

STM32单片机启动文件startup_stm32f10x_hd.s详解相关推荐

  1. 【Linux】U-Boot启动文件start.S详解(超详细讲解,上篇)

    U-Boot U-Boot的版本选择 U-Boot的下载地址:/pub/u-boot的索引 进入到U-Boot的下载页面,发现U-Boot的版本众多: 那怎么选取U-Boot的版本呢?够用就行. 本文 ...

  2. STM32单片机启动过程详解

    本文详细介绍STM32单片机启动的过程,既从上电Reset_Handle跳转到main()函数的过程.其中,会着重解释__main的汇编代码 STM32启动过程 1. 从Reset_Handler开始 ...

  3. STM32启动文件——startup_stm32f10x_hd.s

    STM32启动文件--startup_stm32f10x_hd.s 宗旨:技术的学习是有限的,分享的精神是无限的.   一.启动文件的作用  (关于启动代码的作用,前面已经提到过了,这里再啰嗦一下) ...

  4. STM32应用IAP进行程序更新详解及实例

      这是以前就想写的一个小专题关于IAP,以及IAP在STM32编程的应用,专题分三小节,主要介绍常见的单片机烧录方式,IAP的实际应用,以及Ymodem协议在IAP编程中应用,在笔记吃灰很久了,终于 ...

  5. [PXE] Linux(centos6)中PXE 服务器搭建,PXE安装、启动及PXE理论详解

    本篇blog主要讲述了[PXE] linux(centos)PXE无盘服务器搭建,安装,启动及pxe协议详解 , Kickstart (PXE+DHCP+TFTP+HTTP). PXE环境概述 作为中 ...

  6. Android init.rc文件解析过程详解(三)

    Android init.rc文件解析过程详解(三) 三.相关结构体 1.listnode listnode结构体用于建立双向链表,这种结构广泛用于kernel代码中, android源代码中定义了l ...

  7. Android init.rc文件解析过程详解(一)

        Android init.rc文件解析过程详解(一) 一.init.rc文件结构介绍 init.rc文件基本组成单位是section, section分为三种类型,分别由三个关键字(所谓关键字 ...

  8. oracle如何启动和停止服务,CentOS启动和停止服务详解

    CentOS启动和停止服务详解 服务简介 Linux 系统服务是在Linux启 动时自动加载, 服务的添加.删除.自动运行及状态 CAMS 在安装过程中会自动添加相关的服务,例如: service c ...

  9. 怎么打开python shell_Python之使用adb shell命令启动应用的方法详解

    一直有一个心愿希望可以用Python做安卓自动化功能测试,在一步步摸索中,之前是用monkeyrunner,但是发现对于控件ID的使用非常具有局限性,尤其是ID的内容不便于区分 具有重复性时,后面又发 ...

最新文章

  1. 用户利益何在:微软Windows10新政背后的疑问
  2. OpenGL之深入解析纹理的渲染使用
  3. 【VBS】一款无聊的 Visual Basic Script 表白程序
  4. 三台云服务器搭建hadoop集群
  5. 2017-2018-1 20155313 《信息安全系统设计基础》第五周学习总结
  6. 遇上浏览器跨域问题怎么办?
  7. 297 - Quadtrees
  8. html5模板区别,网页设计和平面设计理念的六大区别
  9. 君正X1500基于Minios的crash分析
  10. dnslog盲打学习
  11. 机器学习分析租房价格的影响因素
  12. PYTHON通过高德API实现城市地址与经纬度批量转换(每十个一组查询)
  13. 手机无线访问计算机文件夹,电脑怎么通过无线wifi读取手机文件
  14. 微信好友只有昵称没有微信号_只知道昵称怎么查他的微信号
  15. android第三方apk找不到/system/lib64/里面的系统库
  16. [UVM] include_coverage not located message
  17. arp协议分析python编程实现arp欺骗抓图片
  18. 无意中发现软件下载网站 softonic
  19. 【C语言练习4】根据公式计算π的值,π=4-4/3+4/5-4/7+4/9+... 打印出一个表格来显示,用公式中的1项、2项、3项...计算出来π的近似值
  20. 书法练字帖纸——井字格悄然而至

热门文章

  1. linux 的FAQ
  2. cisco的telnet终端显示debug调试信息
  3. BIM工程信息管理系统-详细设计
  4. HTTP性能测试工具wrk安装及使用
  5. Polygons HDU - 1632 (半平面交)
  6. 背景固定,内容滑动效果 - 仿QQ下载首页
  7. SQL.变量、运算符、if、while
  8. ffmpeg和opencv 播放视频文件和显示器
  9. 没有钱,能做什么呢?(转载)
  10. python访问共享文件夹_python – 通过linux机器打开Windows共享文件夹