s3c2440 mmu 裸机程序

程序用的韦东山的第七章的示例代码。这里总结下问题:

  1. 韦东山的代码写的挺好的。注释比较多,结合芯片手册以及920T内核手册页很容易看懂。
  2. 我用的JLINK直接在内存里调试裸机程序。因此不需要使用H-JTAG烧写nandflash,程序直接下载到内部ram里面运行。编译好的mmu.bin大小为3KB,内部ram为4KB。
  3. FL2440的几个led灯对应于GPB5,6,8,10.因此改了下leds.c的一些代码。如下:
    /*
     * leds.c: 循环点亮4个LED
     * 属于第二部分程序,此时MMU已开启,使用虚拟地址
     */ 
    
    #define GPBCON      (*(volatile unsigned long *)0xA0000010)     // 物理地址0x56000010
    #define GPBDAT      (*(volatile unsigned long *)0xA0000014)     // 物理地址0x56000014
    
    #define	GPB5_out	(1<<(5*2))
    #define	GPB6_out	(1<<(6*2))
    #define	GPB8_out	(1<<(8*2))
    #define	GPB10_out	(1<<(10*2))
    
    /*
     * wait函数加上“static inline”是有原因的,
     * 这样可以使得编译leds.c时,wait嵌入main中,编译结果中只有main一个函数。
     * 于是在连接时,main函数的地址就是由连接文件指定的运行时装载地址。
     * 而连接文件mmu.lds中,指定了leds.o的运行时装载地址为0xB4004000,
     * 这样,head.S中的“ldr pc, =0xB4004000”就是跳去执行main函数。
     */
    //static inline void wait(volatile unsigned long dly)
    static inline void wait(unsigned long dly)
    {
        for(; dly > 0; dly--);
    }
    
    int main(void)
    {
        unsigned long i = 0;
        
        // 将LED1-4对应的GPB5/6/7/8四个引脚设为输出
        //GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out;       
    	GPBCON = GPB5_out|GPB6_out|GPB8_out|GPB10_out;		// 将LED1-4对应的GPB5/6/8/10四个引脚设为输出
    
        while(1){
            wait(30000);
            //GPBDAT = (~(i<<5));     // 根据i的值,点亮LED1-4
            GPBDAT = ((i&0x8?0:1)<<10) | ((i&0x4?0:1)<<8) | ((i&0x2?0:1)<<6) | ((i&0x1?0:1)<<5); 
            if(++i == 16)
                i = 0;
        }
    
        return 0;
    }
    
  4. 在测试的时候遇到一个问题,那就是led不是按照我所预想的4个灯以i的值进行闪烁。而是常亮。

           经过仔细对比前面章节的led实验,以及代码。发现:

          

objs := head.o init.o leds.o

mmu.bin : $(objs)
	arm-linux-ld -Tmmu.lds -o mmu_elf $^
	arm-linux-objcopy -O binary -S mmu_elf $@
	arm-linux-objdump -D -m arm mmu_elf > mmu.dis
	
%.o:%.c
	#arm-linux-gcc -Wall -nostdlib -O2 -c -o $@ $<
	arm-linux-gcc -Wall -O2 -c -o $@ $<
	#arm-linux-gcc -Wall -c -o $@ $<

%.o:%.S
	#arm-linux-gcc -Wall -nostdlib -O2 -c -o $@ $<
	#arm-linux-gcc -Wall -O2 -c -o $@ $<
	arm-linux-gcc -Wall -c -o $@ $<

clean:
	rm -f mmu.bin mmu_elf mmu.dis *.o		

           其中可以看出,对*.c 进行O2优化,因此在leds.c中wait函数中dly变量可能被优化。

           将static inline void wait(unsigned long dly) 改为 static inline void wait(volatile unsigned long dly),防止编译进行优化操作。

           这篇文章对编译器优化原因以及volatile关键字用法做了详细说明http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764231.html

           或者我们将Makefile中的优化选项去除,同样能达到效果。有兴趣的同学可以试试。

           arm-linux-gcc -Wall -c -o $@ $<

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值