`
fp_moon
  • 浏览: 971099 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

对(*(volatile unsigned long *)) 的理解

阅读更多

 

对(*(volatile unsigned long *)) 的理解

 

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

 

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

 

volatile 类型是这样的,其数据确实可能在未知的情况下发生变化。比如,硬件设备的终端更改了它,现在硬件设备往往也有自己的私有内存地址,比如显存,他们一般是通过映象的方式,反映到一段特定的内存地址当中,这样,在某些条件下,程序就可以直接访问这些私有内存了。另外,比如共享的内存地址,多个程序都对它操作的时候。你的程序并不知道,这个内存何时被改变了。如果不加这个voliatile修饰,程序是利用catch当中的数据,那个可能是过时的了,加了 voliatile,就在需要用的时候,程序重新去那个

 

地址去提取,保证是最新的。归纳起来如下:

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

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

对于((volatile unsigned long *) 0xE0028000)为随硬件需要定义的一种地址,前面加上“*”指针,为直接指向该地址,整个定义约定符号IOPIN代替,调用的时候直接对指向的地址寄存器写内容既可。这实际上就是内存映射机制的方便性了。其中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的值,而是用第一次读出的值,如果这样,那这个循环可能是个死循环。用了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)可看作是一个普通变量,这个变量有固定的地址,指向0x20。而0x20只是个常量,不是指针更不是变量。

 

分享到:
评论

相关推荐

    (*(volatile unsigned long *)详解

    (*(volatile unsigned long *)详解

    SPI.zip_6410_6410 spi_swap

    #define CLK_CFG1 ( *((volatile unsigned long *)0xE1400004) )//0X #define FB_CLK_SEL1 ( *((volatile unsigned long *)0xE140002C) ) #define SWAP_CFG1 ( *((volatile unsigned long *)0xE1400028) ) #...

    ARM寄存器定义_总线访问外部地址寄存器定义====与51的区别

    (volatile unsigned long *)0x53000000 强制类型转换为无符号的长整形的指针,即指定0x53000000存储单元存储的变量是无符号的长整形 而volatile 关键字表示定义的变量会被外部进程所修改。 比如跨进程访问的内存...

    ili932x系列驱动程序

    /****************************************************************************** * 文件名称:ili932x.c * 摘 要:支持ILI9320和ILI9325...#define Clr_Rst (*((volatile unsigned long *) 0x40011414) = RstPin)

    51单片机TCP/IP源代码

    unsigned int volatile event_word; unsigned char idata debug; unsigned char idata rcve_buf_allocated; char xdata text[20]; // This sets my hardware address to 00:01:02:03:04:05 unsigned char code my_...

    AVR示波器工程制作

    #define ulong unsigned long #endif /**********************************************************************************/ /***********************************************************************/ #...

    51系列mp3源代码

    #define UINT32 unsigned long #define UINT8X unsigned char xdata #define UINT8VX unsigned char volatile xdata UINT8VX CH375_CMD_PORT _at_ 0x9FF1; /* CH375命令端口的I/O地址 */ UINT8VX CH375_DAT_...

    pt7c4307 驱动

    static volatile unsigned long rtc_irq_data; static unsigned long rtc_freq = 1; /*FTRTC010 supports only 1Hz clock*/ static struct fasync_struct *rtc_async_queue; static DECLARE_WAIT_QUEUE_HEAD(rtc_...

    uboott移植实验手册及技术文档

    int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) { int i, j; Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) if ((start_addr & ...

    哈希表查找

    "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while" }; char *key_help_temp[] = { "auto function", "break function", "case function", "char function", "const ...

    嵌入式系统/ARM技术中的Linux 进程创建

    作者:李智敏,华清远见嵌入式学院上海分中心讲师。  在 Linux 内核内,进程是由相当大的一个称为 task_struct 的结构表示的。... volatile long state;  void *stack;  unsigned int flags;  in

    C#编写的简单词法分析

    const float short unsigned continue for signed void default goto sizeof volatile do while static f 标识符: (常量名,变量名,过程名) 1. 所有标识符必须由一个字母(a~z或A~Z)或下划线(_)开头; 2. 标识符的...

    C_gjz.rar_float

    unsigned void Volatile while 说明: 1、关键字auto用于说明自动变量,由于变量声明时默认情况下就是自动变量,所以很少使用。 2、volatile(易变的)表示该变量不经过赋值,其值也可能被改变(例如表示时钟的变量...

    C++各种排序+哈希查找(数据结构作业)

    "switch" , "typedef" , "union" , "unsigned" , "void" , "volatile" , "while" } ; //定义字符串数组,存放32个关键字 int HUSH ( char * ); //哈希函数 void Search () ; //查找 void Print () ; //打印...

    c语言入门教程.txt

    union unsigned void volatile while C语言还包括一些不能用做标识符的扩展关键字。 asm cdecl _cs _ds _es far huge interrupt near pascal _ss 所以在以后的学习中,在给变量命名时要避开这些关键字。 3. Turbo C...

    初级C语言教案 auto break case char const

    初级C语言教案 适用于初学者,对初学者很有帮助.里面介绍的 很详细auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof ...

    C语言 由ANSI标准定义的32个关键字

    auto double int struct break else long switch case enum register typedef char extern return union const float short unsigned continue for signed void default goto sizeof volatile do if while static

    Linux内核中的定时

    系统定时器频率(节拍率)是通过静态预处理器定义的,也是HZ,编写内核代码时,不要以为HZ值是固定不变的值。连续两次时钟的间隔时间叫做节拍,它等于节拍率分之一秒。... extern unsigned long volatile jiffie

    C++基本概念 (面试、复习)

    long switch case enum register typedef char extern return union const float short unsigned continue for signed void default goto sizeof volatile do if static while asm _cs _ds _es _ss cdecl far huge ...

    哈希查找-表长101

    建立哈希表查找c++中32个关键字,其中哈希表长为M=101 32个关键字为auto break case char const continue default do double else enum extern float for ...struct switch typedef union unsigned void volatile while

Global site tag (gtag.js) - Google Analytics