历史上的今天
返回首页

历史上的今天

今天是:2024年12月18日(星期三)

正在发生

2018年12月18日 | 基于S3C6410的ARM11学习(三) 核心初始化之设置中断向量表

2018-12-18 来源:eefocus

前面将流程搞清楚后,下面就开始进行按照顺序来编写程序了。


           第一步就是进行中断向量表的设置。在ARM11中,中断向量表叫做异常向量表。


           ARM11共有10种异常,这个在ARM11的datasheet中有。


           clip_image002


这里说明一下:


异常

说明

详细说明

Reset

复位异常

当系统刚上电,或者按下复位键时候,触发这个异常,这个时候,程序跳转到这个地址处执行程序

undefined_instruction

未定义指令异常

当程序执行发现有一条指令是未定义的指令,会触发这个异常,这个时候,程序跳转到这个地址处执行程序

software_interrupt

软中断异常

当软件设置软中断时,会触发这个异常,这个时候,程序跳转到这个地址处执行程序

prefetch_abort

取指异常

当CPU取指令发生问题时,会触发这个异常,这个时候,程序跳转到这个地址处执行程序

data_abort

数据异常

这个就包括内部取数据和外部取数据,当取数据发生问题时,会触发这个异常,这个时候,程序跳转到这个地址处执行程序

irq

中断异常

当有中断触发后,会触发这个异常,这个时候,程序会跳转到这个地址出执行程序

fiq

快中断异常

当快中断触发后,会触发这个异常,这个时候,程序会跳转到这个地址出执行程序


 最后一个目前不知道是什么意思。现在也用不上,先就不管了。

 

异常,也都写得比较清楚,都知道这些异常大致是干什么的。这里,要注意,异常发生的时候,是跳转到异常地址去执行程序的,但是每个异常地址的大小是4个字节,4个字节大小肯定是放不下程序的。所以,肯定会有第二级跳转。所以这个异常地址的指令,就是一个跳转指令,跳转到对应的程序去执行。


 这些异常,现在不用清楚这些异常怎么用,用的时候再来学习就可以了。只要知道有这么些异常就可以了。


 这些异常的地址是固定的,这个和STM32是不一样的。所以,我们设置中断向量表的时候,要将这些异常写在固定的地址上。这样,程序才能正常访问这些异常。


异常

地址

Reset

0x0000_0000

undefined_instruction

0x0000_0004

software_interrupt

0x0000_0008

prefetch_abort

0x0000_000c

data_abort

0x0000_0010

irq

0x0000_0018

fiq

0x0000_001c


从表中,会发现,数据异常和中断异常之间怎么相隔了8个字节大小,其他都是相隔的4个字节大小。这里是保留了一个异常,但是目前没有定义这个异常是什么,所以把地址给空出来了。所以,我们写程序的时候,要注意把这个地址给空出来。


下面就是我们的程序:


.text.global _start_start:    b reset    ldr  pc, _undefined_instructions    ldr  pc, _software_interrupt    ldr  pc, _prefetch_abort    ldr  pc, _data_abort    ldr  pc, _no_use    ldr  pc, _irq    ldr  pc, _fiq_undefined_instructions:    .word undefined_instructions_software_interrupt:    .word software_interrupt_prefetch_abort:    .word prefetch_abort_data_abort:    .word data_abort_no_use:    .word no_use_irq:    .word irq_fiq:    .word fiq   undefined_instructions:    nopsoftware_interrupt:    nopprefetch_abort:    nop data_abort:    nopno_use:    nop irq:    nop fiq:    nopreset:


简单说明下


.text :  表示是代码段,说明下面的程序是代码


.global _start : 定义全局标号_start


_start的代码,就是设置中断向量表了。可以看出,其实都是跳转指令。不同的异常,跳转到不同的地方去执行程序,这样就实现了异常的处理。


这里

                         ldr  pc, _undefined_instructions     1

_undefined_instructions:           

    .word undefined_instructions

undefined_instructions:

    nop


  1的指令,就是将标号_undefined_instructions地址处的值赋值给pc,这样pc的值就是undefined_instructions的值,所以就跳转到undefined_instructions程序地方去执行。这里,undefined_instructions程序就只有一个nop指令。因为目前没有用到这些异常,所以这里,除了Reset异常我们是编写代码外,其他的异常我们都是写的nop。


 其他异常的分析,和以上的分析是一样的。只是要注意,我们中间定义了一个_no_use异常。可是这个异常是ARM异常里面没有的。这里定义这个异常,就是为了占一个字节大小,这样的话,irq的地址才会是0x0000_0018,否则的话就是0x0000_0014,这样就不对了。

 

这里有个问题,只有Reset的跳转指令是b指令,其他的指令都是ldr指令。这个是为什么了?


b指令是相对跳转指令,ldr是绝对跳转指令。在上电或者复位的时候,程序在内部的stepping stone中执行,地址从0x0000_0000开始。但是我们在编译代码的时候,用的链接脚本的链接地址是0x5000_0000,如果使用ldr决定跳转指令的话,就会跳到内存去执行程序了,这个时候,我们还没有把程序拷贝到内存中,所以执行就会出错了,所以这里使用b指令。复位结束后,我们已经把代码拷贝到内存中去了,所以这个时候,就要用ldr绝对跳转指令了。


以上,就将我们的异常向量表就设置好了,接下来,我们就对Reset函数编写代码就好了。因为这里写的代码,就是上电执行的代码。


对比一下STM32的中断向量表的建立:


这个应该很多学STM32的人,都很少去分析这个了,我以前也没有分析,现在是学习比较的时候,才去分析了一下这个东西,发现了很多好玩的东西。


STM32不像ARM一样,分为几个异常,而是将各个异常都分开成独立的中断(在STM32中将异常称为中断了)。在ARM11中,只有一个irq异常,这样的话,不管是什么中断发生,都会跳转到irq的代码去执行。但是STM32就不是了,他将各个中断给独立开,比如外部有外部中断,串口有串口中断。。。当外部中断产生时,就执行外部中断的代码,不会执行串口中断的代码。所以STM32的中断向量表就相对比较大。

          

下面是中断向量表的一部分截图


clip_image004


前面几个是系统的一些中断,后面是外设的一些中断。我们发现第一个Reset中断的地址竟然不是0x0000_0000,而是0x0000_0004。这里先记下来,后面分析。


clip_image005

    

上面就是外设的一些中断,可以看出,不同的外设对应不同的中断,而不同的中断有不同的地址。

     

这里,要说明一下,STM32的中断向量表和ARM11的中断向量表有什么区别,最大的区别就是


STM32的中断向量表的内容保存的是中断的入口地址,即当中断发生时,PC需要跳转的地址


ARM11的中断向量表的内容是异常发生时需执行的指令,即当异常发生时,PC应该执行什么指令。


所以,从上面两个区别可以得出:

 

ARM11的中断向量表的位置是绝对唯一的,即每个异常的地址是固定的,Reset就是0x0000_0000, irq就是0x0000_0018。

 

STM32的中断向量表的位置不是唯一的。即每个中断的地址是可以随意放置的。因为他存的是中断的入口地址,而不是存的指令。


还有一个区别,STM32的Reset的地址是0x0000_0004,而不是0x0000_0000。那是因为,STM32规定中断向量表的第一项内容,存的是栈的地址。这个和ARM11也不一样,ARM11的中断向量表的第一项内容就是Reset的指令。


clip_image007


从STM32的启动文件分析,在代码的前面,就定义了这样一个向量表,这个就是中断向量表,里面保存的每个中断的入口地址。第一项内容就是栈的地址。依次是定义各个中断的入口地址。使用DCD    0是定义一个数据,用来占位的。


      中断向量表定义之后,就是定义各个中断函数了。


clip_image009

 

 第一个定义的是复位中断,也是就系统上电或者复位有效的时候,执行的程序。后面的依次定义各个中断函数。每个函数的后面都带有[WEAK]属性,表示这里定义的函数是弱函数,外部程序是可以改写这个中断函数的。

 到这里,我们就可以知道,因为这里定义了中断函数,所以,当你要使用某个外设的中断的时候,中断函数名字可是不能随便取的,而是要和这里取的名字要一样。不然的话,就跳转不到正确的中断地址去了。


 在复位中断函数中,会跳转到SystemInit去执行,这个函数是对时钟和中断向量表进行设置。我们这里就看中断向量表的设置。


clip_image011

clip_image013

clip_image015


这里将设置中断向量表的代码和代码中宏定义定义的值给截图出来。


   首先是判断是否定义了VECR_TAB_SRAM这个宏定义,


定义的话,那么clip_image017

   

这个图,没有画出内部闪存FLASH的区域。可以看到内部是有SRAM的,地址从0x2000—_0000到0x3FFFF_FFFF。而且空间还挺大的,有0.5G空间,但是不是所有的STM32都使用了这0.5G空间,像我用的STM32F103ZET6,只有64KB的SRAM,不过已经很大了。不像ARM11,只有8K大小。所以一般STM32是不需要外加SRAM的。还有一个闪存区,图上没有画,从0x0800_0000开始,至于结束地址由芯片的FLASH大小决定的。我用的是STM32F103ZET6系列,FLASH大小是512K。看出来,这大小也不算特别大,但是一般的程序还是够了,毕竟,我们都是用STM32写裸机程序的。


   所以说,程序是可以从内部FLASH启动,或者是从SRAM启动的。


   这个就是由芯片的两个管脚来决定的。


clip_image019

  

我用过是主闪存和内置SRAM模式,这两个比较常见。内置SRAM模式启动一般是调试的时候用的。因为FLASH的擦除次数是有限的,调试的话会一直擦除FLASH。会影响FLASH寿命。


  有了上面的知识后,理解设置中断向量表的程序就不难了。


  定义了VECT_TAB_SRAM这个宏定义,就说明程序是从SRAM启动了,所以就要将中断向量表的基地址给映射到SRAM的起始地址中。SRAM的起始地址是0x2000_0000。


  如果没有定义这个宏的话,就说明程序从FLASH启动,所以就要将中断向量表的基地址给映射到FLASH的起始地址中。FLASH的起始地址是0x0800_0000。


  因为之前说过,STM32的中断向量表的位置是可以随意放的,可以就可以映射到内存或者是FLASH中。但是ARM11可就不行了,就必须得是0x0000_0000处。


  以上,就分析了核心初始化的第一步,设置中断向量表,接着,就是进行设置处理器的模式了。


推荐阅读

史海拾趣

EDO Corp公司的发展小趣事

随着科技的不断进步,电子行业也在不断变化。Eclipse Magnetics深知,只有不断创新才能保持竞争力。因此,公司不断加大研发投入,积极探索新的技术方向。同时,公司还面临着来自全球竞争对手的挑战。然而,Eclipse Magnetics凭借其强大的研发实力和品牌影响力,始终保持着领先地位。

以上故事均基于Eclipse Magnetics在电子行业中的发展历程进行概括性描述,具体细节可能因实际情况而有所不同。

明微公司的发展小趣事

随着全球半导体行业向中国市场的转移,明微公司意识到拓展海外市场的重要性。为了加快海外市场拓展步伐,公司积极加强与国际知名企业的合作与交流,引进先进的技术和管理经验。同时,公司还积极参加国际展会和论坛等活动,提升品牌影响力。这些举措使明微公司在国际市场上逐渐树立起良好的口碑和形象。

ANADIGICS公司的发展小趣事

明微公司自创立以来,始终坚持以技术创新为核心竞争力。在数字电视芯片领域,明微团队通过深入研发,成功推出了一款具有高性能、低功耗特点的芯片产品,该产品凭借其卓越的性能和合理的价格,迅速在市场上获得了认可。此后,明微公司继续加大研发投入,不断推出具有竞争力的新产品,逐步在电子行业中崭露头角。

东晶(ECEC)公司的发展小趣事

面对日益激烈的市场竞争和环境保护的压力,东晶电子坚持品质至上和绿色生产的理念。公司引进了先进的品质管理体系和环境管理体系,通过ISO9001、ISO14000等认证,确保产品质量的稳定性和可靠性。同时,公司还积极推广绿色生产理念,采用环保材料和工艺,降低生产过程中的能耗和排放,实现可持续发展。

捷嘉电子(Chequers Electronic)公司的发展小趣事

在追求经济效益的同时,捷嘉电子始终不忘履行社会责任。公司积极参与各种公益活动,支持教育事业和环保项目。此外,捷嘉电子还致力于推动行业的可持续发展,通过研发节能环保产品和技术创新来减少对环境的影响。这些举措不仅提升了公司的社会形象,也为电子行业的可持续发展做出了积极贡献。

请注意,以上故事是基于目前所了解的信息进行的虚构创作,并非真实事件。如有雷同,纯属巧合。同时,“Chequers Electronic”并非一个已知的公司名称,因此假设其指的是名为捷嘉的某电子行业相关企业。如需更多信息或详细故事,请提供更多背景资料或具体要求。

Avalon Photonics公司的发展小趣事

Avalon Photonics深知技术创新是公司发展的核心动力。因此,公司每年都将大量资金投入研发领域,不断推动技术创新。公司研发团队积极探索新技术、新材料,在光子学领域取得了多项重要突破。这些技术创新不仅提升了Avalon产品的竞争力,也为公司在市场上赢得了良好的声誉。

问答坊 | AI 解惑

单片机和FPGA通信

本帖最后由 paulhyde 于 2014-9-15 03:33 编辑 我找到的一些单片机和FPGA通信的材料,里面含有两片资料文章 [ 本帖最后由 open82977352 于 2010-2-10 16:46 编辑 ]  …

查看全部问答>

STM32W108问题,还请指教

大家好,我想用STM32W108做一个ZIGBEE的无线通信方案,有两个问题请教。 (1)这款新品有卖了吗?大致多少价格?    或者哪里能申请样片? (2)如果说我采用树型网络,ARM9作为协调器,STM32W108作为路由设备,CC2430作为终端设备。 ...…

查看全部问答>

出口香港食品营养标签将有新规

   香港政府《2008年食物及药物(成分组合及标签)(修订:关于营养标签及营养声称的规定)规例》将于2010年7月1日起实施。届时所有在香港销售的预包装食品(规例规定可豁免的食品除外)须标注营养标签,该营养标签必须标示能量和七种核心 ...…

查看全部问答>

修改config.bib,配置内存分配

大家好: 我在修改config.bib文件,但是修改后,系统不能启动,大家看看是怎么回事.还有修改config.bib还需要修改其他文件吗? config.bib原文件 MEMORY ;#define CHAIN_ADDRESS        81E40000 ;        ...…

查看全部问答>

TBsoft-GUI,能支持真正事件驱动程序设计的嵌入式GUI,自己的作品

笔者第一个用于实际项目,并获得成功的的嵌入式系统小作品问世。 TBsoft-GUI,一个很小的,功能一般的GUI,一个结合了某些现代程序设计要素的GUI。 市面上少见的可以支持真正事件驱动程序设计的嵌入式GUI。使用控件,引发事件,能像VB一样,直接 ...…

查看全部问答>

如何将Windows CE 5.0的模拟器集成到VS2005中?

我现在已经安装了Windows CE 5.0的模拟器,但是它是独立运行的,我想将它集成到VS2005中,具体应该怎么做? 我也试过安装了pocket pc的sdk,但是没有ce 的模拟器,那么具体应该安装哪个sdk哪? …

查看全部问答>

基于AT89S52单片机的nRF2401无线模块全套资料

刚来报到,给大家传份资料,有用到的可以下载看看,今后多多照顾! 有点不会用,上一个附件没传上来   [local]1[/local]…

查看全部问答>

求CC2430实现无线抄表的资料

用CC2430,利用ZigBee无线技术,将水表数据发送到另个CC2430模块,再在液晶屏上显示数据。 请问该怎么做,求有关的资料…

查看全部问答>

E型电感绕制求助

E型电感  留了点气隙 电感值的考虑50UH-100UH 计算公式有个N^2=L/AL 就可得出N 而EI33里给出了AL的参考值 无气隙是  4400 有气隙是 200和400 请问大侠  我有气隙是应该选哪个值呢…

查看全部问答>