C语言(*(volatile unsigned CHAR *)addr)理解

嵌入式中C语言操作寄存器

看ARM程序时,会看到类似如下的代码:

#define SREG     (*(volatile unsigned CHAR *)0x5F)

在嵌入式系统编程中,一般要求程序员能够利用C语言访问固定的内存地址。按C语言的语法来看,这个地址应该由指针类型来表示,所以在操作某个内存地址,比如0x5c时,其步骤如下:

  1. 将地址强制转换为指针类型 ->(unsigned  CHAR * )0x5c,假设ARM是八位的寄存器,就用char,是32位,就用long了,这时候地址被强制转换成了指向unsigned CHAR类型。
  2. 对指针变量解引用 -> (unsigned  CHAR )0x5c 这样就能操作指针所指向的地址内容了
  3. 为了防止编译器的优化,同时为了规范代码,将#define宏中的参数用括号括起来,将0x5c用变量名代替,并加上volatile关键字,所以最后的形式就是这样的 -> #define SREG ((volatile unsigned  CHAR )(addr) )

这个时候就可以采用如下方式对这个内存地址进行操作了

读取内容:temp = addr

写入内容:addr = 0x57

实际的例子如下:

#define REG32(addr)     (*(volatile unsigned long  * const)(addr))
unsigned long temp;
temp = REG32(addr); // 读addr这个地方的值
REG32(addr) = temp; // 往addr这个地方写值

/*
(*(volatile unsigned long * const)(addr))
将addr这个地址转化成一个指针(*),该指针不能改变它的指向(const),该指针会指向一个unsigned long类型,该unsigned long会以“意想不到”的方式被改变,所以请编译器不要做优化(volatile)
*/
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页