DDR读写源码测试

DDR读写程序:

Uint32 memfill32( Uint32 start, Uint32 len, Uint32 val )
{
    Uint32 i;
    Uint32 end = start + len;
    Uint32 errorcount = 0;

    /* Write Pattern */
    for ( i = start; i < end; i += 4 )
    {
        *( volatile Uint32* )i = val;
    }

    /* Read Pattern */
    for ( i = start; i < end; i += 4 )
    {
        if ( *( volatile Uint32* )i != val )
        {
            errorcount++;
            break;
        }
    }

    return errorcount;
}

(volatile Uint32 *)i :将 i 强制转换成易变指针,指向start,start为DDR写入的首地址。

*(volatile Uint32 *)i :改写 i 指向地址中的值。

test:

Int16 ddr_test( )
{
    ddr_base = 0x80000000;       // DDR memory
    ddr_size = 0x00100000;       // 1 MB

    if ( memfill32( ddr_base, ddr_size, 0xFFFFFFFF ) )
        return 1;

    if ( memfill32( ddr_base, ddr_size, 0xAAAAAAAA ) )
        return 2;

    if ( memfill32( ddr_base, ddr_size, 0x55555555 ) )
        return 4;

    if ( memfill32( ddr_base, ddr_size, 0x00000000 ) )
        return 8;
    return 0;
}

main.c

void main( void )
{
    /* Initialize BSL */
    EVMDM6437_init( );
    TEST_execute( ddr_test, "DDR", 1 );
    printf( "\n***ALL Tests Passed***\n" );
}

volatile关键字的作用:

简单的说使用 volatile的目的就是: 
让对 volatile 变量的存取不能缓存到寄存器,每次使用时需要重新存取。 

编译器对代码的优化是指: 
CPU 在执行的过程中,因为访问内存的速度远没有 cpu 的执行速度快,为了提高效率,引入了
高速缓存 cache. C 编译器在编译时如果不知道变量会被其它外部因素(操作系统、硬件或者
其它线程)修改,那么就会对该变量进行标识,即优化.那么这个变量在 CPU的执行过程中,就
会被放到高速缓存 cache 去,进而达到对变量的快速访问. 在了解了优化的概念后,试想如
果我们事先就知道该变量会被外部因素改变,那么我们就在这个变量定义前加上 Volatile,
这样编译器就不会对该变量进行优化.这样该变量在 cpu 处理的过程当中,就不会被放到高
速缓存 cache 中
。 

#define A (*(volatile unsigned long *)0x48000000) 
... 
     A = 0x01; 
... 
    这实际上就是内存映射机制的方便性了。其中 volatile 关键字是嵌入式系统开发的一个重要特点。上述表达式拆开来分析,首先(volatile unsigned long *)0x48000000的意
思是把 0x48000000 强制转换成 volatile unsigned long 类型的指针,暂记为 p,那么就是
#define A *p, 即A 为P 指针指向位置的内容了。 这里就是通过内存寻址访问到寄存器 A,
可以读/写操作。 
用 GCC 编译时。volatile 所指示的寄存器不进行优化!!! 

理解#define rRTCCON    (*(volatile unsigned char *)0x57000043) //RTC control 
嵌入式系统编程,要求程序员能够利用 C 语言访问固定的内存地址。既然是个地址,那么按
照 C 语言的语法规则,这个表示地址的量应该是指针类型。所以,知道要访问的内存地址后,
比如 0x57000043, 
   第一步是要把它强制转换为指针类型 
(unsigned char *)0x57000043, s3c2410 的rRTCCON是单字节访问的(怎么看出来的???
我无法理解),所以 0x57000043 强制转换为指向 unsigned char 类型。 
   volatile(可变的)这个关键字说明这变量可能会被意想不到地改变,这样编译器就不
会去假设这个变量的值了。这种“意想不到地改变”,不是由程序去改变,而是由硬件去改
变——意想不到。 
   第二步,对指针变量解引用,就能操作指针所指向的地址的内容了 
   *(volatile unsigned char *)0x57000043 
   第三步,小心地把#define 宏中的参数用括号括起来,这是一个很好的习惯。 
在嵌入式系统中经常使用到 Volatile,对于volatile 的用法 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值