搜索
bottom↓
回复: 70

调ARM9 NORFLASH启动的一些经验教训(菜鸟,轻拍)

[复制链接]

出0入0汤圆

发表于 2010-1-29 13:50:07 | 显示全部楼层 |阅读模式
从开始想弄norflash启动到现在,已经5个月了(当时丁老师还没走,心心念念这块工作,很抱歉当时不务正业,有负所托),从真正扎扎实实干到现在两个星期,刚才终于实现了norflash片外启动,心情那个激动呀,哈哈,原谅我这只笨笨的小菜鸟如此得意忘形吧。
记得刚开始做的时候那个一头雾水,整天上网铺天盖地得找大侠的调试经验,或者去论坛四处瞎问却也石沉大海,现在好不容易调好了,写个菜鸟笔记,纪念一下两周吐血的经历,更希望能给和艰难奋战的ARM入门级战友分享我的经验教训。
交代一下板子情况:
AT91SAM9263,内嵌Uc/OS II,编译软件IAR,仿真器及软件有两套:wigger+HJTAG,Jlink 6.0及配套软件。
1. 背景
关于norflash启动及remap,ARM菜鸟成长记中有一段描绘得很生动:
REMAP,顾名思义就是存储器的重新映射,即某些存储器的地址又发生了变化。我就很不理解了,这地址本来就不好记,还变来变去的,麻不麻烦呀,学51的时候咋就没这玩意呢?后来查了些资料,有些明白了,51是8位机,更重要的是51的主频不高,8位的ROM或Flash足够匹配51的主频,不用插入等待指令,所以程序直接在ROM或Flash中跑影响不到系统的速度。而ARM就不同了,ARM是32位机,但是Flash一般是8位或16位,32位的也有吧,好像价格很高。而且ARM的主频很高,动辄上百M,所以Flash的工艺达不到这个速度。如果程序跑在Flash中就要插入过多的等待指令,所以会影响ARM的性能。而RAM一般存取速度比较快,很容易构成32位,可以与高速的ARM匹配。更重要的是ARM上电后必须从0x0地址处取得指令,因此上电后必须将ROM或Flash映射位0X0地址处,当时还产生了一个RZ的想法,既然RAM这么好,为啥还要ROM或Flash,直接将程序下载到RAM中不就得了,后来才猛地想到RAM是易失型存储器,掉电后啥也没了,再上电后0X0处啥都没有。而且还有一条,ARM的中断向量表,既存放各个中断入口地址的地方,一般放在0x0处,即ROM或Flash中,为了加快中断响应速度,也应该将0X0映射到RAM中去。因此,ARM一般从ROM或Flash启动完成初始化,然后将应用程序拷贝到RAM,然后跳到RAM执行。

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2010-1-29 13:53:17 | 显示全部楼层
2. 步骤
2.1 配置icf文件
    icf是iar5.0版本以上的段配置文件,它定义了编译链接出来的程序里各个代码段、数据段以及中断向量表所分配的地址。以下配置说明摘自我师弟的调试笔记:
icf文件分为三个部分。
第一部分是各种符号的定义,即用各种符号常量代替地址和大小的具体数值,如“define symbol __ICFEDIT_region_ROM_start__   = 0x10000000;”即将0x10000000这个地址(即norflash基地址)定义为__ICFEDIT_region_ROM_start__,以下的部分就可以用这一符号代替norflash的地址了。
第二部分为区间定义,与第一部分是类似的,通过前面定义的符号定义一存储系列区间,如“define region STA_region = mem:[from __ICFEDIT_region_ROM_start__ size __ICFEDIT_size_startup__];”,这句话定义了一段存储区间STA_region,其范围为从__ICFEDIT_region_ROM_start__开始,大小为__ICFEDIT_size_startup__(这两个量都在第一部分中定义,这里分别表示norflash的基地址和bootloader代码的大小)。
第三部分为初始化方式及段分配规则,这是icf文件实际起作用的最重要的一部分,也是我们重点要修改的部分。在最后norflash启动所使用的flash.icf文件中,这一部分是这样的:
initialize by copy { readwrite };
initialize by copy { section .vectors };
initialize by copy { readonly };
do not initialize  { section .noinit };
place in STA_region { section .cstartup };
place in ROM_region {readonly};
place in VEC_region { section .vectors };
place in RAM_region { readwrite, block IRQ_STACK, block SVC_STACK, block CSTACK, block HEAP };
先看后四句,为段分配规则定义,它定义了最后生成的二进制代码中的程序段分布。如第一句表示了.cstartup段(即bootloader代码)放置在STA_region区域(这一区域是第二部定义的),第四句表示readwrite部分即各堆栈段放置在RAM_region即内存里。STA_region、ROM_region都定义在了norflash中,这样bootloader段、代码段都放置在了norflash的相应位置,同时中断向量表在board_cstartup_iar.s的首部,编译后也在bin文件的首部。这些是保证从norflash启动的第一步。
前四句为初始化方式定义,分别表示在初始化过程中复制readwrite部分、section.vectors部分、readonly部分,不要初始化section.noinit部分。这些名称应该都是IAR中类似关键字的词,代表了编译连接过程中程序的特定部分。其中readwrite指可读可写的部分,即数据段中的变量;section.vectors指中断向量表,这一句话将中断向量表复制到sram的起始处,保证了remap的正常进行;readonly指只读部分,包括代码段和数据段中的常量;section.noinit的具体内容还不清楚,可能指不需要马上初始化的部分。通过这部分的配置,实现了将数据、中断向量表即代码放到内存中的效果,这样便实现了从norflash启动并在sram中运行;如果不要initialize by copy { readonly }这一句,将不会复制代码段,程序会在norflash中运行。
事实上,icf文件不只是影响了生成的bin文件的结构(否则很难解释通过bin文件中程序段的某种变换就可以控制是否将代码复制到sram中去),它还会使IAR在编译过程中加入一些库函数以实现所需的操作,这一点会在bootloader部分中提到。
在IAR4.X版本里要配置的是xcl文件,xcl文档向icf的迁移参见《IAR EWARM使用指南 (转贴)- xcl文件》一文。

出0入0汤圆

 楼主| 发表于 2010-1-29 13:54:08 | 显示全部楼层
2.2 Bootload(启动代码board_cstartup_iar.s)
一般而言,一个ARM的bootload必须要完成以下部分的初始化:定义入口点、设置中断/异常向量、初始化存储系统(如果需要,进行代码的搬移)、初始化堆栈、初始化I/O设备、初始化中断中用到的变量、开中断、必要时改变处理器的模式和处理器的状态、初始化C程序中用到的存储区、引导处理器进入C程序。
事实上在IAR的例程中已经有了bootload的简单过程,完全可以满足单片机开发的要求,至于像uboot、at91bootstrap等专门的bootloader程序,可能是针对嵌入式开发、用于引导一个操作系统的,会更复杂一些。
例程中的bootloader(board_cstartup_iar.s)主要就是如下代码:
      SECTION .cstartup:CODE:NOROOT(2)
        PUBLIC  resetHandler
        EXTERN  LowLevelInit
        EXTERN  ?main
        REQUIRE resetVector
        ARM
//程序入口,上电后CPU检测到norflash起始处有合法中断向量表后从这里开始运行
resetHandler:
        /* Set pc to actual code location (i.e. not in remap zone) */
            LDR     pc, =label
        /* Perform low-level initialization of the chip using LowLevelInit() */
label:
//跳转到LowLevelInit()函数,进行底层初始化。
            LDR     r0, =LowLevelInit
        LDR     r4, =SFE(CSTACK)
        MOV     sp, r4
        MOV     lr, pc
        BX      r0
//初始化堆栈
        /* Set up the interrupt stack pointer. */
        MSR     cpsr_c, #ARM_MODE_IRQ | I_BIT | F_BIT      ; Change the mode
        LDR     sp, =SFE(IRQ_STACK)
        /* Set up the SVC stack pointer. */
        MSR     cpsr_c, #ARM_MODE_SVC | F_BIT           ; Change the mode
        LDR     sp, =SFE(CSTACK)
//bootload完成,跳转到主函数
        /* Branch to main() */
        LDR     r0, =?main
        MOV     lr, pc
        BX      r0
        /* Loop indefinitely when program is finished */
loop4:
        B       loop4
        END
这段汇编语言不用修改, 这里面的容易出问题的地方在LowLevelInit,而且启动代码基本不能用断点调试(仿真器容易出错,而且可能干扰程序执行),所以详细讲一下。
LowLevelInit主要实现底层初始化,包括:

出0入0汤圆

发表于 2010-1-29 13:55:07 | 显示全部楼层
嗯,其实先搞个U-BOOT上去,然后跑啥OS(不包括M$的)都很方便了。

出0入0汤圆

发表于 2010-1-29 14:08:28 | 显示全部楼层
写的很通俗易懂!顶一下

出0入0汤圆

 楼主| 发表于 2010-1-29 14:17:38 | 显示全部楼层
回复【3楼】rtems
-----------------------------------------------------------------------

哎,一只笨菜鸟,没办法,U-BOOT对所有板子都支持吗?

出0入0汤圆

发表于 2010-1-29 14:22:18 | 显示全部楼层
呵呵,UBOOT支持的板子不是一般的多,而且ATMEL自己也支持,我用了很多年了。

看看这里吧:
http://www.at91.com/linux4sam/bin/view/Linux4SAM/U-Boot

不过你这样好啊,ARM的启动部分搞清楚了,研究UBOOT就很轻松了。

出0入0汤圆

 楼主| 发表于 2010-1-29 14:23:14 | 显示全部楼层
2.2.1频率设置
如果我们用仿真器带SDRAM.MAC,会看到DEBUG窗口有“SET PLL 100MHZ” “SET SDRAM 100MHZ”,是的,AT91SAM9263正常运行的主频就是100MHZ。观察板子,ARM旁边有一个18.432MHz的有源晶体,通过PLL分频(div)和倍频(mul)把频率设到200MHZ,然后在切换主时钟时分频成100MHz,我设的是BOARD_MCK=((18432000 * 98 / 9) / 2)。
    /* Initialize main oscillator
     ****************************/
    AT91C_BASE_PMC->PMC_MOR = BOARD_OSCOUNT | AT91C_CKGR_MOSCEN;
    while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS));
    /* Initialize PLLA at 200MHz (198.656) */
    AT91C_BASE_PMC->PMC_PLLAR = BOARD_CKGR_PLLA
                                | BOARD_PLLACOUNT
                                | BOARD_MULA
                                | BOARD_DIVA;
    while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA));
    // Initialize PLLB for USB usage
    AT91C_BASE_PMC->PMC_PLLBR = BOARD_USBDIV
                                | BOARD_CKGR_PLLB
                                | BOARD_PLLBCOUNT
                                | BOARD_MULB
                                | BOARD_DIVB;
    while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKB));
    /* Wait for the master clock if it was already initialized */
    while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));
有一个问题要注意:在LowLevelInit()函数中不能在norflash配置前切换到快时钟,因为在norflash配置前,CPU是在一个较慢的时钟下按一个固有的时序访问norflash进而运行程序,一旦将时钟切换为快时钟,CPU的固有时序将失效,而norflash控制器又还未配置,CPU将无法对norflash进行访问,因而无法继续运行程序。那么在切换到快时钟之前配置好norflash呢?实验中似乎也不行,可能是由于配置好norflash后,CPU将试图按快时钟的频率去访问norflash,但此时的时钟仍为慢时钟,导致访问出错。这一问题最后的解决办法是在主函数中切换时钟、配置norflash控制器,这时程序都已拷贝到sram中,在sram中运行,就不存在上述的冲突了;但在norflash中运行时如何切换到快时钟还是一个问题。

出0入0汤圆

 楼主| 发表于 2010-1-29 14:31:01 | 显示全部楼层
2.2.3 Remap
本程序中是把启动代码从flash映射到了sram中,程序如下:
AT91C_BASE_MATRIX->MATRIX_MRCR |= (AT91C_MATRIX_RCA926I | AT91C_MATRIX_RCA926D);
具体参见datasheet的memory一章。
对于这个的理解,再次华丽丽地贴上我那可爱小师弟写的归纳,欢迎大家讨论指导:
很长一段时间内我对代码是如何从flash复制到ram中的心存疑虑,是设置好icf文件后CPU自己拷贝?还是要额外写一段汇编自己拷贝?抑或要用一段如at91bootstrap这样的单独一段程序启动系统并拷贝用户程序?最后发现关键就在“LDR     r0, =?main”这句话上,这段跳转到主函数的代码中,这句话是将主函数的地址赋给r0寄存器,以供之后传递给pc寄存器实现跳转。但我在sram中调试时发现,这句执行以后,r0的值并非main函数的地址,在反汇编窗口中查看相应地址,有如下代码段:
?main:
  10000208  E3A00001  MOV          R0, #0x1
  1000020C  EB000018  BL           Region$$Table$$Limit   
  10000210  E3500000  CMP          R0, #0x0
  10000214  1BFFFFE0  BLNE         __iar_data_init2   
实际上?main并不是用户主函数,而是IAR的一个库函数,这一函数中根据icf文件配置而嵌入了一些库函数,如上面的__iar_data_init2;在执行主函数前,ARM先执行这些函数,进行相应的准备工作,代码拷贝过程就是在这里完成的。通过查看附近的代码,发现这些库函数还包括__iar_rle_init2、__iar_zero_init2、__low_level_init、__iar_copy_init2等函数,由于在各种资料中都找不到关于?main和这些库函数的信息,无法准确得知各个函数的用途,但从其名字和实现代码不难看出,他们就是和拷贝代码、初始化内存数据等操作相关的函数。上面列出的是sram中调试时的?main函数,norflash启动的代码应该与其有所不同,还应包括代码拷贝的函数,事实上,?main里的内容可以在build后生成的.map文件里看到,在map文件的INIT TABLE部分列出了初始化要进行的操作,与?main中要调用那些函数是对应的。

基本上这样就可以实现启动了。当然如果你要把程序remap到SDRAM中去,应该先初始化SDRAM,但由于我和师弟的板子都是移到SRAM,所有把这部分初始化挪到MAIN中。

出0入0汤圆

发表于 2010-1-29 14:33:13 | 显示全部楼层
ding

出0入0汤圆

 楼主| 发表于 2010-1-29 15:12:33 | 显示全部楼层
回复【6楼】rtems
-----------------------------------------------------------------------
非常感谢,刚才去看了,很酷呀。

我现在其实也还没完全实现,之前是一个缩减版程序脱机成功了,现在想把整个大程序实现脱机,SRAM搁不下,得转移到SDRAM,遇到些问题,正在想办法了,U-BOOT能实现norflash向SDRAM的转移吗?

不包括M$的OS是什么意思呀?

出0入0汤圆

发表于 2010-1-29 15:26:08 | 显示全部楼层
UBOOT会做启动该做的一切,remap啊,初始化SDRAM,搬运自己到SDRAM啊等等,非常完善的东西。你自己玩的话研究一下当然好,如果做产品,直接用UBOOT,非常节省时间。你只需要把UBOOT跑起来,然后你的OS编译成elf或者bin格式的,下载到SDRAM直接执行就好了。什么flash操作啊,串口下载啊,网口下载啊,都是现成的。当然跑Linux更容易了。

很多玩Linux的人都管MS(Microsoft Soft)叫M$,$就是美元了,哈哈。我上面的意思其实是跑WINCE好像不行,我不清楚了,但是跑Linux,RTEMS,VxWorks啥的非常方便的。

出0入0汤圆

发表于 2010-1-29 18:39:58 | 显示全部楼层
牛,我当时就死在IAR的Norflash启动上,先记下,以后好好看看

出0入0汤圆

发表于 2010-1-29 20:46:26 | 显示全部楼层
曹老师好

出0入0汤圆

发表于 2010-2-2 15:21:22 | 显示全部楼层
remap的问题我也没想的太清楚。我在ads上明明可以跑起来的程序,修改启动代码中的RAM_BASE成RAM_BASE_BOOT,也能在flash中跑起来
可是修改了格式,用GDB调试就老是跑出错。

出0入0汤圆

发表于 2010-2-2 16:36:20 | 显示全部楼层
ding

出0入0汤圆

发表于 2010-2-2 20:49:55 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2010-2-11 11:00:39 | 显示全部楼层
回复【13楼】yyy000
-----------------------------------------------------------------------

恩?
莫非是杨老师

出0入0汤圆

 楼主| 发表于 2010-2-11 11:02:43 | 显示全部楼层
继续贴吧
上次回家得急,还有一部分没贴完

出0入0汤圆

 楼主| 发表于 2010-2-11 11:03:58 | 显示全部楼层
3. 其他
调的时候感觉千辛万苦,现在归纳下来,也不过数语。人总是走过坎坷回头,才会觉得虽一路泥泞却也风光旖旎。呵呵,不矫情了,继续写下一些注意事项吧。
(1)OS/UC II多任务机制和普通程序及中断的共存。虽然之前说把什么放在main 初始化里,其实不是的。这些普通的初始化和中断的设置开启一定要在任务中,这一点很重要。我的代码帖上:
void  main (void)
{
    BSP_IntDisAll();      
    OSInit();          /* Initialize "uC/OS-II, The Real-Time Kernel"     */         
OSTaskCreate(TaskStart,(void *)0,&TaskStartStk[TASK_START_STK_SIZE- 1],TASK_START_PRIO);      
  /*在OSStart 之前至少要建立一个任务*/   
    OSStart();       /* Start multitasking (i.e. give control to uC/OS-II)*/   
}
static  void  TaskStart (void *pdata)
{
    pdata=pdata;                       /* Prevent compiler warning                                 */         
    BSP_Init();              /* 初始化其实是在这里做的,中断的包括时钟节拍的  */                    
    ConfigureTc();               
   OSStatInit();         /* Start stats task                                         */
    TaskCreate();
    OSStart();
    while(1)    {      OSTimeDlyHMSM(0, 1, 0, 0);    }
}
添一段说明:
OSInit();是对系统的初始化
OSTaskCreate();创建系统中用户的任务,就是你的应用程序。
特别注意最好在使用OSTaskCreate()创建的第一个任务的最后初始化系统时钟节拍定时器,而不要在 OSStart()之前初始化,这样系统才不会因为处于未知状态而使用户应用程序崩溃。
  OSStart();之后,系统的任务开始执行,系统时钟节拍中断也开始执行。
在每个用户创建的任务之中需要调用OSTimeDly()在这个函数中又调用了任务级任务调度函数,完成任务调度。
在时钟节拍中断服务程序中又调用了中断级任务调度,完成中断级任务调度。
在调用OSStart( )之前必须先调用OSInit ( )。在用户程序中OSStart( )只能被调用一次。第二次调用OSStart( )将不进行任何操作。
OSStatInit()的调用时机是当多任务环境已经启动,且系统中只有一个任务在运行。
也就是说,该函数只能在第一个被建立并运行的任务中调用。


(2)很多时候自己对着电脑对着实验台,盲目的查资料,乱尝试,耽误了很多时间。回想起来,其实可以借鉴UcosII的多任务调度机制,以后不要这么钻死胡同,一次只做一样,效率真的很低,坐久了,脑袋就像浆糊一样。最后调出来,我觉得一方面是前面工作的积累,另一方面,是自己开始调整思路了,此路不通,赶紧想别的招儿。灵光一现有时候是在去洗手间的路上,楼道里微凉的风带给我冷静的气息,有时候是在半夜辗转反侧之时,有时是在清晨睡眼朦胧之时,离开板子,离开电脑,离开实验室,我觉得自己的思考力反而更强了,呵呵。
这只是一次小到不能再小的成功,其实即便是整块板子都调好了,即便是整套装置研发通过了,即便我的PAPER发表了,那又怎样呢?但正是跨过一个又一个小小的“坎”,给我继续前进的动力和信心。不管是 “西风凋碧树,望断天涯路”、“为伊消得人憔悴” ,还是最后的“那人却在灯火阑珊处”,经过一番努力最后沉淀下来的东西,可以让我们的内心更有力量,可以让我们更坚定地矗立在这方土地上。
最后,感谢这块板子的前期设计者杨老师,感谢我的师弟和我实验室温暖的大家庭。
愿上帝照亮我前行之路,也祝福大家新的一年科研工作顺利开,阿门!
                                                                                           Beaujolin   
                                                                                                          10.01.22

出0入0汤圆

发表于 2010-2-11 14:14:32 | 显示全部楼层
能写下来就不错,顶楼主一下

出0入0汤圆

发表于 2010-2-12 10:25:36 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-28 16:53:51 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-4-28 17:41:55 | 显示全部楼层
顶了

出0入0汤圆

发表于 2010-4-28 20:29:30 | 显示全部楼层
楼主好样的。

出0入0汤圆

发表于 2010-4-28 22:31:30 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-29 14:38:24 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-4-29 14:56:06 | 显示全部楼层
学习

出0入0汤圆

发表于 2010-5-7 07:57:49 | 显示全部楼层
多谢楼主,先做记号,我在调9261板子。打算裸奔,自己先琢磨下。

出0入0汤圆

发表于 2010-5-7 08:25:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-7 14:30:52 | 显示全部楼层
楼主还有所保留阿,没有讲全。希望楼主再现身说法。
比如。BMS,是否要先拉高,再拉低。
NORFLASH里面并不能执行跳转指令,不知道楼主的Lowlevel_init程序是怎么执行到的?
按我的思路应该是,
先搬运一部分的norflash程序到内嵌SRAM中。
在SRAM里面完成SDRAM初始化,搬运全部代码到SDRAM,再REMAP.

我还没有调出来。

出0入0汤圆

 楼主| 发表于 2010-5-12 11:49:33 | 显示全部楼层
回复【30楼】yulutong 土土狗
-----------------------------------------------------------------------
BMS先拉高,通过仿真器把程序下载后,再断电,置地,上电,启动。

你说的思路完全正确。

这个帖子是我实现第一步NORFLASH-SRAM后写的,之后上ATMEL官网下载了全套的例程,用了BOOTSTRAP文件包里的东西,实现了第二步。

发一下当时写的调试记录。

出0入0汤圆

 楼主| 发表于 2010-5-12 11:49:44 | 显示全部楼层
激动而又平静。
我的程序脱机启动终于全部实现了。
盼了好久,终于还是成功了。分两段下载到norflash,第一段boot.bin,第二段算是应用程序的bin,上电后先从norflash执行第一段,把应用程序搬到sdram,然后跳转到那儿执行。
这次有个很重要的经验教训:一定要看官方例程。之前在论坛泡了很久,也从大侠那儿学到一些东西,但水平不一样,我的问题或许在他们眼中都只是小菜一碟。和我一样左呼右求的小菜鸟们,得到的也都是只言片语的回复,碰到的问题还是要靠自己解决。后来在atmel官方求助了一下,他们的亚洲技术支持发给了我一个很全的文档,里面有at91bootstrap,很受用。这些在IAR5.20里面是没有的。后来去他们官网,发现在那儿也能下载,想想自己曾经还想尝试U-BOOT,又因为麻烦企图更改icf直接启动,呵呵,自己之前绕了一个多大的弯啊。不管怎样,都是一次很重要的经验教训。

现在把技术细节再多说一些吧:

有两个项目:getting-started 和 at91bootstrap。
at91bootstrap本来想直接用官方文档里的,更改了一些如PLL的参数,但不能脱机启动,后来在getting-started的基础上删除了各种功能以及UC-OS II 内核,实现了脱机启动。再在上面按官方的在main里添加了BOOT_NOR_CopyBin和GoToJumpAddress,这两个函数很关键,一个是把bin从norflash搬到sdram,另一个是跳转到那个地址去执行。虽然很关键,但应用起来很简单,毕竟是官方编好的东西,很方便使用,只要把库函数加好,能编译通过就能用。BOOT_NOR_CopyBin只要在boot.h设好sdram初始地址,norflash的偏移地址和代码大小就可以了。GoToJumpAddress就更简单了,在main最后直接调用就可以了。用的是flash.icf。
getting-started基本没变,就是把icf改成用sdram的,然后用j-flash把bin烧到0x10010000,留了一个地址偏移量。

出0入0汤圆

发表于 2010-5-12 11:54:44 | 显示全部楼层
多谢楼主分享调试心得,这些经验对新手的帮助极大。
下午根据你的思路试试。

出0入0汤圆

发表于 2010-5-12 13:47:18 | 显示全部楼层
楼主能否共享getting-started 和 at91bootstrap 工程。我在www.atmel.com,www.at91.com.都找不到。

出0入0汤圆

发表于 2010-5-18 12:38:09 | 显示全部楼层
搂在继续请教
我在Bootstrap-v1.15的crt0.gnu.s中看到
_lp_data:
        .word _etext
        .word _sdata
        .word _edata
这部分要被代码搬运时用到,那么在IAR中有什么什么样的标识?
而且我没发现在crto.gnu.s中REMAP过,怎么回事,现在我是吐血了。


IAR动不动就调用库函数,还不如ADS灵活。

出0入0汤圆

发表于 2010-5-18 13:04:47 | 显示全部楼层
记号

出0入0汤圆

发表于 2010-5-18 13:55:40 | 显示全部楼层
原来 at91bootstrap这个工程 IAR自带的。在我眼皮底下竟没有发现。
已经找到楼主提到的BOOT_NOR_CopyBin和GoToJumpAddress  2个函数了。 哈哈
我装的是IAR5.4

出0入0汤圆

发表于 2010-6-1 09:42:55 | 显示全部楼层
请教yulutong 土土狗
   我也是用norflash启动,keil ulink2编程环境,程序写不进flash,硬件没有发现问题,提示超时,楼主能否指点一下思路

出0入0汤圆

发表于 2010-6-1 10:04:37 | 显示全部楼层
正打算学习,领教了!!

出0入0汤圆

发表于 2010-6-7 17:47:39 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-16 06:36:44 | 显示全部楼层
ARM9 NORFLASH启动

出0入0汤圆

发表于 2010-6-16 10:04:37 | 显示全部楼层
mark!

出0入0汤圆

发表于 2010-6-30 09:35:19 | 显示全部楼层
标记

出0入0汤圆

发表于 2010-7-12 10:27:33 | 显示全部楼层
好文章!

出0入0汤圆

发表于 2010-7-17 16:11:25 | 显示全部楼层
回复【8楼】beaujolin  
2.2.3 remap
本程序中是把启动代码从flash映射到了sram中,程序如下:
at91c_base_matrix->matrix_mrcr |= (at91c_matrix_rca926i | at91c_matrix_rca926d);
具体参见datasheet的memory一章。
对于这个的理解,再次华丽丽地贴上我那可爱小师弟写的归纳,欢迎大家讨论指导:
很长一段时间内我对代码是如何从flash复制到ram中的心存疑虑,是设置好icf文件后cpu自己拷贝?还是要额外写一段汇编自己拷贝?抑或要用一段如at91bootstrap这样的单独一段程序启动系统并拷贝用户程序?最后发现关键就在“ldr     r0, =?main”这句话上,这段跳转到主函数的代码中,这句话是将主函数的地址赋给r0寄存器,以供之后传递给pc寄存器实现跳转。但我在sram中调试时发现,这句执行以后,......
-----------------------------------------------------------------------

__iar_rle_init2、__iar_zero_init2、__low_level_init、__iar_copy_init2等函数在iar的安装目录下都有源代码

出0入0汤圆

发表于 2010-8-5 16:05:07 | 显示全部楼层
回复【45楼】flyingxu
-----------------------------------------------------------------------

请问兄弟在那个目录下找到的?我用windows文件搜索都搜不到包含这些函数的文件。

出0入0汤圆

发表于 2010-11-22 21:39:28 | 显示全部楼层
mark!!!!1

出0入0汤圆

发表于 2010-11-22 23:15:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-6 15:17:29 | 显示全部楼层
不是菜鸟了!!牛!学习了!

出0入0汤圆

发表于 2011-1-7 22:19:32 | 显示全部楼层
很给力

出0入0汤圆

发表于 2011-1-7 22:55:31 | 显示全部楼层
收下!!

出0入0汤圆

发表于 2011-4-1 22:24:19 | 显示全部楼层
回复【32楼】beaujolin
激动而又平静。
我的程序脱机启动终于全部实现了。
盼了好久,终于还是成功了。分两段下载到norflash,第一段boot.bin,第二段算是应用程序的bin,上电后先从norflash执行第一段,把应用程序搬到sdram,然后跳转到那儿执行。
这次有个很重要的经验教训:一定要看官方例程。之前在论坛泡了很久,也从大侠那儿学到一些东西,但水平不一样,我的问题或许在他们眼中都只是小菜一碟。和我一样左呼右求的小菜鸟们,得到的也都是只言片语的回复,碰到的问题还是要靠自己解决。后来在atmel官方求助了一下,他们的亚洲技术支持发给了我一个很全的文档,里面有at91bootstrap,很受用。这些在iar5.20里面是没有的。后来去他们官网,发现在那儿也能下载,想想自己曾经还想尝试u-boot,又因为麻烦企图更改icf直接启动,呵呵,自己之前绕了一个多大的弯啊。不管怎样,都是一次很重要的经验教训。......
-----------------------------------------------------------------------
现在把技术细节再多说一些吧:

有两个项目:getting-started 和 at91bootstrap。
at91bootstrap本来想直接用官方文档里的,更改了一些如PLL的参数,但不能脱机启动,后来在getting-started的基础上删除了各种功能以及UC-OS II 内核,实现了脱机启动。再在上面按官方的在main里添加了BOOT_NOR_CopyBin和GoToJumpAddress,这两个函数很关键,一个是把bin从norflash搬到sdram,另一个是跳转到那个地址去执行。虽然很关键,但应用起来很简单,毕竟是官方编好的东西,很方便使用,只要把库函数加好,能编译通过就能用。BOOT_NOR_CopyBin只要在boot.h设好sdram初始地址,norflash的偏移地址和代码大小就可以了。GoToJumpAddress就更简单了,在main最后直接调用就可以了。用的是flash.icf。
getting-started基本没变,就是把icf改成用sdram的,然后用j-flash把bin烧到0x10010000,留了一个地址偏移量



求教楼主:
    用官方的at91bootstrap引导getting-started程序,程序跑飞(但用jlink在ram中调试getting-started程序是正常的)。
    如果删除了所有的中断以后at91bootstrap引导getting-started程序能正常运行。

出0入0汤圆

发表于 2011-4-2 09:38:47 | 显示全部楼层
问题解决了,还是icf文件问题

出0入0汤圆

发表于 2011-4-2 18:20:26 | 显示全部楼层
MARK,谢谢楼主~

出0入0汤圆

发表于 2011-5-18 10:51:40 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-5-18 11:30:55 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-19 10:54:01 | 显示全部楼层
写的很好,和我弄430f149的经历查不多啊

出0入0汤圆

发表于 2011-7-31 11:22:27 | 显示全部楼层
回复【6楼】rtems
-----------------------------------------------------------------------

U-boot是linux移植的时候用的,要移植uC/OS-ii不能用U-boot 吧

出0入0汤圆

发表于 2011-11-4 01:29:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-4 02:10:23 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-8 16:27:56 | 显示全部楼层
顶一下,顺便MARK一把

出0入0汤圆

发表于 2011-11-8 20:52:59 | 显示全部楼层
好详细啊,学习了,谢谢分享

出0入0汤圆

发表于 2011-11-17 22:40:11 | 显示全部楼层
回复【楼主位】beaujolin
-----------------------------------------------------------------------

学习了,谢谢分享!

出0入0汤圆

发表于 2011-11-24 10:52:11 | 显示全部楼层
调ARM9 NORFLASH启动的一些经验教训  强!!!!

出0入0汤圆

发表于 2012-5-15 08:41:45 | 显示全部楼层
支持楼主的经验原创  同样是菜鸟 受用了

出0入0汤圆

发表于 2012-10-28 21:42:17 | 显示全部楼层
关注                 

出0入0汤圆

发表于 2013-8-23 15:06:17 | 显示全部楼层
yulutong 发表于 2010-5-7 14:30
楼主还有所保留阿,没有讲全。希望楼主再现身说法。
比如。BMS,是否要先拉高,再拉低。
NORFLASH里面并不 ...

你好师兄,想请教你一个问题:我在你一个回复中看到你说的norflash中不能执行跳转指令,为什么呀?

出0入0汤圆

发表于 2013-8-29 14:05:48 | 显示全部楼层
学习进行时!

出0入0汤圆

发表于 2013-12-2 16:41:29 | 显示全部楼层
有人知道ATMEL 9260芯片 的ROMBOOT的代码吗?官方网站说不开放的,现在出现在高温时无法从NORFLASH启动的现象

出0入0汤圆

发表于 2014-11-18 12:40:39 | 显示全部楼层
学习中!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-23 21:46

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表