*(volatile unsigned short *)0x20000000背后的意义是啥?

dahuatttt 2008-06-06 04:08:23
加精
从8*8LED点阵灯程序中看到的。
...全文
4115 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
jdygrdzh 2012-02-04
  • 打赏
  • 举报
回复
再补充一点,volatile只是告诉编译器不要优化对这个地址的读写,以便能够直接访问这个地址所对应的硬件寄存器.但是实际上,编译器并不知道这个地址是内存中的还是在内存映射的寄存器里的,硬件对他的操作还是可能经过缓存cache,这样就不能达到直接访问硬件的目的.
解决方法是,处理器会有一个判断逻辑,看目的地址是不是可被缓存的.如果是内存地址当然可以,如果是硬件内存映射那不使用缓冲.这个对软件是透明的.
Robert_NORM 2011-10-28
  • 打赏
  • 举报
回复
前阵子,这个问题困扰我很久,隐隐约约的理解!看了文章之后受益匪浅、、、
谢谢~~~~~~
guangbiao_w 2011-06-03
  • 打赏
  • 举报
回复
已阅。
JimsdogV1 2011-04-26
  • 打赏
  • 举报
回复
volatile表示异变不固定的 每次用的时候都会重新加载值
csong220800227 2011-04-15
  • 打赏
  • 举报
回复
收益良多啊
dong20072 2010-05-10
  • 打赏
  • 举报
回复
楼上太cool了
zhihui525 2009-09-27
  • 打赏
  • 举报
回复
第一条编译的话应该会出错,你可以去试试看,楼上的 shuiyan 同志已经讲的很清楚了,楼主慢慢理解
一定要加*的,就像你定义变量
unsigned int *aa; //定义一个指针变量
aa=0x54; //表示这个指针变量的值为0x54
*aa=0x55;  //表示对以aa的值为地址的值进行赋值,也就是内存中0x00000054里的值置为0x55;

*(unsigned int *)0x54=0x55 也是一样的道理
但是 (unsigned int *)0x54=0x55 是不行的,编译器会认为是类似 0x54=0x55的赋值,那当然会出错的
[/Quote]


这个说得好……说到点子上了
gooogleman 2009-07-24
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 jchqxl 的回复:]
地址强制转换成指针
[/Quote]

指针就是地址啊,不用什么强制转换,只是强制转换某类型而已!
jchqxl 2009-07-09
  • 打赏
  • 举报
回复
地址强制转换成指针
dahuatttt 2008-06-16
  • 打赏
  • 举报
回复
0x20000000是真实的绝对地址么?不是mmu转换以后的地址?
用户 昵称 2008-06-16
  • 打赏
  • 举报
回复
你涉及的都是逻辑地址,有的设备只有几K的地址也能映射到2M以上。
ly_liuyang 2008-06-12
  • 打赏
  • 举报
回复
直接向IO Map操作
yangchao_cy 2008-06-12
  • 打赏
  • 举报
回复
绝对地址
fycom200 2008-06-11
  • 打赏
  • 举报
回复
volatile 是多余的,删掉它,然后应该就明白了吧

sherlock_lai 2008-06-11
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 dahuatttt 的回复:]
"控制该显示模块的I/O地址为0x20000000"
既然如此,那就应该是(volatile unsigned short *)0x20000000=XXX 啊。
可为什么写成*(volatile unsigned short *)0x20000000=XXX 才行呢?

ARM9-2410的板子
[/Quote]

0x20000000=XXX 怎么行?
0x1=0x2 这行么? 这些都是确切的值,当然不能划等号
又不是汇编里的 mov 0x01,0x02
sherlock_lai 2008-06-11
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 dahuatttt 的回复:]
1 (volatile unsigned short *)0x20000000=XXX
2 *(volatile unsigned short *)0x20000000=XXX
可是2在语义上应该是XXX存放在0x20000000内值所指向的地址里啊。和1是不同的地址啊!
还是不明白。。。
[/Quote]

第一条编译的话应该会出错,你可以去试试看,楼上的 shuiyan 同志已经讲的很清楚了,楼主慢慢理解
一定要加*的,就像你定义变量
unsigned int *aa; //定义一个指针变量
aa=0x54; //表示这个指针变量的值为0x54
*aa=0x55; //表示对以aa的值为地址的值进行赋值,也就是内存中0x00000054里的值置为0x55;

*(unsigned int *)0x54=0x55 也是一样的道理
但是 (unsigned int *)0x54=0x55 是不行的,编译器会认为是类似 0x54=0x55的赋值,那当然会出错的
dahuatttt 2008-06-11
  • 打赏
  • 举报
回复
谢谢各位的回答,终于搞清楚了!也谢谢wjlsmail,可惜揭帖早了,没给加上分。
wjlsmail 2008-06-11
  • 打赏
  • 举报
回复
(volatile unsigned short *)0x20000000=XXX
*(volatile unsigned short *)0x20000000=XXX

类似:

unsigned short * pus = 0x20000000;
pus = xxx; // 改变 pus 的指向,即pus这个地址变量的值改变为xxx
*pus = yyy; // pus所指向的地址空间,保存 yyy 值。

shuiyan 2008-06-11
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 dahuatttt 的回复:]
1 (volatile unsigned short *)0x20000000=XXX
2 *(volatile unsigned short *)0x20000000=XXX
可是2在语义上应该是XXX存放在0x20000000内值所指向的地址里啊。和1是不同的地址啊!
还是不明白。。。
[/Quote]

2在语义上是:有一个指针指向地址0x20000000,这个地址(0x20000000)中存放的值是xxx。
注意,在这里0x20000000已经是一个确定的地址值了,而不是变量。
如果在C语言里这么写:
unsigned int value = 100;
unsigned int* pt = &value;
那么你肯定能理解pt是一个指针,指向value这个变量的地址。

那么如果这么写呢:
unsigned int* pt;
pt = 0x20000000;
*pt = xxx;
能理解吗? pt是一直指针,指向一个地址,这个地址是固定的0x20000000,而这个地址上存放的值是一个int型数xxx。
shuiyan 2008-06-10
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 dahuatttt 的回复:]
"控制该显示模块的I/O地址为0x20000000"
既然如此,那就应该是(volatile unsigned short *)0x20000000=XXX 啊。
可为什么写成*(volatile unsigned short *)0x20000000=XXX 才行呢?

ARM9-2410的板子
[/Quote]
向一个地址赋值,当然是要在前面加*的,这是C的基本。
如果不加*,那就是在0x20000000这个地址存放了一个xxx,这个xxx也是一个地址,而不是一个你希望的变量值。
加载更多回复(9)

27,374

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧