热度 28
2012-4-4 12:26
2104 次阅读|
0 个评论
作者,下家山 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关于中断的函数调用流程如下: 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中断的函数调用流程如下 到现在虽然中断句柄已经安装好了,但还没有做映射,系统怎么访问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中的映射表为 我改动后为 我开始以为映射属性的问题,但怎么换都不行,后来,发现问题出在映射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_Tacs13)+(B3_Tcos11)+(B3_Tacc8)+(B3_Tcoh6)+(B3_Tah4)+(B3_Tacp2)+(B3_PMC)); 不然,连cs8900 ID号都读不出来. 要成功编译需要花点时间。但这不是难点!只要细心,应该没有问题。 转载:请注明,作者,下家山 请尊重原创!