zoukankan      html  css  js  c++  java
  • (转)嵌入式linux系统开发过程中遇到的——volatile

    原文地址:http://blog.csdn.net/HumorRat/article/details/5631023

     

    对于不同的计算机体系结构,设备可能是端口映射,也可能是内存映射的。如果系统结构支持独立的I/O地址空间,并且是端口映射,就必须使用汇编语言完成实际对设备的控制,因为C语言并没有提供真正的“端口”的概念。如果是内存映射,那就方便的多了。

     

    以#define IOPIN (*((volatile unsigned long *) 0xE0028000)) 为例:

    作为一个宏定义语句,define是定义一个变量或常量的伪指令。首先( volatile unsigned long * )的意思是将后面的那个地址强制转换成 volatile unsigned long * ,unsigned long * 是无符号长整形,volatile 是一个类型限定符,如const一样,当使用volatile限定时,表示这个变量是依赖系统实现的,被限定的变量会被其他程序或者计算机硬件修改,由于地址依赖于硬件,volatile就表示他的值会依赖于硬件。

     

    volatile 类型是这样的,其数据确实可能在未知的情况下发生变化。比如:

    • 硬件设备的终端更改了它,现在硬件设备往往也有自己的私有内存地址,比如显存,他们一般是通过映象的方式,反映到一段特定的内存地址当中,这样,在某些条件下,程序就可以直接访问这些私有内存了。

    • 共享的内存地址,多个程序都对它操作的时候。你的程序并不知道,这个内存何时被改变了。如果不加这个voliatile修饰,程序是利用cache当中的数据,那个可能是过时的了,加了 voliatile,就在需要用的时候,程序重新去那个地址去提取,保证是最新的。

    归纳起来如下:

    1)volatile变量可变,允许除了程序之外的因素,比如硬件来修改他的内容。

    2)访问该数据任何时候都会再次访问该地址处内容,即通过cache提高访问速度的优化被取消

     

    对于((volatile unsigned long *) 0xE0028000)为随硬件需要定义的一种地址,前面加上“*”指针,表示该地址上的内容,整个定义用字符串IOPIN代替,调用的时候直接对指向的地址寄存器写内容既可,非常方便(可以参考vivi的代码)。

     

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

     

    再给一例:对于(volatile unsigned char *)0x20,它是由两部分组成:

    1)(unsigned char *)0x20,0x20只是个值,前面加(unsigned char *)表示0x20是个地址,而且这个地址类型是unsigned char ,意思是说读写这个地址时,要写进unsigned char 的值,读出也是unsigned char(这句话非常有用)。

    2)volatile,关键字volatile 确保本条指令不会因C 编译器的优化而被省略。例如用while((unsigned char *)0x20)时,有时系统可能不真正去读0x20地址所指向的值,而是直接用第一次读出的值(在cache里),如果这样,那这个循环可能是个死循环。用了volatile 则要求每次都去读地址0x20所指向的实际值。

     

    那么(volatile unsigned char *)0x20是一个固定的指针,是不可变的,不是变量。而char *u则是个指针变量。

     

    再在前面加"*" —— *(volatile unsigned char *)0x20则变成了变量(普通的unsigned char变量,不是指针变量),如果#define i (*(volatile unsigned char *)0x20),那么与unsigned char i是一样了,只不过前面的i的地址是固定的,即:(volatile unsigned char *)0x20。

  • 相关阅读:
    FZU 2112 并查集、欧拉通路
    HDU 5686 斐波那契数列、Java求大数
    Codeforces 675C Money Transfers 思维题
    HDU 5687 字典树插入查找删除
    HDU 1532 最大流模板题
    HDU 5384 字典树、AC自动机
    山科第三届校赛总结
    HDU 2222 AC自动机模板题
    HDU 3911 线段树区间合并、异或取反操作
    CodeForces 615B Longtail Hedgehog
  • 原文地址:https://www.cnblogs.com/sheshiji/p/3624404.html
Copyright © 2011-2022 走看看