当前位置:网站首页 > 编程语言 > 正文

单片机程序的入口地址是?(单片机程序的入口地址是 H。)



一. 硬件环境工作

2.初始化(清零)ZI域。

3.初始化堆栈指针

而Cortex-M3内核规定,起始地址必须存放堆顶指针,而第二个地址则必须存放复位中断入口向量地址,这样在Cortex-M3内核复位后,会自动从起始地址的下一个32位空间取出复位中断入口向量,跳转执行复位中断服务程序。对比ARM7/ARM9内核,Cortex-M3内核则是固定了中断向量表的位置而起始地址是可变化的。即是对于flash启动来说(正常工作也是flash启动),0x地址存放的是栈顶地址__initial_sp,0x地址存放的是复位中断向量Reset_Handler入口地址(STM32使用32位总线,存储空间为4字节对齐);在编写多段程序时,偏移地址空间需注意,如编写一个BootLoader,从BootLoader到应用程序段的相互跳转。

https://mp.weixin..com/s/EuXIECgKUBM45c2-7dpscw

大学里第一开始接触到的单片机也许就是51单片机,但是有多少人还记得51单片机的启动流程。

MSC-51单片机的总结结构是冯诺依曼结构,指令和数据总线分开编址。传统的51单片机片内RAM:128字节,ROM:4K;两个16位的定时器;1个全双工的串口;8位CPU;32个I/O口(P0-P3),其中P0口是开漏输出,做输出脚时需要接上拉电阻10k。

上电的时候,cpu指向0000H的位置,一般在000H放置一条跳转指令,跳转指令调至main函数的入口,外部中断0的服务入口地址为0003H,定时器0中断服务入口地址为:000BH;外部中断1的服务入口地址为0013H,定时器1中断服务入口地址为:001BH;串口中断服务入口地址位0023H.定时器2中断入口地址位:002BH

下面是一个52的汇编程序,程序的开头是一个伪指令ORG,接着就一个跳转指令跳转到主程序的指令AJMP.然后就是中断服务函数的入口出口的定义.

 
  

 启动代码通常都烧写在flash中,它是系统一上电就执行的一段程序,它运行在任何用户c代码之前。上电后,arm处理器处于arm态,运行于管理模式,同时系统所有中断被禁止,pc到地址0处取指令执行。一个可执行映像文件必须有个入口点,而能放在rom起始处的映像文件的入口地址也必须设置为0。

 在汇编语言中,我们已经说过怎样定义一个程序的入口点,当工程中有多个入口点时,需要在连接器中使用-entry指出程序的入口点。如果用户创建的程序中,包含了main函数,则与c库初始化代码对应的也会有个入口点。

 总的来说,启动代码主要完成两方面的工作,一是初始化执行环境,例如中断向量表、堆栈、i/o等;二是初始化c库和用户应用程序。

在第一阶段,启动代码的人物可以描述为:

  • (1)建立中断向量表;
  • (2)初始化存储器;
  • (3)初始化堆栈寄存器;
  • (4)初始化i/o以及其他必要的设备;
  • (5)根据需要改变处理器的状态。

建立中断向量表

 初始化代码必须建立好中断向量表,以备应用程序后续使用。如果系统的地址0处是rom,则中断向量表直接是一些跳转指令就可以了,他们转到相应的中断处理函数执行。如果系统的0地址处不是rom,则中断向量表是通过动态的方式创建的,这主要是通过存储器映射的方式来实现:即上电后,rom中的地址被映射到地址0,它首先开始执行以便完成环境的初始化,最重要的它会将中断向量表拷贝到ram中,然后通过地址映射将ram地址映射为0,这样ram中的中断向量就可以使用了。

初始化存储系统

 对于有mmu的处理器,需要正确初始化mmu,没有的只需正确初始化存储控制器,为每个bank配置正确的参数就可以了。

初始化堆栈指针

 初始化代码必须初始化处理器各个模式下的堆栈指针,所有系统或用户程序会涉及的处理器模式对应的堆栈指针都应该初始化。通常未定义指令和预取指终止异常对应模式的堆栈指针不需要配置,除非用户需要使用它们作为调试使用。

初始化堆栈指针

 初始化代码必须初始化处理器各种模式下的堆栈指针,所有系统或用户程序会涉及的处理器模式对应的堆栈指针都应该被初始化。通常未定义指令和预取指终止异常对应模式的堆栈指针不需要配置,除非用户需要使用它们作为调试使用。

初始化i/o以及其他必要设备

 关键的输入输出模块必须在中断打开之前被配置,例如看门狗,否则它们会在系统启动后产生复位信号。

改变处理器状态和模式

 启动代码运行时,处理器状态认为管理模式,如果用户程序需要运行在用户模式,可以切换转入用户模式;所有处理器上电后是处于arm状态的,如果需要改变处理器状态,也可以在启动代码里切换到thumb态。

 在执行环境建立起来后,接下来就是应用程序的初始化,简单点就是讲用户程序加载到他们相应的运行地址,初始化数据区等,这个阶段完成后,才能进入用户最终的c代码区域。用户应用程序的初始化过程包括:将rw段的数据拷贝到他们的运行地址处,同时在rw段后面初始化相应大小的zi段数据,把他们初始化为0,使用了库函数的程序(工程中有main函数)是在库函数_main中自动完成这些工作的。

https://mp.weixin..com/s/a7wV78NZLS81TCKpMQiQiw

对于熟悉电脑的伙伴们来说,BIOS(那个蓝色的界面)可能不会太陌生吧,这货就是电脑的启动代码。没有BIOS的电脑,那注定是一块板砖!BIOS主要是做一些开机前的准备工作,例如系统时间设定、启动顺序。。。扯远了!

其实电脑本身就是从单片机而来,那么单片机也是有启动代码的,只是我们绝大部分情况不去关心它。

启动代码究竟都干了些什么工作,为何需要它?想想你在c语言中用到了什么东西,而这些东西却是拿来就可以用的?堆、栈!没错,就是他们。我们知道堆和栈是内存中划分出的一块区域,那为什么我们没有亲自划分呢,因为启动代码帮了你的忙!!!再想想单片机工作的时候,有哪些配置被我们忽略了,而它却可以用?时钟,就是这货,我们可以不配置时钟,而你发现它竟然有默认值!还是启动代码帮了你!

接下来仔细研究一下STM32的启动代码,首先要知道启动代码藏在哪里:一个叫做startup的汇编文件。启动代码是对硬件的一个最初级的配置,它必须用汇编语言来实现,汇编是真正的硬件编程语言。

从上到下解读启动代码:

startup_stm32f103xe.s

1、定义栈大小

 
  

2、定义堆大小

 
  

3、中断向量地址

 
  

ps:Cortex-M4内核要求内存的第一个地址是栈指针,第二个地址开始为中断向量。而中断向量的第一个必须是复位,因为代码是从上到下执行,开机首先遇到的就是复位。

4、复位中断处理函数

 
  

ps1:仔细那看有两个东西需要注意:“SystemInit”这个是时钟初始,“__main”这一句代表跳转到“main”函数。正因为复位这样的写法,所以程序都是从main函数开始执行的。

ps2:“SystemInit”具体实现过程在stm32fxxx.c,“__main”也是在某个地方与真正的main关联起来。

5、其他中断处理函数

 
  

ps1:绝大部分中断的实现系统没有给出,等待程序员去写。但是中断的名字我们都可以看到的,每一个名字都和上面向量表中对应着。我们知道函数名其实就是一个地址,而中断的入口地址是固定的,只要找对名字,那地址也就找对了。

ps2:中断的入口地址由内核和芯片决定,无法更改。因此不要改启动代码中的中断向量表

6、初始化堆、栈

 
  

ps:正因为堆和栈已经被初始化,所以你的C语言才可以顺利的执行。

启动代码是非常关键的,所有的CPU都有启动代码。这里完成了最基本的初始化功能,尤其是中断向量表,程序员每一个中断函数的名字都要与启动代码中的向量表对应,否则中断是无法进入的。

到此这篇单片机程序的入口地址是?(单片机程序的入口地址是 H。)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 打印控件怎么安装到电脑(打印控件怎么安装到电脑上)2026-05-16 19:54:08
  • yml文件怎么导入(yml文件导入失败)2026-05-16 19:54:08
  • 如何把回收站清空的文件找回来(如何将回收站清空的东西找回来)2026-05-16 19:54:08
  • github 国内访问(如何访问github上的项目)2026-05-16 19:54:08
  • pass平台厂商(pass平台是做什么的)2026-05-16 19:54:08
  • 爱普生c7000打印机(爱普生C7000打印机拆解)2026-05-16 19:54:08
  • 位置信息怎么改变自己的定位(如何改变定位位置信息)2026-05-16 19:54:08
  • 儿童多动症行为干预训练(儿童多动症行为干预训练有哪些)2026-05-16 19:54:08
  • 单片机程序的入口地址是,外部中断1的入口地址是(51单片机外部中断1的入口地址是什么?)2026-05-16 19:54:08
  • list转逗号分隔(list转字符串逗号隔开并加单引号)2026-05-16 19:54:08
  • 全屏图片