AM3517缓存与MMU的调试
需求:前段时间做过一款产品,要求高速和高精度,每秒钟数据采样与处理在两千次以上,初步做两种方案,一种是在Linux操作系统下,稳定性高,升级方便,但操作系统对主控芯片的开销会增大,担心不能满足要求;第二种:是前后台模式。
简析:一直很信赖TI的产品,经再三考虑选了AM3505这款芯片,主频600M,理论推算可以满足要求,因为暂时没有界面处理,所以选了一个不带图形加速器的,但在样片申请时AM3505暂时没有,就给了AM3517,很感谢TI的样片申请业务。
系统:主控芯片AM3517,内存:美光DDR2 MT47H64M16HR-25,Flash:三星K9K8G08U0A,电源芯片:tps65910,网卡:IP101A,另外预留了HDMI和CAN接口,芯片型号:TFP410PAP和ISO1050等。
应用开始:
第一步,焼写启动代码,从ti技术支持得到的开发包,TI的启动代码包含了两部分一个是X-loader TI自己做到,另一个是linux通用引导U-boot。用ti的flash tool烧写工具,用之前需要根据自己的硬件类型做一些配置,如NandFlash是几位的,最大容量,块大小,页大小等,对相应的只修改一下。其他还有一些配置,由于个人没有用过就不再多说,有问题时建议多看Help文件,Ti论坛也有很多相关资料。
接下来是将x-loader和U-boot合并到一起。X-loader存在的原因可能是,U-boot内容过多,芯片内部Ram有限(64K),所以就做了一级缓冲,先运行x-loader对硬件环境一个简单的初始化,然后将u-boot拷贝到内存中,再将控制权交给U-boot。
对编译后的X-loader做了一下分析,发现x-loader头部是一个固定的内容,就是X-loader的大小,合并方法是将U-boot的对硬件必要的初始化和添加搬运自己代码到内存中的这段程序压缩到64K以内,等Uboot把自己搬运完了就跳到内存中从新运行U-boot,在U-boot中要判断自己是在内存中还是在Flash中,这个可以通过地址来判断,在Flash中就运行拷贝自己的程序,在内存中就跳过。这个很简单,都是U-boot内部函数的一些拷贝。
第二步:网卡移植,IP101A非常好用,我们用的是RMII精简接口,需要给AM3517的网络部分提供一个50M的时钟,IP101A内部可以产生这个时钟,其他都用默认配置即可。在U-boot里添加以下IP101A的PHY地址做个判断就可以。
第三步:一键更新,使用u-boot通过网络自己更新自己、内核、文件系统会很方便,而且速度很快,只是指令多了点。这里就是把u-boot的tftp下载命令,擦出nand flash命令和写命令综合到一起,其他也没什么,值得说的就是,烧写u-boot时用的是硬件1bit Ecc校验,这个是am3517内部定义的。烧写内核时用的是硬件Ecc 4 bit校验方式。
第四步:在U-boot里验证开启指令缓存,数据缓存后与开启前的速度对比。
之前一直都是在搞51和M3,所以对缓存不是很清楚,但硬件的资源一般都是根据要求配置一些寄存器,于是就开始看AM3517数据手册,两千多页全英文,想想都头大,哎!英语不好。
于是就挑了一些相关的关键的看,但在芯片手册里根本找不到关于缓存的初始化和相关的介绍。在u-boot里有打开指令缓存和数据缓存的函数,但都只是一个接口。
废话就不多说了,关于MMU的作用以及为什么要使用内存管理与虚拟映射,还有缓存cache的分类,网上都有详细的资料,这里就不再多说了。在A8(整个ARM体系里具有MMU的内核)里指令缓存是可以单独单开的,但数据缓存必须与MMU同时打开,初始化步骤是先建立MMU页表,可以使用虚拟地址,也可以不用虚拟地址,但页表必须要建立,也就是必须要做映射(因为打开了MMU),在建立页表的时候可以根据自己的需要对相应的内存地址做允许缓存和不允许被缓存,页表是存储在内存空间里的一个,建立页表是一个比较复杂的过程,这里有一份某个培训机构(具体名字忘记了)的关于cache和mmu的详细资料,有需要的可以联系我,另外还有本很不错的书籍,建议想把ARM玩精的,都要看一下《ARM体系结构与编程》杜春雷的,写的很详细。
以下是建立一级页表的程序:
如有疑问,请联系woshic23
static inline unsigned int initializeMMU()
{
unsigned int adat,rr2,rr3,i;
rr2 = 0xdfe;
adat = get_cr() & 0xfffffffe; //Read Control Register
asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" : : "r" (adat) : "cc"); //disable MMU
asm volatile("mcr p15, 0, %0, c7, c5, 0 @ set CR" : : "r" (0) : "cc"); //invalidate caches jay
asm volatile("mcr p15, 0, %0, c7, c5, 6 @ set CR" : : "r" (0) : "cc"); //clear the whole jump target of cache
asm volatile("mcr p15, 0, %0, c7, c5, 7 @ set CR" : : "r" (0) : "cc"); //invalidate VA from branch predictor array
asm("MRC p15, 0, %0, c1, c0, 1 @ get CR" : "=r" (adat) : : "cc"); //Read Auxiliary Control Register
adat &= 0x3d;
asm volatile("mcr p15, 0, %0, c1, c0, 1 @ set CR" : : "r" (adat) : "cc"); //disable L2
asm volatile("mcr p15, 0, %0, c8, c7, 0 @ set CR" : : "r" (0) : "cc"); //invalidate TLBs //Invalidate Inst-TLB and Data-TLB
asm volatile("mcr p15, 0, %0, c2, c0, 2 @ set CR" : : "r" (0) : "cc"); //selected table reg 0 //Write Translation Table Base Control Register
asm volatile("mcr p15, 0, %0, c2, c0, 0 @ set CR" : : "r" (0x80000000) : "cc"); //set start of translation table //Write Translation Table Base Register
for( i=0;i<0x400;i++ ) //initialize the nand space page table (0 - 0x3fffffff)
{
rr3 = (rr2 | ( i<<20 ));
(*(volatile unsigned int*)(0x80000000+(i<<2))) = rr3;
}
for( i=0x400;i<0x800;i++ ) //initialize the on-chip Memory space page table (0x40000000 - 0x7fffffff)
{
rr3 = (rr2 | ( i<<20 )) & 0xfffffff2;
(*(volatile unsigned int*)(0x80000000+(i<<2))) = rr3;
}
rr3 = (rr2 | ( 0x800<<20 ));
(*(volatile unsigned int*)(0x80000000+(0x800<<2))) = rr3 & 0xfffff01f; //initialize the store page table space in the sdram (0x80000000 - 0x80100000)
for( i=0x801;i<0x900;i++ ) //initialize the SDRAM main address space(SMS) page table (0x80000000 - 0xbfffffff)
{
rr3 = rr2 | ( i<<20 );
(*(volatile unsigned int*)(0x80000000+(i<<2))) = rr3;
}
asm volatile("mcr p15, 0, %0, c3, c0, 0 @ set CR" : : "r" (0xfffffffd) : "cc"); //Setup domain control register Enable all domains to client mode //Write Domain Access Control Register
asm("MRC p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (adat) : : "cc"); //read CP15 register 1 into adat
//adat &= ~((1<<12)|(1<<2)); //disable icache and dcache
adat |= 1 | (1<<12) | (1<<2);
asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" : : "r" (adat) : "cc");
}
公司现在所有的液晶驱动从4.3到12.1都是用的三星的2440,一直想对Ti a8的液晶驱动研究一下,但由于时间原因,还没有机会,希望有机会能体验一下AM3359的性能!
写的不好,请大家见谅,这是第一次写一个总结,一直都比较忙,这几天一直等一台样机,所以闲了几天。
希望大家能多分享!!
下面还有一篇关于LM3S-M3的应用,抽时间再写吧!