*(volatile int *)解读
#def ine reg_gpio_ctrl *(volatile int *)(ToVirtual(GPIO_REG_CTRL))
#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关键字声明的变量i每一次被访问时,执行部件都会从i相应的内存单元中取出i的值。
没有用volatile关键字声明的变量i在被访问的时候可能直接从cpu的寄存器中取值(因为之前i被访问过,也就是说之前就从内存中取出i的值保存到某个寄存器中),之所以直接从寄存器中取值,而不去内存中取值,是因为编译器优化代码的结果(访问cpu寄存器比访问ram快的多)。
以上两种情况的区别在于被编译成汇编代码之后,两者是不一样的。之所以这样做是因为变量i可能会经常变化,保证对特殊地址的稳定访问。
volatile关键字的作用在于提醒编译器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份;通过这种方式也就给了volatile定义的变量被线程或中断服务子程序共享使用的能力,否则即使变量在中断中修改了,终端返回后读到的值仍然是修改之前的值,这样的程序会出现这样那样不可预知的bug。
*(volatile int *)解读的更多相关文章
- const volatile int i
问题: const volatile int i=10:这行代码有没有问题?如果没有,那 i 到底是什么属性? 回答: 没有问题,例如只读的状态寄存器.它是volatile,因为它可能被意想不到地改变 ...
- 嵌入式中的 *(volatile unsigned int *)0x500 解释
C语言中*(volatile unsigned int *)0x500的解释: 如下: (unsigned int *)0x500:将地址0x500强制转化为int型指针*(unsigned int ...
- const volatile同时限定一个类型int a = 10
const和volatile放在一起的意义在于: (1)本程序段中不能对a作修改,任何修改都是非法的,或者至少是粗心,编译器应该报错,防止这种粗心: (2)另一个程序段则完全有可能修改,因此编译器最好 ...
- *(volatile unsigned int *)的理解
1. 解释 前面是无符号整型unsigned int的指针, 后面加一个地址,就是无符号整型的地址,前面又一个星号就是这个地址的值. 2.volatile 同步 因为同一个东西可能在不同的存储介质中有 ...
- AbstractQueuedSynchronizer源码解读
1. 背景 AQS(java.util.concurrent.locks.AbstractQueuedSynchronizer)是Doug Lea大师创作的用来构建锁或者其他同步组件(信号量.事件等) ...
- 面试(三)---volatile
一.前言 最近去成都玩了一圈,整体感觉还不错,辞职以后工作找的也很顺利,随着年龄增加自己也考虑定居和个人长期发展的问题,反正乱七八糟的事,总之需要好好屡屡思路,不能那么着急下定论,当然我对 ...
- java并发编程之volatile
Java语言规范第三版中对volatile的定义如下:Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获得这个变量. 了解volatile关键字之 ...
- 关于多线程start()方法原理解读
1.为什么启动线程不用run()方法而是使用start()方法 run()方法只是一个类中的普通方法,调用run方法跟调用普通方法一样 而start()是创建线程等一系列工作,然后自己调用run里面的 ...
- J.U.C剖析与解读2(AQS的由来)
J.U.C剖析与解读2(AQS的由来) 前言 前面已经通过实现自定义ReentrantLock与自定义ReentrantReadWriteLock,展示了JDK是如何实现独占锁与共享锁的. 那么实际J ...
随机推荐
- Timeline Storyteller 现已加入自定义图表库
前言 下载地址: https://store.office.com/en-us/app.aspx?assetid=WA104381136&sourcecorrid=328f5e2b-e973- ...
- Nest.js 守卫
Docs: https://docs.nestjs.com/guards 当调用者具有足够的权限时,特定路由才可用 // app.guard.ts import { CanActivate, Exec ...
- 类似于Mimikatz的Linux Hash Dump工具
项目主页 https://github.com/huntergregal/mimipenguin 需要root权限 支持 Kali 4.3.0 (rolling) x64 (gdm3) Ubuntu ...
- Docker win10安装
因为虚拟机还没装好,所以现在win10上安装Docker 1.首先下载Docker Toolbox,因为Docker for windows需要win10专业版或者其他64位版本,我的系统虽然也是wi ...
- 解决在Windows10没有修改hosts文件权限
当遇到有hosts文件不会编辑或者,修改了没办法保存”,以及需要权限等问题如图: 我学了一招,先在交给你: 1.win+R 2.进入hosts的文件所在目录: 3.我们开始如何操作才能不出现权限问题那 ...
- css学习_css清除浮动
若元素没有设置宽高,那元素实际宽高是被内容撑起来, 若元素自己有设置宽高,那实际面积于自己的盒子模型有关 1.清除浮动的本质 清除浮动主要是为了解决父级元素因为子级浮动而引起的内部高度为0的问题. ( ...
- css 子盒子上下居中 文字溢出省略号
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 使用hashlib进行文件校验
import hashlib import os path = r'D:\CentOS 64 位' def file_md5(path): """ 文件校验 :param ...
- Java学习-049-正则工具类
自去年九月份决定再次入学和职业资格进阶,开始备战二者考试至今,以及当下进行中的职称申请,犹如孤独的狼,不断前行在路上,而今凡凡总总的已历8月... 不感慨了,如下为一园友需要的正则工具类,直接上码: ...
- java框架之Struts2(3)-OGNL&ValueStack
OGNL 概述 OGNL 是 Object-Graph Navigation Language 的缩写,它是一种第三方的.功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用 ...