CM3启动汇编文件详解

S32DS中链接文件及启动代码学习 文件夹中有linker_flash.ld文件和linker_ram.ld文件。Linker File称为链接文件,它是作用在链接过程。程序代码(.s 和 .c)源文件会经过预编译、编译、汇编、链接最后生成目标可执行文件;linker_flash.ld文件功能:Flash和SRAM内存分配,为Flash构建目标分配代码段和数据段;linker_ram.ld文件功能:SRAM内存分配,为RAM构建目标分配代码段和数据段。linker_flash.ld文件分析: 文件夹中有以... 阅读详情

转载地址:http://www.360doc.com/content/18/0502/16/496343_750516698.shtml

一、启动文件解析

启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作:

  • 初始化堆栈指针SP=_initial_sp
  • 初始化PC指针=Reset_Handler
  • 初始化中断向量表
  • 配置系统时钟
  • 调用C库函数_main初始化用户堆栈,从而最终调用main函数去到C的世界

二、查找ARM汇编指令

在讲解启动代码的时候,会涉及到ARM的汇编指令和Cortex内核的指令,有关Cortex内核的指令我们可以参考《CM3权威指南CnR2》第四章:指令集。剩下的ARM的汇编指令我们可以在MDK->Help->Uvision Help中搜索到,以EQU为例,检索如下:

 

检索出来的结果会有很多,我们只需要看Assembler User Guide 这部分即可。下面列出了启动文件中使用到的ARM汇编指令,该列表的指令全部从ARM Development Tools这个帮助文档里面检索而来。其中编译器相关的指令WEAK和ALIGN为了方便也放在同一个表格了。

下表格是启动文件使用的ARM汇编指令汇总

指令名称

作用

EQU

给数字常量取一个符号名,相当于C语言中的define

AREA

汇编一个新的代码段或者数据段

SPACE

分配内存空间

PRESERVE8

当前文件堆栈需按照8字节对齐

EXPORT

声明一个标号具有全局属性,可被外部的文件使用

DCD

以字为单位分配内存,要求4字节对齐,并要求初始化这些内存

PROC

定义子程序,与ENDP成对使用,表示子程序结束

WEAK

弱定义,如果外部文件声明了一个标号,则优先使用外部文件定义的标号,如果外部文件没有定义也不出错。要注意的是:这个不是ARM的指令,是编译器的,这里放在一起只是为了方便。

IMPORT

声明标号来自外部文件,跟C语言中的EXTERN关键字类似

B

跳转到一个标号

ALIGN

编译器对指令或者数据的存放地址进行对齐,一般需要跟一个立即数,缺省表示4字节对齐。要注意的是:这个不是ARM的指令,是编译器的,这里放在一起只是为了方便。

END

到达文件的末尾,文件结束

IF,ELSE,ENDIF

汇编条件分支语句,跟C语言的if else类似

 

三、启动文件代码讲解

1.    Stack—栈

Stack_Size      EQU     0x00000400

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

开辟栈的大小为0X00000400(1KB),名字为STACK,NOINIT即不初始化,可读可写,8(2^3)字节对齐。

栈的作用是用于局部变量,函数调用,函数形参等的开销,栈的大小不能超过内部SRAM的大小。如果编写的程序比较大,定义的局部变量很多,那么就需要修改栈的大小。如果某一天,你写的程序出现了莫名奇怪的错误,并进入了硬fault的时候,这时你就要考虑下是不是栈不够大,溢出了。

EQU:宏定义的伪指令,相当于等于,类似与C中的define。

AREA:告诉汇编器汇编一个新的代码段或者数据段。STACK表示段名,这个可以任意命名;NOINIT表示不初始化;READWRITE表示可读可写,ALIGN=3,表示按照2^3对齐,即8字节对齐。

SPACE:用于分配一定大小的内存空间,单位为字节。这里指定大小等于Stack_Size。

标号__initial_sp紧挨着SPACE语句放置,表示栈的结束地址,即栈顶地址,栈是由高向低生长的。

2.    Heap堆

Heap_Size       EQU     0x00000200

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

开辟堆的大小为0X00000200(512字节),名字为HEAP,NOINIT即不初始化,可读可写,8(2^3)字节对齐。__heap_base表示对的起始地址,__heap_limit表示堆的结束地址。堆是由低向高生长的,跟栈的生长方向相反。

堆主要用来动态内存的分配,像malloc()函数申请的内存就在堆上面。这个在STM32里面用的比较少。

                PRESERVE8
                THUMB

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

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

3.    向量表

; Vector Table Mapped to Address 0 at Reset
                AREA    RESET, DATA, READONLY
                EXPORT  __Vectors
                EXPORT  __Vectors_End
                EXPORT  __Vectors_Size

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

EXPORT:声明一个标号可被外部的文件使用,使标号具有全局属性。如果是IAR编译器,则使用的是GLOBAL这个指令。

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

编号

优先级

优先级类型

名称

说明

地址

 

-

-

-

保留(实际存的是MSP地址)

0X0000 0000

 

-3

固定

Reset

复位

0X0000 0004

 

-2

固定

NMI

不可屏蔽中断。 RCC 时钟安全系统(CSS) 连接到 NMI 向量

0X0000 0008

 

-1

固定

HardFault

所有类型的错误

0X0000 000C

 

0

可编程

MemManage

存储器管理

0X0000 0010

 

1

可编程

BusFault

预取指失败,存储器访问失败

0X0000 0014

 

2

可编程

UsageFault

未定义的指令或非法状态

0X0000 0018

 

-

-

-

保留

0X0000 001C-

0X0000 002B

 

3

可编程

SVCall

通过 SWI 指令调用的系统服务

0X0000 002C

 

4

可编程

Debug Monitor

调试监控器

0X0000 0030

 

-

-

-

保留

0X0000 0034

 

5

可编程

PendSV

可挂起的系统服务

0X0000 0038

 

6

可编程

SysTick

系统嘀嗒定时器

0X0000 003C

0

7

可编程

-

窗口看门狗中断

0X0000 0040

1

8

可编程

PVD

连接EXTI 线的可编程电压检测中断

0X0000 0044

2

9

可编程

TAMP_STAMP

连接EXTI 线的入侵和时间戳中断

0X0000 0048

中间部分省略,详情请参考《STM32F4xx 中文参考手册》第十章-中断和事件-向量表部分

84

91

可编程

SPI4

SPI4全局中断

0X0000 0190

85

92

可编程

SPI5

SPI5全局中断

0X0000 0194

86

93

可编程

SPI6

SPI6全局中断

0X0000 0198

87

94

可编程

SAI1

SAI1全局中断

0X0000 019C

88

95

可编程

LTDC

LTDC全局中断

0X0000 01A0

89

96

可编程

LTDC_ER

LTDC_ER全局中断

0X0000 01A4

90

97

可编程

DMA2D

DMA2D全局中断

0X0000 01A8

 

 __Vectors  DCD   __initial_sp        ;栈顶地址
			
            DCD   Reset_Handler       ;复位程序地址
			
            DCD   NMI_Handler
				
            DCD   HardFault_Handler
				
            DCD   MemManage_Handler
				
            DCD   BusFault_Handler
				
            DCD   UsageFault_Handler
				
            DCD               0                    ; 0 表示保留
								
            DCD               0
				
            DCD               0
				
            DCD               0
				
            DCD   SVC_Handler
				
            DCD   DebugMon_Handler
				
            DCD               0
				
            DCD   PendSV_Handler
				
            DCD   SysTick_Handler
				
 
			
 
			
 ;外部中断开始
					
            DCD   WWDG_IRQHandler
				
            DCD   PVD_IRQHandler
				
            DCD   TAMP_STAMP_IRQHandler
				
 
			
 ;限于篇幅,中间代码省略
            DCD   LTDC_IRQHandler
				
            DCD   LTDC_ER_IRQHandler
				
            DCD   DMA2D_IRQHandler
				
 __Vectors_End
				
			
 __Vectors_Size EQU __Vectors_End - __Vectors

__Vectors为向量表起始地址,__Vectors_End 为向量表结束地址,两个相减即可算出向量表大小。

向量表从FLASH的0地址开始放置,以4个字节为一个单位,地址0存放的是栈顶地址,0X04存放的是复位程序的地址,以此类推。从代码上看,向量表中存放的都是中断服务函数的函数名,可我们知道C语言中的函数名就是一个地址。

DCD:分配一个或者多个以字为单位的内存,以四字节对齐,并要求初始化这些内存。在向量表中,DCD分配了一堆内存,并且以ESR的入口地址初始化它们。

4.    复位程序

 AREA    |.text|, CODE, READONLY
				
			
定义一个名称为.text的代码段,可读。

  Reset_Handler PROC
				
                EXPORT  Reset_Handler    [WEAK]
				
                IMPORT  SystemInit
				
                IMPORT  __main
				
  
			
                LDR R0, =SystemInit
				
                BLX R0
				
                LDR R0, =__main
				
                BX  R0
				
                ENDP
				

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

WEAK:表示弱定义,如果外部文件优先定义了该标号则首先引用该标号,如果外部文件没有声明也不会出错。这里表示复位子程序可以由用户在其他文件重新实现,这里并不是唯一的。

IMPORT:表示该标号来自外部文件,跟C语言中的EXTERN关键字类似。这里表示SystemInit和__main这两个函数均来自外部的文件。

SystemInit()是一个标准的库函数,在system_stm32f4xx.c这个库文件总定义。主要作用是配置系统时钟,这里调用这个函数之后,F429的系统时钟配被配置为180M。

__main是一个标准的C库函数,主要作用是初始化用户堆栈,最终调用main函数去到C的世界。这就是为什么我们写的程序都有一个main函数的原因。如果我们在这里不调用__main,那么程序最终就不会调用我们C文件里面的main,如果是调皮的用户就可以修改主函数的名称,然后在这里面IMPORT你写的主函数名称即可。

 Reset_Handler PROC
				
               EXPORT  Reset_Handler    [WEAK]
				
               IMPORT  SystemInit
				
               IMPORT  user_main
				
               LDR R0, =SystemInit
				
               BLX R0
			
               LDR R0, =user_main
				
               BX  R0
               ENDP

这个时候你在C文件里面写的主函数名称就不是main了,而是user_main了。

LDR、BLX、BX是CM4内核的指令,可在《CM3权威指南CnR2》第四章-指令集里面查询到,具体作用见下表:

指令名称

作用

LDR

从存储器中加载字到一个寄存器中

BL

跳转到由寄存器/标号给出的地址,并把跳转前的下条指令地址保存到LR

BLX

跳转到由寄存器给出的地址,并根据寄存器的LSE确定处理器的状态,还要把跳转前的下条指令地址保存到LR

BX

跳转到由寄存器/标号给出的地址,不用返回

 

5.    中断服务程序

在启动文件里面已经帮我们写好所有中断的中断服务函数,跟我们平时写的中断服务函数不一样的就是这些函数都是空的,真正的中断复服务程序需要我们在外部的C文件里面重新实现,这里只是提前占了一个位置而已。

如果我们在使用某个外设的时候,开启了某个中断,但是又忘记编写配套的中断服务程序或者函数名写错,那当中断来临的时,程序就会跳转到启动文件预先写好的空的中断服务程序中,并且在这个空函数中无线循环,即程序就死在这里。

 NMI_Handler     PROC    ;系统异常
			
                 EXPORT  NMI_Handler           [WEAK]
				
                 B       .
				
                 ENDP
				
 
			
 ;限于篇幅,中间代码省略
			
 SysTick_Handler PROC
				
                 EXPORT  SysTick_Handler       [WEAK]
				
                 B       .
				
                 ENDP
				
 
			
 Default_Handler PROC    ;外部中断
			
                 EXPORT  WWDG_IRQHandler       [WEAK]
				
                 EXPORT  PVD_IRQHandler        [WEAK]
				
                 EXPORT  TAMP_STAMP_IRQHandler [WEAK]
				
 
			
 ;限于篇幅,中间代码省略
			
 LTDC_IRQHandler
				
 LTDC_ER_IRQHandler
				
 DMA2D_IRQHandler
				
                 B       .
				
                 ENDP

B:跳转到一个标号。这里跳转到一个'.',即表示无线循环。

6.    用户堆栈初始化

 1 ALIGN	

ALIGN:对指令或者数据存放的地址进行对齐,后面会跟一个立即数。缺省表示4字节对齐。

;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************
                 IF      :DEF:__MICROLIB
                
                 EXPORT  __initial_sp
                 EXPORT  __heap_base
                 EXPORT  __heap_limit
                
                 ELSE
                
                 IMPORT  __use_two_region_memory
                 EXPORT  __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

                 ALIGN

                 ENDIF

                 END

判断是否定义了__MICROLIB ,如果定义了则赋予标号__initial_sp(栈顶地址)、__heap_base(堆起始地址)、__heap_limit(堆结束地址)全局属性,可供外部文件调用。如果没有定义(实际的情况就是我们没定义__MICROLIB)则使用默认的C库,然后初始化用户堆栈大小,这部分有C库函数__main来完成,当初始化完堆栈之后,就调用main函数去到C的世界。

IF,ELSE,ENDIF:汇编的条件分支语句,跟C语言的if ,else类似

END:文件结束

四、系统启动流程

下面这段话引用自《CM3权威指南CnR2》3.8—复位序列,CM4的复位序列跟CM3一样。

在离开复位状态后, CM3 做的第一件事就是读取下列两个 32 位整数的值:

1、从地址 0x0000,0000 处取出 MSP 的初始值。

2、从地址 0x0000,0004 处取出 PC 的初始值——这个值是复位向量, LSB 必须是 1。 然后从这个值所对应的地址处取指。

图 142 复位序列

请注意,这与传统的 ARM 架构不同——其实也和绝大多数的其它单片机不同。传统的 ARM 架构总是从 0 地址开始执行第一条指令。它们的 0 地址处总是一条跳转指令。在 CM3 中,在 0 地址处提供 MSP 的初始值,然后紧跟着就是向量表。向量表中的数值是 32 位的地址,而不是跳转指令。向量表的第一个条目指向复位后应执行的第一条指令,就是我们刚刚分析的Reset_Handler这个函数。

图 143 初始化MSP和PC的一个范例

因为 CM3 使用的是向下生长的满栈,所以 MSP 的初始值必须是堆栈内存的末地址加 1。举例来说,如果我们的堆栈区域在 0x20007C00-0x20007FFF 之间,那么 MSP 的初始值就必须是 0x20008000。

向量表跟随在 MSP 的初始值之后——也就是第 2 个表目。要注意因为 CM3 是在 Thumb 态下执行,所以向量表中的每个数值都必须把 LSB 置 1(也就是奇数)。正是因为这个原因,图 143中使用0x101 来表达地址 0x100。当 0x100 处的指令得到执行后,就正式开始了程序的执行(即去到C的世界)。在此之前初始化 MSP 是必需的,因为可能第 1 条指令还没来得及执行,就发生了 NMI 或是其它 fault。 MSP 初始化好后就已经为它们的服务例程准备好了堆栈。

4、stm32F103 启动文件 简介 启动文件名为“ startup_stm32f10x_hd.s”的文件,它里边使用汇编语言写好了基本程序,当STM32 芯片上电启动的时候,首先会执行这里的汇编程序,从而建立起 C 语言的运行环境,所以我们把这个文件称为启动文件。 startup_stm32f10x_hd.s 文件由官方提供,一般有需要也是在官方的基础上修改,不会自己完全重写。该文件从 ST 固件库里面找到,找到该文件后把启动... 阅读详情

相关推荐

13、启动文件详解

文章目录1、启动文件简介2、查找 ARM 汇编指令3、启动文件代码讲解3.1、Stack—栈3.2、Heap堆3.3、向量表3.4、复位程序3.5、中断服务程序3.6、用户堆栈初始化 1、启动文件简介 启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作: 初始化堆栈指针 SP=_initial_sp 初始化 PC 指针=Reset_Handler 初始化中断向量表 配置系统时钟 调用 C 库函数 _main 初始化用户堆栈,从而最终调用 main 函数去到 C 的世界 2、查找 AR

嵌入式羊圈 2175

CM3-读书笔记《Cortex-M3权威指南Cn》-1

目的: 通过中断向量表等相关描述,得出一个清晰的思路来撰写启动代码,以及bootloader+app双工程的配置问题 具体体现会在以后的demo工程中说明,这里作为参考资料  (时间紧凑,先摘录原文,回头会来写体会)   Cortex-M3  处理器内核  vs.  基于Cortex-M3的MCU Cortex ‐ M3处理器内核是单片机的中央处理单元(CPU )。完整的基于CM3

lhdzwkk4的专栏 1599

STM32-KEIL分散加载范例

以前看到IAR可以做 linux内核也可以做,一直以为是一个未解之谜,比如一个数组ARR[10]注意的话,你以后在每个模块.C.H用的时候用ARR[1] ARR[4]是不能在空白地方作为全局变量的 必须在函数内部 而 我们需要的是在空白地方做全局变量!分散加载就是这个技术!附件是我KEIL成功的!非常顺利,因为我从RTT源码里学习的

CM0+启动文件及ld文件分析

这是处理器在重置事件后首次开始执行时调用的代码。只执行绝对必要的设置,然后调用应用程序提供的main()例程。

qq_42475191的博客 1995

STM32内核CM3系列的MDK(keil)使用启动配置文件arm.zip.zip

MDK使用的ARM 启动配置文件 也可以自己去ST官网下载 或者在网上查找 这是固件库V3.5版本 STM32 内核CM3系列的

CM3权限及模式和堆栈的使用说明

CM3权限及模式和堆栈的使用说明,描述CM3的两种权限两种模式以及堆栈MSP和PSP的使用。

[转载]ARM Cortex-M0 启动过程分析

芯片上电或复位后,cpu首先从中断向量表中读出栈指针(MSP)和入口函数地址(复位向量,即程序执行的起始位置)。Bootloader是由芯片供应商预先编程,有时它位于片上Flash存储器并且与用户程序是分开的(这样用户更新程序也不会影响到Bootloader),而更多的时候它是位于和可编程程序存储器相互独立的ROM中。通常中断向量表会放在启动文件中,那么什么是启动文件呢?启动文件是使用汇编语言编写的,在堆栈建立之后才可以运行C代码,因为C函数调用需要把参数函数返回地址入栈,堆栈没有建立不能运行C代码。

qq_61918649的博客 381

C语言新手必练:10个实战小项目带你快速上手(附完整代码)

本文为C语言初学者精选10个实战项目,从基础的温度转换器到高级的迷宫求解算法,涵盖输入输出、条件判断、循环控制、数组操作等核心知识点。每个项目配有完整代码和详细解析,帮助新手通过实践掌握编程思维,特别适合刚学完语法但缺乏实战经验的学习者。

weixin_29208077的博客 736

《Cortex-CM3权威指南》——指令集

Cortex-CM3指令集

一世豁然的专栏 7356

qt使用qxlsx实现xlsx、xls表格文件快速写入和读取

新年第二篇文章,收尾一个去年计划中发表文章和实现功能。

kbq的博客 1万+

《生成式AI引发的“认知污染”:社交媒体虚假信息的治理困局》

认知污染与生成式AI“认知污染”指信息环境被大量虚假、误导性内容所充斥,干扰公众对事实的认知判断。在社交媒体时代,虚假信息的生产和传播门槛大幅降低,呈现出工业化、规模化的趋势。近年兴起的生成式人工智能(Generative AI)技术,如大型语言模型(LLM)和深度伪造(deepfake),更是加剧了这一问题。AI可以自动生成看似真实的文本、图像、音视频,将虚假信息批量生产并快速散播到社交平台上。

那谁的博客 5912

CM3学习-中断

(使用双堆栈的条件下,线程模式响应中断时,进入中断入栈时使用psp,然后在中断中使用msp,结束该中断时,切换到psp来出栈)现在使用PendSV来切换上下文,(将PendSV的优先级设置为最低),滴答定时器打断中断后上下文未发生变化,因此可以回到被打断的中断。悬起后,如果优先级不够高,则将缓期等待执行。相同的抢占优先级,不同的子优先级,不会发生抢占,只用于解除悬挂状态,当子优先级也一致时,判断中断源的编号。中断状态标志位在系统内部,用于标识运行,悬挂,完成状态,可以动态改变,可能会导致硬件层次的死循环。

红叶落水的博客 818

基于STM32L4XX、HAL库的MCP4561数字电位器驱动程序设计

/ HAL库需要左移一位。* @param address: 设备地址(0x2C-0x2F)* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hi2c: I2C句柄。

zhusl6688的博客 340

Cortex_M3之启动文件和MDK编译讲解

本小节总结一下CM3的启动文件和MDK编译相关的内容,启动文件是系统上电之后执行的第一个指令文件,是程序入口,C环境的运行是在此文件代码执行完成之后开始执行的。启动文件由汇编指令编写,本文主要是基于MDK平台介绍启动文件内容。由于STM32也是CM3的内核,所以启动文件内容取自STM32的官方文件。废话少说,干货开始。

weixin_40167339的博客 1415

Oracle EBS GL日记账批“选定以过账”状态数据修复

日记账来源:应收账款。用户操作过账以后,自动提交请求“过账:单一分类账”一直运行中,该请求执行5,6个小时甚至10多个小时无法完成,导致“标准管理器”阻塞大量请求待定,“冲突解决管理器”的待定数量不断增加。系统管理员不得不把该请求强制取消,此时,日记账批的状态处于“选定以过账”(GL_JE_BATCHES.STATUS为S),如下图 检查此日记账批有3千多条日记账题头,由于日记账比较多,日记账的科目余额计算需要大量服务器资源和执行时间比较长。

陈显平的专栏-Oracle EBS 3245

深度学习在地质勘探中的应用:使用Python构建卷积神经网络进行地震数据分析

在本文中,我们介绍了如何利用深度学习技术,特别是卷积神经网络(CNN),来处理和分析地震数据。我们使用了Python编程语言和TensorFlow框架构建了一个CNN模型,并使用地震数据进行了训练和评估。在本文中,我们将探讨如何利用深度学习技术,特别是卷积神经网络(CNN),来处理和分析地震数据。首先,我们需要获取地震数据集。通过本文的介绍,希望您能对深度学习在地质勘探领域的应用有更深入的了解,并能够应用这些技术来解决实际问题。在准备好地震数据和构建CNN模型后,我们需要将数据分为训练集和测试集。

斌擎科技 1471

关于ARM CM3的启动文件分析

关于ARM CM3的启动文件分析下面以ARM Cortex_M3裸核的启动代码为例,做一下简单的分析。首先,在启动文件中完成了三项工作:    1、  堆栈以及堆的初始化    2、  定位中断向量表    3、  调用Reset Handler。  在介绍之前,我们先了解一下ARM芯片启动文件中涉及到的一些汇编指令的用法。   补充一下,其中DCD相当于C语言当中的&,定义地址。 1、堆...

一颗中国芯的博客 2079

Spring AI Alibaba Agent开发实战:DeepResearch Agent调度系统

智能Agent调度系统通过专业化分工解决传统AI系统的三大痛点:通用模型专业性不足、处理效率低下和资源浪费。系统采用分层架构设计,核心组件包括智能调度器、Agent选择辅助器和集成工具类,实现问题分类、专业Agent匹配和搜索策略优化的全流程自动化。系统特点包括:1)配置驱动的灵活扩展;2)分层回退的容错机制;3)支持工具调用与传统搜索的智能切换。该架构通过策略模式和依赖注入等技术,在保证稳定性的同时显著提升了研究质量和效率,为企业级多Agent协作提供了完整解决方案。(149字)

wjianwei666的专栏 501

STM32--启动文件详解

启动文件由汇编编写,是系统上电复位后第一个执行的程序。

qq_57787567的博客 2017

CMake教程:C++ CMake自定义find_package并在其它项目使用

find_package 是 CMake 中一个非常重要的命令,用于在系统中找到外部库或包,并将其包含到项目中。: 要查找的包的名称。[version]: 可选的版本号。如果指定了版本号,CMake 会尝试找到该版本或更高版本的包。[REQUIRED]: 如果指定了这个关键字,找不到包时会产生一个错误并终止配置过程。: 指定要查找的包的组件。: 指定可选的组件,即使找不到这些组件,配置过程也会继续。: 指定查找包的模式,CONFIG表示查找配置文件,MODULE表示查找模块文件。

琅嬛福地 1561

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

STM32基础--启动文件详解

ALIGNALIGN:对指令或者数据存放的地址进行对齐,后面会跟一个立即数。缺省表示 4 字节对齐。ELSEBX LRALIGNENDIF首先判断是否定义了 __MICROLIB ,如果定义了这个宏则赋予标号 __initial_sp(栈顶地址)、__heap_base(堆起始地址)、__heap_limit(堆结束地址)全局属性,可供外部文件调用。有关这个宏我们在 KEIL 里面配置,具体见图使用微库。然后堆栈的初始化就由 C 库函数 _main 来完成。

weixin_48713132的博客 2368

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

startup_stm32f10x_hd.s启动文件详解;

启动文件中已经写好了所有的中断处理程序,但这些处理程序中都是空的,真正的中断处理程序需要我们在外部的C文件中重新实现。如果我们在使用某个外设的时候,开启了某个中断,但没编写配套的中断处理程序或中断处理程序的名字写错。那么当中断来临的时候,程序就会跳转到启动文件预先写好的中断处理程序中,并在这个空程序中无限循环。

weixin_61470035的博客 2975

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

启动文件详解

第14章     启动文件详解 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege   本章参考资料《STM32F4xx 中文参考手册》第十章-中断和事件:表 46. STM32F42xxx 和 STM32F43xxx 的向量表;MDK中的帮助手册—ARM Developm...

qq_28238141的博客 4963

第八章 启动文件详解

本章讲解了W55MH32的启动文件,其由汇编编写,系统上电后首执行,完成初始化堆栈、中断向量表、配置系统时钟等工作,还介绍了常用ARM汇编指令及代码结构。

WIZnet2012专栏 1032

再造STM32---第十二部分:启动文件详解

本章参考资料《STM32F4xx 中文参考手册》第十章-中断和事件:表 46.STM32F42xxx 和 STM32F43xxx 的向量表; MDK 中的帮助手册—ARM Development Tools:用来查询 ARM 的汇编指令和编译器相关的指令。 12.1 启动文件简介: 启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作: ...

sumjess 2744
上一篇: Keil启动文件详解
下一篇: 串口波特率计算方式
StudyTaoo
博客等级 码龄11年 128粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值