全部博文(395)
分类: LINUX
2012-02-08 18:10:49
volatile和不加volatile的区别
今天碰到一个非常奇怪的问题,我有一个ram区,存在于fpga中,但是这个ram只能写不能读,一旦读的时候,读到的应该是随机数。
下面就是这个ram区的地址:fpga_virt_base + SCRAM1_BASE_ADDR
程序如下:
#if 0
for( i=6; i<14; i++){
*((volatile unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +i)) =i;
}
printk("\n");
#else
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +6)) =0x06;
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +7)) =0x07;
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +8)) =0x08;
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +9)) =0x09;
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +10)) =0x0a;
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +11)) =0x0b;
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +12)) =0x0c;
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +13)) =0x0d;
#endif
printk("\nwmsc_write is write ram is:\n");
printk("%d %d %d %d %d %d %d %d\n",
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +6)),
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +7)),
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +8)),
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +9)),
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +10)),
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +11)),
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +12)),
*((unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +13))
);
1.
此时输出的结果是:
fpga_virt_base is 0xf1580000
6 7 8 9 10 11 12 13
2.
当我把#if 0换成#if 1
后,输出结果是:
wmsc_write is write ram is:
34 34 0 0 51 51 0 0
在这个地方我试验了一下午
3。
当我把输出的地方改为如下的方式时:
printk("%d %d %d %d %d %d %d %d\n",
*((volatile unsigned char *)(fpga_virt_base + SCRAM1_BASE_ADDR +6)),
时,和2的输出效果是一样的。
综上,这也就说明了,对于一个地址,如果加上了volatile参数,这个地址也就不会经过编译器优化,也就是说这个地址就是真实的地址,但是,如果不加上volatile的话,这个地址可能被编译器优化,这个例子就是,关于优化,什么优化,对于这个例子而言,这个地址就是不是硬件本身的地址,而是驻足与内存中的地址(导致了后面访问这个地址的时候,数据输出为想要的地址。),所以才有了结果不一样的情况出现。