原创 ARM初学宝典

2010-6-15 11:17 2132 4 4 分类: MCU/ 嵌入式

ARM初学宝典


技术日志 2007-12-16 17:25:11 阅读838 评论4 字号:



首先声明:这是别人写的,作者是钟和平,我觉得说得比较好,我比较认同,转帖过来的。现在我虽然在使用ARM但,真正很多功能都没认真去研究过,只是使用了我需要的那部分 ,如果从学习的角度看,还是应该了解全面点



   一直都在听说ARM有多么好,有多神奇,有多难学。故学它时都兴奋加恐惧。呵呵,我刚好用ARM也有一段时间了。写点东西给ARM的初学者,希望能起到帮助作用。


1,记住:ARM很简单,就如从51转换到PIC或者转换到AVR一样简单。ARM的一个功能就如同掌握一个其他IC的使用一样,如时钟芯片,存在芯片,等等,甚至更简单。所以ARM的那些功能就可以忽略了。


2,和51系列相比,arm的寄存器不在存储空间之内,而且不分数据、程序空间。记住它的分配图.


3,ARM有多种处理器模式,每个模式都有自己的独立


   记住表格


   记住寄存器的使用


4,ARM的中断加强了,增加了软件中断,掌握swi


   可以把处理器模式及异常看成都是中断的扩张,从这些方面去理解也许快些。


   swi是嵌入式系统中任务切换的一个关键指令。故先有个心里准备。用法:swi 立即数。执行该执行时,程序会跑到swi中断处。立即数包含在该指令代码中,如果要根据立即数执行程序必须找出立即数。


5,ARM的启动程序及引导地址


   你编写的代码启动时:ARM都是从0x00000000开始运行。


   实际芯片运行时:ARM启动时,先根据硬件判断是否进入ISP还是经入程序运行。如进行程序运行,又会根据硬件判断会从0x00000000内部flash空间,还是外部flash空间0x80000000处运行(此时芯片会自动改变映射,也就是将0x80000000映射到0x00000000)


   在ADS软件上:ADS软件会把ARM Linker-Layout-Place at beginning of image-Objiect/symbol中指明开始代码的文件。


Section中指明代码开始的程序块。一般习惯Objiect/symbol中填写的时Startup.o。Section中填写Start。因为大家一般会将开始程序放在Startup文件中的Start段。


   ADS软件知道了我们程序的开始地方,还不知道这个程序的开始地方放到实际芯片的那个地址,所以我们还要为ADS软件指明开始地址,ARM Linker-Option-Image entry point中指明就行了。


   这样我们自己编写的代码、实际芯片、仿真器程序起始的关系就差不多明白了,然后记住下面中断向量表的代码。


6,地址重新映射


   这是个新概念,但记住它的功能是存储器映射用于改变从0x00000000开始的中断向量的映射。记住1:是0x00000000开始的中断向量的映射;记住2:为什么要这样做是为了不管你这段程序放在芯片实际的那个可以开始放的地方,ARM内部都可以从0x00000000开始运行。


7,汇编语言与c语言的混合编程


   如果你不会这个先最好了解一点概念


   汇编与c的参数传递是靠R0,R1这些寄存器传递的。


   函数的返回值也是靠R0。


   汇编中的标号与函数名相当


   c语言函数结束时实际上是汇编子程序的返回指令,故用汇编语言中用BL调用c的函数。否则就会返回出错。


8,汇编指令的记忆


   多了几种寻址方式


   先记住基本指令然后进行扩展,在记指令的执行条件,在搞懂特性符合的意义,如!,^等


我先是记住了以下几个指令:B,BX,BL,LDR,STR,LDM,STM,MOV,MRS,MSR,DCD,SWI,ADD,AND,CMP,MUL这些指令后,以后就边用边记。


9,ARM初始化要干些什么


   ARM初始化灵活方式,很多功能都可以方便设置。故开始初始化的事情也是蛮的多,主要做那些呢


   开始的中断向量表要做好吧。


   每个处理器模式都有自己的SP,你要指明每个SP的开始地址,进行堆栈的初始化。


   初始化外部总线控制


   设置存储器加速模块


   初始化时钟,初始化VIC等等,当然有很多你不必管,先拷贝


   在网上找资料就行了。中断向量表与初始化堆栈一般如下


;中断向量表


Reset


        LDR     PC, ResetAddr


        LDR     PC, UndefinedAddr


        LDR     PC, SWI_Addr


        LDR     PC, PrefetchAddr


        LDR     PC, DataAbortAddr


        DCD     0xb9205f80           ;ARM保留位,使向量表所有数据32位累加和为0,才能脱机运行。


        LDR     PC, [PC, #-0xff0]    ;


        LDR     PC, FIQ_Addr


ResetAddr           DCD     ResetInit


UndefinedAddr       DCD     Undefined


SWI_Addr            DCD     SoftwareInterrupt


PrefetchAddr        DCD     PrefetchAbort


DataAbortAddr       DCD     DataAbort


Nouse               DCD     0  ;


IRQ_Addr            DCD     0  ;


FIQ_Addr            DCD     FIQ_Handler


;未定义指令


Undefined


        B       Undefined


;软中断


SoftwareInterrupt


        B       SoftwareInterrupt


;取指令中止


PrefetchAbort


        B       PrefetchAbort


;取数据中止


DataAbort


        B       DataAbort


;快速中断


FIQ_Handler


        STMFD   SP!, {R0-R3, LR}


        BL      FIQ_Exception


        LDMFD   SP!, {R0-R3, LR}


        SUBS    PC,  LR,  #4


;初始化堆栈


InitStack   


        MOV     R0, LR


;设置管理模式堆栈


        MSR     CPSR_c, #0xd3


        LDR     SP, StackSvc


;设置中断模式堆栈


        MSR     CPSR_c, #0xd2


        LDR     SP, StackIrq


;设置快速中断模式堆栈


        MSR     CPSR_c, #0xd1


        LDR     SP, StackFiq


;设置中止模式堆栈


        MSR     CPSR_c, #0xd7


        LDR     SP, StackAbt


;设置未定义模式堆栈


        MSR     CPSR_c, #0xdb


        LDR     SP, StackUnd


;设置系统模式堆栈


        MSR     CPSR_c, #0xdf


        LDR     SP, =StackUsr


        MOV     PC, R0


StackSvc           DCD     SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4  ;


StackIrq           DCD     IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4


StackFiq           DCD     FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4


StackAbt           DCD     AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4


StackUnd           DCD     UndtStackSpace + (UND_STACK_LEGTH - 1)* 4


        AREA    MyStacks, DATA, NOINIT, ALIGN="2"


SvcStackSpace      SPACE   SVC_STACK_LEGTH * 4  ;管理模式堆栈空间


IrqStackSpace      SPACE   IRQ_STACK_LEGTH * 4  ;中断模式堆栈空间


FiqStackSpace      SPACE   FIQ_STACK_LEGTH * 4  ;快速中断模式堆栈空间


AbtStackSpace      SPACE   ABT_STACK_LEGTH * 4  ;中止义模式堆栈空间


UndtStackSpace     SPACE   UND_STACK_LEGTH * 4  ;未定义模式堆栈


10,边看书边实践,不断培养自己对ARM的兴趣,不断取得点成绩,别奢望一口吃成一个胖子,不断的给自己带来成功得快乐,我们都需要短期成绩的刺激才能长久的坚持。


11,做一个项目吧。否则永远也不能说你学会了。


12,本文给初学者指路用,背下本文,然后去看学习ARM的书籍,现在网上到处都有的ARM指令集,ARM的芯片资料,ARM应用系统开发详解,ADS-EasyJTAG,本篇宝典将是你学习ARM的加速器。

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
4
关闭 站长推荐上一条 /3 下一条