MPC8572调试记录

来源:互联网 发布:零件的加工方法与编程 编辑:程序博客网 时间:2024/05/22 12:00

2008-5-13

1、准备从bootrom开始调试,使用probe烧录。打开workbench3.0发现不支持MPC8572。打电话给OCD专家结果找不到人。

2、改一下思路,先不调试bootrom了,因为现在里面已经有了uBoot,会有一些地址信息从中能够查到,如果使用bootrom覆盖了,后面查地址必须看原理图了。现在准备从uBoot启动,然后加在vxWorks的image。

3、启动uBoot以后发现加载不了,找freescale的工程师Liu Yi [Yi.Liu@freescale.com]要了资料。后来发现里面不但烧了uBoot还烧了linux的bsp,在启动linux之前有一个10秒的间隙,如果不输入任何东西会自动启动linux的bsp。在10秒间隙内输入任何值,就是uBoot的状态了。

4、根据8572ADS板的target.ref文档找到了uBoot的使用方法。加载vxWorks的image。结果显示指令错,可能是config.h里面的地址不匹配。

5、串口和网口都没起来,没有调试手段,准备点灯。查看了原理图,8个GPIO都通过阻排接地了,阻排在cpu风扇的下面,想用示波器或万用表检测管脚都做不到。板子上有10几个灯,查了一些原理图,有3个是电源灯,8个是总线低8位的检测。没办法了,看来是点灯是没戏了。

6、只能寄希望于异常打印上了。

 

2008-5-14

1、把config.h看了一遍,把flash地址和DRAM的地址都修正了。还是起不来。

=> tftp 100000 vxWorks.bin

Speed: 10, half duplex

Using eTSEC1 device

TFTP from server 172.25.48.32; our IP address is 172.25.48.13

Filename 'vxWorks.bin'.

Load address: 0x100000

Loading: Got error 4

T #################################################################

         ###############################################

done

Bytes transferred = 1642720 (1910e0 hex)

=> go 0x00100000

## Starting application at 0x00100000 ...

NIP: 0012D20C XER: 00000000 LR: 0011BD78 REGS: 000ffec0 TRAP: 0700 DAR: 00000000

MSR: 00008000 EE: 1 PR: 0 FP: 0 ME: 0 IR/DR: 00

 

GPR00: 0011D8B0 000FFFB0 00000200 00000001 4C000064 00000010 002910F8 00000001

GPR08: 00000001 00000020 FFFFFFFF 00000007 0FF8DC00 A19272A0 0FFF4A00 20030000

GPR16: 00000000 00000000 00000000 00000000 00000000 000FFEB0 00000000 00000000

GPR24: 0FF90A40 00000000 00000000 00000002 00100000 0FF8DF7C 0FFF5598 000FFFB0

** Illegal Instruction **

Call backtrace:

DEADBEEF 0011D8B0 0FFC8B50

Program Check Exception

### ERROR ### Please RESET the board ###

增加了编译map的选项,查看map,0011D80地址是prjConfig.c文件中函数usrInit里面调用的第二个函数cacheLibInit。

2、可能是这句不对,注释掉后,重新跑,没有任何变化。

3、在cacheLibInit前面增加while(1)。如果是cacheLibInit出错,那么增加了while后,就应该停在前面,不会再报异常。测试结果是依然异常。

4、把while往前提一句,看一下是不是我的做法不对,根本就没跑进我的代码,结果把while加在usrInit的第一句时,系统不再报错,而是停住了。说明我的这种调试方法是可行的。

5、记得曾经遇到过不配置mmu就会出现不能调用函数的情况,估计这次也是这个原因,因为usrInit里面的第一个函数sysStart只是简单的赋值,不应该有其他可能。

6、在sysAlib.s里面增加了对flash段和内存段的映射。结果还是报异常:

=> go 0x100000

## Starting application at 0x00100000 ...

NIP: 00123CB8 XER: 00000000 LR: 0011D93C REGS: 000ffee0 TRAP: 0700 DAR: 00000000

MSR: 00008000 EE: 1 PR: 0 FP: 0 ME: 0 IR/DR: 00

 

GPR00: 0011D930 000FFFD0 002867A8 00000012 00000012 00000000 0000A9EC 00000001

GPR08: 00000000 00290000 00000020 000FFFD0 00198B24 002985A0 0FFF4A00 20030000

GPR16: 00000000 00000000 00000000 00000000 00000000 000FFED0 00000000 00000000

GPR24: 0FF90A40 00000000 00000000 00000002 00100000 0FF8DF7C 0FFF5598 000FFFD0

** Illegal Instruction **

Call backtrace:

0011D930 0FFC8B50

Program Check Exception

### ERROR ### Please RESET the board ###

不过这次有了点变化,上面红色的部分即R3和R4,值是18,这是cacheLibInit的两个输入参数。绿色的两处分别是R2和R13,在函数sysStart中,这两个寄存器分别保存了_SDA2_BASE_和_SDA_BASE_,查了一下map表,果然是这两个值。说明函数能够调用了,现在情况已经发生了变化,问题集中到了cacheLibInit上。

7、最直接的想法,注释掉这个函数,并且把cache改成disable。结果在调用下一个函数excVecInit的时候又非法指令了,函数调用还是有问题。

 

2008-5-15

1、每次在集成环境上先编译完vxWorks文件,再手工使用命令:objcopyppc -O binary --binary-without-bss vxWorks vxWorks.bin把vxWorks转换成vxWorks.bin太麻烦了。准备改一下集成环境的设置,直接编译出bin文件。不过一直没有找到地方,后来咨询了上海的同事,终于找到了地方:工程点右键选择properties->Build Properties->Build Macros->POST_BUILD_RULE,在后面增加$(EXTRACT_BIN) vxWorks vxWorks.bin可以直接编译出bin来。

2、由于调试没什么进展,准备换个思路,可能uBoot对后面的vxWorks有影响,不使用uBoot,直接把bootrom烧到flash里面去。使用升级后的workbench OCD可以连上,flash的读取也正常。查看了原理图,flash的型号是MX29LV640BT。Probe连接上以后自动选择的flash型号是S29GL01GP,明显不对,但列表里面没有MX29LV640BT,应该跟29LV640是兼容的,但我不知道板子上的是B还是T,这涉及到小扇区的分布。选了29LV640MB,能够使用,烧录没有显示异常。但是启动没有反映,单步跟踪,第一条执行是跳转到0xFFFFF000,跳过去后看到的不是二进制代码,而是一片0。感觉到这里面有不对的地方。按照MPC85XX的启动流程,第一条指令在0xFFFFFFFC。MPC85XX的运行是一定需要mmu支持的,初始状态的Mmu只映射了地址空间末尾的4K。所以第一条指令只能做一个4K内的跳转,也就是0xFFFFF000内的一个地址,在这里可以写一些简单的代码扩大mmu的映射空间,然后在从这里跳到其他地址去,vxWorks习惯于跳到0xFFF00100。但是现在明显没有按照流程来,反复烧了几次都是这个结果。

3、放弃了再烧bootrom的想法,准备把uBoot再烧回去,慢慢来吧。烧回去的时候发现最后一个block烧录过程中报错,复位、断电、多次烧录都同一个结果。查看前面的都正常,可能是flash小扇区的问题,极有可能是flash型号选错了。换成29LV640MT,烧录成功,每次换很麻烦,直接修改MPC8572的寄存器文件,使之一劳永逸,位置在\ocd\0127\RegisterFiles\PowerPC\85xx\Motorola\MPC8572E_WhiteFIN_Uboot_core0.reg,将:

TF CONF 133 00005000 65436 F8000000 'AMD   S29GL01GP (65536 x 16 )  1 Device ';

改为:

TF CONF 133 00005000 65436 FF800000 'AMD   29LV640MT (65536 x 16 )  1 Device ';

这里面我不理解为什么烧bootrom的时候没有报错,可能是我们的OCD在flash烧录校验方面的算法有问题,我看了一下uBoot和bootrom在最后一个block空间内的区别,uBoot只有最后4字节是有内容的(跳转指令),其他都是F,而bootrom是有数据,在烧录bootrom的时候大部分空间都是可写的,只有最后4个字节不同,uBoot的是0x4BFFF004,bootrom的是0x4BFFF804,有一位的差别,我查看了前面烧录的内容,bootrom烧完以后,最后4字节仍然是0x4BFFF004,所以才会出现跳转以后遇到的是0不是代码的情况。我怀疑我们的OCD在校验的时候对最后4位的校验有bug。

4、既然找到了bootrom走不下去的原因,就再继续把这条路走走看。烧录后,单步跟踪正常,程序按照预定跳转到了0xFFFFF800继续执行,设置完内存的片选以后有个循环等待,循环0x2000次,我使用run to here和设置断点都无效,只有单步跟踪有用。点了run,再也停不住了,飞了。

5、注释掉循环的地方,这里的循环无非是要等个时间,我单步的执行时间足够用了。单步跟踪发现在

useBuildOscFreq:

       cmpwi   r9, PIXIS_OSC_33_MHZ

       beq     useBuildOscFreq

之间存在循环。从表面看,应该是内存主频配置不对。

 

2008-5-16

1、内存的主频配置不对可能引发了昨天的内存初始化大循环,早上查看了资料,系统晶振是66M,所以不让代码去读0xF0000000的地址了,直接配置66M。发现仍然不行,代码运行到0xFFF00354的地方,这个地方在文件bootInit.c里面,对应的语句是退栈操作,把一个数据写入0x010000f0的地方。估计是内存不可写导致了错误。

 

2008-5-20

1、这几天一直在看MPC8572的文档,把rominit又过了一遍。E500与其他架构有些不同,E500支持36位地址,这种模式超出了软件的4G空间限制。为了让软件能够访问到所有的地址空间,E500提供了一个window的概念,所有的地址只有映射到window以后才能被访问,系统提供了12个window,每个window由一组两个寄存器配置(LAWBAR,LAWAR),一个负责起始地址,一个负责大小和属性,每个window的大小必须是2的整数次幂,最小可配置的大小为4K,所以起始地址的配置寄存器只有低24为有效。也有例外,CCSRBAR、SRAM和BootRom不需要window,这是为了启动上的方便。CCSRBAR是芯片的寄存器空间,共1M,所有片内的寄存器都集中在这里,缺省地址是0x0_FF70_0000。BootRom缺省可访问空间是4K,位置在低4G空间的末尾(0x0_FFFF_F000 到0x0_FFFF_FFFF),按照FreeScale提供的启动流程,第一条指令在低4G空间的最后4个字节(0x0_FFFF_FFFC),这里一般放一条跳转指令,跳到4K范围内的一个地址,在这段最大4K的代码里面初始化内存和mmu,执行完以后再跳转到Windriver传统的启动地址0xFFF00100。SRAM被L2SRBAR缺省映射。

自己总结了一下,如果要访问一个地址,需要片选(OR/BR)、MMU、Window同时映射才可以。

在Rominit.s里面需要访问的地址,包括CCSRBAR、Flash、SDRAM三种。

 

2008-5-21

1、在查看代码的时候发现一个问题,我们在代码中前面一部分配置的mmu表项都是TS0的,直到usrconfig以后才会有TS1的表项配置,但是TS0能够起作用是要依靠msr的一个特定位为0为前提的。如果这个位不为0,mmu如何配置都没用了。想到前面几天一直重复的一个内存无法访问的问题,感觉可能跟这里有点关系。我们缺省的代码里对msr也做了处理,不过比较简单:

       

        mfmsr   r3                     

        INT_MASK (r3, r4)              

        rlwinm  r4, r4, 0, 20, 18      

        mtmsr   r4                     

        isync

实际上是只清了中断位。

我对这个地方做了一下修改,把整个msr都初始化为0:

    mfmsr   r3                     

    li      r4, 0                  

    mtmsr   r4                     

    isync

测试一下,单步跟踪果然过了bootinit前面的压栈操作,说明内存可以访问了。

2、在前面的基础上go一下,停住,通过map表比较当前位置,还在bootinit里面,单步跟踪,发现在做一个拷贝操作。代码上是在对内存做填充0的操作。我感觉这个动作也没有多大的必要,就在rominit入口的地方修改了启动参数,把BOOT_COLD改为BOOT_NORMAL。这样就避免了内存清0操作,加快了启动速度。

3、再往下跑,发现跑飞了,并且串口仍然没有打印。通过点灯,查到原因在vxBus的初始化里面,由于此时的串口还没有打印,问题比较难查了。每次加点灯可以知道代码跑到哪一行,但是遇到循环就麻烦了,没办法用点灯来看变量和字符串,麻烦的很。个人感觉,在“复杂”的vxBus初始化之前,串口应该完成初始化,并且vxBus应该提供很方便的调试开关,而不是依靠重新编译vxBus的源码。