为什么我们像这样在微控制器编程中寻址寄存器
Why we address registers in micro-controller programming like this
为什么我们在为寄存器写入地址时要在基地址上加上偏移量?
还有为什么要写下面这样的语法
#define CGPIO (*((volatile unsigned long*)0x400FE608));
我指的只是指针部分语法
(volatile unsigned long*)0x400FE608
语法将内存中的硬件特定地址(可能是寄存器)强制转换为指向 volatile unsigned long
的指针。指针的类型,volatile unsigned long
,是基于寄存器的大小,需要把它当作无符号的。指针定义为指向 volatile
以确保编译器不会优化多次读写,每次您的代码需要时执行一个操作。
前面的星号和整个表达式周围的括号是为了让您可以将 CGPIO
视为可分配的全局变量,并编写
CGPIO = 123;
和
unsigned long val = CGPIO;
不在CGPIO
前加星号。
它是一种技巧或副作用或语言的有意部分,允许您创建可用于访问(读取或写入)物理地址的指针。通常以这种方式用于外围设备的控制和状态寄存器。如果它是一个内存库,你当然也可以做同样的事情。
这不是唯一的方法,我也遇到过它无法生成正确大小的传输,但它的工作方式比它不工作的方式更频繁。在芯片供应商中找到开源裸机驱动程序是一件极其常见的事情。
为什么我们在为寄存器写入地址时要在基地址上加上偏移量?
还有为什么要写下面这样的语法
#define CGPIO (*((volatile unsigned long*)0x400FE608));
我指的只是指针部分语法
(volatile unsigned long*)0x400FE608
语法将内存中的硬件特定地址(可能是寄存器)强制转换为指向 volatile unsigned long
的指针。指针的类型,volatile unsigned long
,是基于寄存器的大小,需要把它当作无符号的。指针定义为指向 volatile
以确保编译器不会优化多次读写,每次您的代码需要时执行一个操作。
前面的星号和整个表达式周围的括号是为了让您可以将 CGPIO
视为可分配的全局变量,并编写
CGPIO = 123;
和
unsigned long val = CGPIO;
不在CGPIO
前加星号。
它是一种技巧或副作用或语言的有意部分,允许您创建可用于访问(读取或写入)物理地址的指针。通常以这种方式用于外围设备的控制和状态寄存器。如果它是一个内存库,你当然也可以做同样的事情。
这不是唯一的方法,我也遇到过它无法生成正确大小的传输,但它的工作方式比它不工作的方式更频繁。在芯片供应商中找到开源裸机驱动程序是一件极其常见的事情。