原创 rtems在s3c2410上的移植(二)

2012-4-4 12:26 2104 28 28 分类: 消费电子

作者,下家山

9.1需要改动的地方

       ①c/src/lib/libcpu/arm/s3c2410/include/s3c2400.h相应register的修改.

       ②因为要使用串口功能,所以需要在应用程序中添加端口初始化函数,来初始化各端口,主要初始化Port F,H,端口F为LED显示功能所用,端口H为串口打印功能所用.

           (可以直接复制s3c2410开发板套件资料的armsys_2410/hardware_test_pro中的Port_Init函数)

       ③在c/src/lib/libbsp/arm/gp32/startup/Bspstart.c,bsp_start_default函数中添加bank0-bank7的相关register的设置

       ④在start.S(见c/src/lib/libbsp/arm/gp32/start)中添加LED显示子程序.

   9.2需要确认的地方:

       ①在c/src/lib/libbsp/arm/gp32/console/Uart.c中对照s3c2410 datasheet确信各register地址是否正确.

       ②确信baudrate是否与PC机上的串口baudrate一致.

       ③Fclk,Pclk,Hclk的值为多少,相关函数参照c/src/lib/libcpu/arm/s3c2400/clock/Support.c c/src/lib/libbsp/arm/gp32/include/Bsp.h  c/src/lib/libbsp/arm/gp32/startup/Bspstart.c 知道baudrate,Fclk,Pclk,Hclk是怎么计算的,并对照s3c2410 datasheet确信计算结果是否准确.

    9.3调试方法

           LED跟踪(并借助ads)

            所以需要写一个LED显示程序,最好用汇编写,并在ads上验证该程序能正常调用.

10:调试hello world时碰到的问题

         我用LED一直跟踪到boot_card函数都很顺利,但到执行 BSP_RTEMS_Configuration = *Configuration.RTEMS_api_configuration;这条语句时程序跳飞。显然,这条跳飞的原因大半是指针造成的,Configuration.RTEMS_api_configuration是一个指针,使用指针的大忌是不初始化就使用,因为没有初始化,所指向的地址未知,因此程序跑飞.所以,我定义了一个rtems_api_configuration_table

    结构体,并把其地址赋给Configuration.RTEMS_api_configuration,果然BSP_RTEMS_Configuration = *Configuration.RTEMS_api_configuration;执行过去了.我开始接着往下调,但一个OS往往是牵一发而动全身,改动了Configuration.RTEMS_api_configuration,接下来很多地方都要改动,所以要找到根源.

          BSP_RTEMS_Configuration是Configuration的一个复制体,而Configuration是在confdefs.h中定义的,是一个已初始化的全局变量,所以我怀疑是不是全局变量初始化不成功?初始化的全局变量是放在.data区域的,而这一区域是定位在sdram中的.那么怎样才能看到这一区域的内容呢?最后想到了ads,我通过ftp把编译好的bin文件下载到板子后,再通过AXD调试软件查看sdram中的内容.这里,可以定义些一眼就能看出来的特征值,比如定义两个全局变量int a=0xaaaaaaaa;int b=0xbbbbbbbb;.但是,64M的sdram怎么查呢!用过ads的人应该知道,编译后的执行文件(.o)对每个函数,全局变量都已分配好了地址,这些地址在编译完成时在Section Cross References中会列出来.那么,在gcc中编译后怎么查看其中的函数,变量的地址呢?找相关资料,发现readelf就是干这个事的,所以readelf -a helloworld.exe >map得到map文件,用UltraEdit -32打开查看,记下全局变量a,b的地址(map中你还可以看到各函数的具体位置及占用空间的大小。要知道自己添加的文件是否编译进去,这是个很好的方法,我在编译network时,就如此).然后,在axd中定位到刚才记下的地址,发现AXD中a,b的地址与刚记下的地址(map)相差0x100偏移量.后面,我还做了大量的实验,比如定义结构体.都证明gcc编译后的全局变量的地址与AXD中查到的地址相差0x100,AXD查到的地址应该是sdram中的实际反映.因此我马上想到了linkcmds文件的.base段,其定义的就是sdram起始的0x100个字节,果然,当我把.base段去掉后原来跑飞的地方通过了.但去掉.base也不是办法,之后把它移到.bss段。但后来想来想去还是不妥,既然系统把它定义到前面一定不会错,我把它改动了,还不知有什么后患呢?那还有什么办法呢?后来突然想到,我通过uboot下载bin文件到sdram时,load地址是0x30000000,我把load地址改为0x30000100后,也一样解决了问题.

        在调试hello world例程时碰到的主要是这个问题.其他地方只要调试时细心应该不会有什么问题.

11:调试网络时碰到的问题

           在testsuites/samples中找到loopback例程,发现要用到clock驱动. 而专门测试clock的例程是testsuites/samples下的ticker.clock是通过中断来实现的,所以接下来要添加中断.

           首先,弄清楚RTEMS内核,中断的实现机制.rtems-4.6.99.3关于中断的函数调用流程如下: 

 
绘图302.jpg

rtems_exception_init_mngt安装六类异常向量地址到rtems_vector_table(在linkcmds中定义,实际地址为0x30000020)开始的地方,rtems_irq_mngt_init以实际的irq句柄初始化异常向量表,并以default_int_handler地址初始化32个rtems bsp

      irq中断向量地址.当发生irq中断时,系统跳到0x00000018地址执行,0x00000018地址处装载的就是rtems_irq_mngt_init安装的实际的irq句柄,通过这个句柄就可以找到相应的32个rtems bsp irq中断向量的哪个发生了中断,从而跳到对应isr服务程序执行.

           系统是怎么找到clock中断isr服务地址的,rtems-4.6.99.3关于clock中断的函数调用流程如下

 

 
 
绘图301.jpg

到现在虽然中断句柄已经安装好了,但还没有做映射,系统怎么访问0x00000018地址呢?

11.1   MMU

         记得,在start.S中我屏蔽了

         ldr     r0, =mem_map/*装载映射表*/

         bl      mmu_init   /*初始化mmu*/

         现在要打开

         程序的调试工作有回到了汇编阶段,所以,我又用LED跟踪.

         一直跟踪到函数mmu_init中的 mmu_set_ctrl函数

        前都没事,但调用这个函数时程序跑飞了.

        我开始怀疑是C内嵌汇编出了问题,所以我把mmu_set_ctrl换成了纯汇编程序放到了start.S中,同样跟踪到了我转换后的汇编函数中。但,就在执行使能mmu这条语句时飞掉了.把这条语句屏蔽了就没事.说明不是内嵌汇编的问题.那么在执行这条语句时,cpu到底做了些什么呢?要擦看汇编及pc指针最好的办法莫过于用ads了,用AXD调试程序运行到使能mmu这条语句时也跑飞了.做了改动的地方只有

      mem_map,gp32中的映射表为

 

绘图11.jpg

我改动后为

 

绘图12.jpg

我开始以为映射属性的问题,但怎么换都不行,后来,发现问题出在映射size上,64M的sdram只映射了9M,暂且不说,因为我程序加各堆栈再怎么样也不会超过9M,没有映射完64M也不会出什么问题.但是,Internals Regs如果没有映射完就有问题了,我对照s3c2410.h,发现,从48000000-4a000000,50000000-5a0000000而我只映射了16M也就是只映射了48000000-49000000,50000000-510000000,这么多register没有映射,当要访问没有映射的register时肯定会因找不到地址而跑飞.所以,映射所有的bank0-bank7

    mmu_sect_map_t mem_map[] = {

/*    */

    {0x30000000, 0x00000000,   1, MMU_CACHE_NONE},     /* SDRAM for vectors */

    {0x30000000, 0x30000000,   32, MMU_CACHE_WTHROUGH}, /* SDRAM W cache */

    {0x32000000, 0x32000000,   32, MMU_CACHE_NONE},     /* SDRAM W/O cache */

    {0x48000000, 0x48000000,   256, MMU_CACHE_NONE},    /* Internals Regs - */

    {0x50000000,  0x50000000,   256, MMU_CACHE_NONE},    /* Internal Regs - */

    {0x00000000, 0x00000000,   0,    0}                /* The end */

};

这样,运行ticker例程时,看到了正确结果.

11.2 照葫芦画瓢

     由于rtems-4.6.99.3源码自带的gp32-bsp中并没有网络驱动,所幸的是edp7312中有cs8900的驱动,因此可以copy edp7312目录下的整个network目录到c/src/lib/libbsp/arm/gp32下,并修改相关makefike文件,这里我把要注意的地方列出来:

     ①在configure rtems-4.6.99.3时去掉disable-networking disable-posix;

②对bank3 bus设置:

  /*==========Bank 3 parameter==========*/

#define B3_Tacs        0x0  /*0clk*/

#define B3_Tcos        0x3  /*0clk*/

#define B3_Tacc        0x7  /*14clk*/

#define B3_Tcoh        0x1  /*0clk*/

#define B3_Tah         0x0  /*0clk*/

#define B3_Tacp        0x3 

#define B3_PMC         0x0  /*normal*/

rBANKCON3= ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC));

不然,连cs8900 ID号都读不出来.

要成功编译需要花点时间。但这不是难点!只要细心,应该没有问题。

转载:请注明,作者,下家山   请尊重原创!

 

 

文章评论0条评论)

登录后参与讨论
我要评论
0
28
关闭 站长推荐上一条 /2 下一条