zoukankan      html  css  js  c++  java
  • keil 启动代码at91sam9260

    ARM菜鸟成长记--之三
    from:http://hi.baidu.com/%BD%D9jie%B8%F6%C9%AB/blog/item/8e2137868d837622c75cc3cb.html

    起启动代码,我就嗷嗷郁闷,IAR下的程序都死在了这里,Keil中出现的问题很多都是通过对启动代码的修修补补才解决的,一句话:成也启动代码,败也启动代码。
    启动代码应该是刚接触ARM的新手必须面对而又很头痛的问题吧,刚开始我也很纳闷,为什么搞个这玩意,学51的时候咋就没见过呢。而且还都是汇编写的,俺的汇编还停留在“MOV”阶段,其他的不是很懂,没办法,谁让汇编的效率高呢。提到启动代码还不得不老生常谈一下其中要完成的任务:
    1、建立异常中断向量表,ARM从0X0开始给每个异常中断分配4个字节的空间,一般存放一个跳转指令(B)或PC的装载指令(LDR PC,X_Vector),当发生异常时,ARM从此处取得相应异常中断处理程序入口地址,再跳转执行;
    2、ARM都是高速处理器,而在高速下启动很可能会不稳定,所以在启动代码从慢时钟开始运行,在适当的位置,从32.768K切换到高速运行;
    3、ARM一般带有片外存储器,Flash、SDRAM等,这些存储器都需要初始化才能使用,这都是在启动代码中完成,但是Norflash的初始化要在时钟初始化之前;
    4、ARM有不同的模式,每种模式都需要相应的堆栈;
    5、Copy异常中断向量表到RAM,并实现REMAP,具体请参照上一节;
    6、Copy可执行映像的数据段到RAM,并将ZI区清零。这个一般都是由编译器完成的,IAR下是?main来实现,Keil中由__main实现。
    现在启动代码可以看懂一些,不过自己写启动代码还是很遥远的事情。如果开始对启动代码很抵触,可以考虑使用Keil,因为Keil由启动代码的图形化配置,直接点击鼠标操作就可以实现自己的启动代码。下面结合我们at91sam9260的板子,说说Keil中的启动代码。

    打开Keil生成的SAM9260.S,点击左下角的“Configuration Wizard”进入图形化配置向导,根据你的需要选择参数,全部选择完毕后,再点击"Text Editor",将会看到生成的启动代码。
    我靠,不是吧,将近2000行,开始你可能会很泄气,但仔细一看,前面不都是些宏定义嘛,跟图形化配置向导一一对应的,只有从1200多行的这一句开始的才是真正的启动代码部分。
    ;----------------------- CODE --------------------------------------------------

                    PRESERVE8
    开始是8个PC装载指令,注意第六个向量,即地址0X14处,存放可执行映像的大小,||Image$$ER_ROM1$$RO$$Length||+||Image$$RW_RAM1$$RW$$Length||

    接下来是SMC、PMC的初始化,我们的板子外扩了Norflash,如果在未初始化Norflash前,切换到快时钟,系统起不来,所以应该先初始化SMC,再初始化PMC,而Keil自带的启动代码中默认PMC在前,怎么办,可以将前面PMC的宏定义部分和初始化部分剪切,然后分别粘贴在SMC宏定义部分和初始化部分的后面,然后再看“Configuration Wizard”中,PMC自动放到了SMC的后面了。
    接下来是关闭看门狗(默认是打开的),拷贝异常中断表到RAM中,然后REMAP,建立缓存,建立各个模式的堆栈指针。
    最后进入__main进行数据段和代码段的拷贝以及初始化C语言库函数,然后跳转到main执行。

    Keil中有详细的注释,理解起来应该不是很难,具体的语句无需明白,知道个大致意思就行了。无非是将某个外设的基地址装载(LDR)到一个寄存器R0,将要向这个外设的某个寄存器赋的值装载到另一个寄存器R1,然后加载(STR)。一般的模式就是这样:
    LDR   R0,=Periphral_BASE     ;某外设的基地址
    LDR   R1,=0XFFFF0000         ;向寄存器要赋的值
    STR    R1,[R0,#Periphral_Register_OFS] ;向外设Peripheral基地址偏移OFS的寄存器Register赋值0xFFFF0000

    Keil的启动代码部分有两个注意的地方:
    1、启动代码中有很多IF语句,如:IF      :DEF:RAM_INTVEC。这就可以通过在Options/Asm对话框中的Define中填入RAM_INTVEC就可以实现中断向量从Flash到RAM的拷贝。同理,还有IF      :DEF:REMAP等等;
    2、带有Keil特色的MICROLIB,通过在Options/Target中选择“Used MICROLIB”,比不使用微库相比生成的代码较小。不过除此之外,应该还有其他的关系,因为我们的程序如果选择不使用微库的话,就执行不成功。对于微库只有这些很片面的理解,还请老手指教。

    总而言之,Keil中的启动代码还是比较好理解的,而且借助图形化配置向导,可以更快的上手,以实现自己的启动代码。

    下面要说说Keil下,怎样实现程序在片外Norflash运行、片外SRAM调试、片外SRAM运行。

  • 相关阅读:
    [Everyday Mathematics]20150226
    [Everyday Mathematics]20150225
    [Everyday Mathematics]20150224
    [Everyday Mathematics]20150223
    [Everyday Mathematics]20150222
    [Everyday Mathematics]20150221
    [Everyday Mathematics]20150220
    [Everyday Mathematics]20150219
    [Everyday Mathematics]20150218
    [Everyday Mathematic]20150217
  • 原文地址:https://www.cnblogs.com/xinjie/p/1546765.html
Copyright © 2011-2022 走看看