S3C2440之MMU操作(MDK4.20) 与 S3C2440开发工具realview MDK4.20使用入门

目前仍然有许多人在使用ADS1.2编译ARM9的程序,这款编译器实属经典,但是已经多年停止更新、维护了。这篇文章主要讲解ARM公司受够Keil之后力推的一款编译器MDK。

MDK的使用上和ADS1.2有很多相似之处,从ADS1.2过渡到MDK也是非常容易的一种事情。


还是无图无真相。

<一>这是MDK打开的情形,当然我这已经是一个建立好的工程。如果一开始是空的,按图点击project-->new uvision project即可。



<二>

关于工程名的命名,修改,添加文件等与其余的编译器无异,相信大家都会的。这里重点讲解魔术棒的配置



<三>

可以看到介面上有个Target Option选项。这才是该编译器强大的所在。


设备选择,大家根据实际情况选择即可,我这里选择的是S3C2440A

 


时钟部分为模拟调试的时钟,默认即可。

操作系统部分,MDK提供了一个实时操作系统,便于大家开发RTOS上的程序,如果不需要,可以选无。

右上角可以选择ARM或者Thumb代码模式。

左下角为只读内存的区域配置:有内部的ROM on-chip,有外部的ROM off-chip这个根据自己实际情况选择。S3C2440A无片上可以利用的ROM,但是可能会外接ROM,比如

Nor或者NAND。为你的目标板上有的资源打上default勾选。

右下角为读写内存区域配置:有内部的RAM on-chip,有外部的RAM off-chip这个也是根据自己实际情况配置。S3C2440A有内部RAM,为0x40000000的4K大小,NAND时候会被映射到BANK0。

NOTE:::以上内存的区域配置是很灵活的,除了根据你自己的目标板实际配置外,还可以根据你的目的来配置,你可能需要将RAM也模拟成ROM,这样便于调试等等。



这里选项很简单,默认没有勾选Create HEX File,可以勾选上。也可以根据需要生成目标库。也可以为目标文件单独选择存放文件夹,使工程文件清晰。



List也可以选择存放的目录。可以选择输出的内容文件。比如内存映像文件,符号文件,调用关系,交叉引用,生成文件的内存信息,未使用的section信息等。

便于查看。



选项也很清晰。重点是bulid后的用户程序。一般是用来将自己生成的axf转换为bin文件,和ads1.2很像。但是它比ads1.2至少强在一地方。

大家可能注意到--bincombined--bincombined_padding=1类似的命令,该命令存在的原因跟scatter文件有关。

scatter文件描述了如何组成自己的输入段,形成加载域,执行域,最终按照要求得到自己想要的内存布局文件。

BUT如果存在两个及其以上的加载域的话,生成的二进制文件会有多个,虽然我们可以自主的烧写到我们的目标存储区,但是这无疑增加了我们的负担!

在ADS1.2中,是没有直接的办法将多个bin文件连接在一起的,只能利用H-JTAG类似的工具,将多个bin文件转为HEX文件,拼接起来,再转为bin,有些麻烦

但是MDK下,直接利用这个命令即可完成将多个bin连成1个bin文件,是很方便的。这样scatter文件的多个加载域就不是问题了。



没什么特别的,注意默认优化级别的选择对应是level2。警告的话,可以选显示全部警告信息。

自己工程的头文件路径也要直接添加好,不然找不到。



与上一个选项卡类似。



linker选项也是十分重要的。默认的不是这个图的样式,是勾选了“利用目标选项卡里的内存布局”安排RO RW段。

一般情况下,这样的确是可以的,但是如果自己有特殊的要求,是需要自己写scatter文件的。这个图就是我自己写的一个scatter文件,未利用默认选项,所以未勾选。

微控制命令下可以自己写上对应的命令,比如这里的指定入口等等。



左右对称的选项,重点是右边,虽然模拟也很强大,但是大家一般都是有目标板的,所以还是硬件调试的手段。

可以选用的有Jlink Ulink等等,我手头有个山寨的Jlink,所以选择Jlink了。

下面的勾选框表明将自己要调试的文件下载到startup里,以及是否直接运行到main()函数。这个要根据实际需要来。

很可能你并不想利用MDK提供的库功能,就如同你不想使用ADS1.2提供的库功能一样,不使用main函数,那么就不存在run to main()。

很可能你是用SDRAM模拟ROM,在SDRAM中调试代码,也可能不需要将代码下载到starup。

抑或你在SDRAM中调试,使用了调试脚本,调试脚本里已经做了这2项工作,也是不需要勾选的,可以自己逐步尝试。



应用选项卡,是针对Flash应用的。可以选择flash烧写工具。



点击设置可以进入Flash选择,如果不存在自己的flash型号,可以自己添加算法,MDK手册有模板教你一步一步添加自己的Flash算法,比如nor nand之类的都可以添加。

Ramfor Alg是用于烧写算法的空间,MDK手册是说一般用内部RAM。

 

重点的都讲完了,老规矩,以点亮LED结束这篇文章吧。

 

程序部分:

本程序将0-1M映射为本身,将0xa0000000~0xa000fffff映射为0x56000000~0x560ffffff,将0xb0000000~0xb3ffffff映射为0x30000000~0x3fffffff

涉及到代码文件有s3c2440.s文件,init.c文件,led.c文件,led.sct文件

s3c2440.s主要是调用一些初始化程序,init.c是初始化代码,led.c只是利用新的虚拟地址寻找gpio,点亮led。

编译器MDK4.20

led.sct文件如下所示:

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
; Run in RAM

LR_ROM1 0x00000000 0x00200000         {    ; load region
   NANDFLASH +0 0X00200000  {  ; load address = execution address
   *.o (mmu, +First)  ; 用一个 " +first " 强行将 *.s 中的 sdram段 放在 ER_ROM1段 的起始位置,即 0x0 位置。
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_RAM1 +0  {  ; RW data
  .ANY(+RW +ZI)
  }
;   RW_IRAM1 0x40000000 0x00001000  {
;    .ANY(+RW +ZI)
;  }
}

LR_ROM2 2048 2048{
 SDRAM 0XB0004000{
 leds.o(*)
 }
}

 

head.s文件:

 PRESERVE8
 AREA mmu, CODE, READONLY
 ENTRY
start
 IMPORT disable_watch_dog
 IMPORT memsetup
 IMPORT copy_2th_to_sdram
 IMPORT create_page_table
 IMPORT mmu_init 

 ldr sp, =4096
 bl disable_watch_dog
 bl memsetup
 bl copy_2th_to_sdram
 bl create_page_table
 bl mmu_init
 ldr sp, =0xB4000000
 ldr pc, =0xB0004000
halt_loop
 b halt_loop

 END

 


init.c文件:

//creat page table
void create_page_table(void)
{
#define MMU_FULL_ACCESS(3<<10)
#define MMU_DOMAIN(0<<5)
#define MMU_SPECIAL(1<<4)
#define MMU_CACHEABLE(1<<3)
#define MMU_BUFFERABLE(1<<2)
#define MMU_SECTION(2<<0)
#define MMU_SECDESC(MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL |\
MMU_SECTION)
#define MMU_SECDESC_WB(MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL |\
MMU_SECTION | MMU_CACHEABLE | MMU_BUFFERABLE)
#define MMU_SECTION_SIZE0x00100000

ulong virtualaddr, physicaladdr;
ulong *mmu_tlb_base = (ulong*)0x30000000;

/*<1>0~1M map to 0~1M  virtualaddr == physicaladdr*/
virtualaddr = 0;
physicaladdr = 0;


//mmu page table store at 0x30000000
//vritualaddr>>20 is index of mmu page table
*(mmu_tlb_base + (virtualaddr>>20)) = (physicaladdr&0xfff00000) | MMU_SECDESC_WB;

/*<2>0xa0000000~0xa000fffff map to 0x56000000~0x560fffff*/
virtualaddr = 0xa0000000;
physicaladdr = 0x56000000;
*(mmu_tlb_base + (virtualaddr>>20)) = (physicaladdr&0xfff00000) | MMU_SECDESC;


/*<3>0xb0000000~0xb3ffffff map to 0x30000000~0x33fffffff total=64m totaldescs=64*/
virtualaddr = 0xb0000000;
physicaladdr = 0x30000000;

while(virtualaddr < (ulong)0xb4000000)
{
*(mmu_tlb_base + (virtualaddr>>20)) = (physicaladdr&0xfff00000) | MMU_SECDESC_WB;
virtualaddr += MMU_SECTION_SIZE;
physicaladdr += MMU_SECTION_SIZE;
}
}




//init MMU
void mmu_init(void)
{
ulong ttb = 0x30000000;

__asm{
mov r0,#0
mcr p15,0,r0,c7,c7,0         //invalidate Icache Dcache

mcr p15,0,r0,c7,c10,4//drain writer buffer
mcr p15,0,r0,c8,c7,0        //invalidate TLB

mov r4,ttb
mcr p15,0,r4,c2,c0,0         //set page table base-addr

mvn r0,#0                    //invert all bits:0x0000000->0xffffffff
mcr p15,0,r0,c3,c0,0         //set domain(all is 0b11)


mrc p15,0,r0,c1,c0,0        //read control register

bic r0,r0,#0x3000
bic r0,r0,#0x0300
bic r0,r0,#0x0087

orr r0,r0,#0x0002
orr r0,r0,#0x0004
orr r0,r0,#0x1000
orr r0,r0,#0x0001

mcr p15,0,r0,c1,c0,0

};
}

 

leds.c文件:

#define GPBCON (*(volatile unsigned long*)0xa0000010)
#define GPBDAT (*(volatile unsigned long*)0xa0000014)

#define GPB5_OUT (1 << (5 * 2))
#define GPB6_OUT (1 << (6 * 2))
#define GPB7_OUT (1 << (7 * 2))
#define GPB8_OUT (1 << (8 * 2))

/*static void wait(unsigned long dly)
{
 for(; dly > 0; dly-- );
} */

int main(void)
{
 unsigned long i =  0, dly;
 GPBCON = GPB5_OUT | GPB6_OUT | GPB7_OUT | GPB8_OUT;

 while(1)
 {
  for(dly = 30000000; dly > 0; dly-- ); 
 // wait(3000000);
  GPBDAT = (~(i << 5));
  if(++i == 8)
   i = 0;
 }
 return 0;
}

 

文章参阅处:http://blog.csdn.net/sam1430/article/details/6970037

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值