您的位置 首页 开关

ARM界说特别寄存器*(volatile unsigned long *))的了解

以前老是对ARM程序中(*(volatileunsignedlong*))不理解,通过查阅资料,和看别人写的文章,今天对这个类型转换进行解析一下…

曾经老是对ARM程序中(*(volatile unsigned long *))不理解,经过查阅材料,和看他人写的文章,今日对这个类型转化进行解析一下。这个用法不止在界说内部特别寄存器有用,在用到外部总线时,界说外部器材的地址也会用。

关于嵌入式体系编程,要求程序员能够运用C言语拜访固定的内存地址。既然是个地址,那么依照C言语的语法规矩,这个表明地址的量应该是指针类型。所以,知道要拜访的内存地址后,比方0x5F。

第一步是要把它强制转化为指针类型
(unsigned CHAR *)0x5FAVR的SREG是八位寄存器,所以0x5F强制转化为指向unsigned CHAR类型。
volatile(可变的)这个关键字阐明这变量或许会被意想不到地改动,这样编译器就不会去假定这个变量的值了。这种“意想不到地改动”,不是由程序去改动,而是由硬件 去改 变—-意想不到。
第二步,对指针变量解引证,就能操作指针所指向的地址的内容了。
*(volatile unsigned CHAR *)0x5F
第三步,小心肠把#define宏中的参数用括号括起来,这是一个很好的习气,所以#defineSREG (*(volatile unsigned CHAR *)0x5F)
相似的,假如运用一个32位处理器,要对一个32位的内存地址进行拜访,能够这样界说:#define RAM_ADDR(*(volatile unsigned LONG*)0x0000555F)
然后就能够用C言语对这个内存地址进行读写操作了
读操作:tmp = RAM_ADDR;
写操作:RAM_ADDR = 0x55;

关于不同的计算机体系结构,设备或许是端口映射,也或许是内存映射的。假如体系结构支撑独立的IO地址空间,并且是端口映射,就必须运用汇编言语完结实践对设备的操控,因为C言语并没有供给真实的“端口”的概念。假如是内存映射,那就便利的多了。

以#define IOPIN (*((volatile unsigned long *) 0xE0028000))为例:作为一个宏界说句子,define是界说一个变量或常量的伪指令。首要(volatile unsigned long *)的意思是将后边的那个地址强制转化成volatile unsigned long *,unsigned long *是无符号长整形,volatile是一个类型限定符,如const相同,当运用volatile限守时,表明这个变量是依靠体系完成的,这个变量会被其他程序或许计算机硬件修正,因为地址依靠于硬件,volatile就表明他的值会依靠于硬件。volatile类型是这样的,其数据的确或许在不知道的情况下发生变化。比方同享的内存地址,多个程序都对它操作的时分。你的程序并不知道,这个内存何时被改动了。假如不加这个volatile润饰,程序是运用cache傍边的数据,那个或许是过期的了,加了volatile,就在需求用的时分,程序重新去那个地址去提取,保证是最新的。归纳起来如下:

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)可看作是一个一般变量,这个变量有固定的地址,指向0x20。而0x20仅仅个常量,不是指针更不是变量。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/dianyuan/kaiguan/276580.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部