固定有关C/C 的知识差距并注册访问
Fixing Gap in knowledge about C/C++ and register access
诚然,我是C 的新手。不幸的是,我看到的大多数代码要么使用asm
调用或定义extern
函数,其主体在汇编文件中。
这就是为什么我非常退出以找到以下代码的原因。我已经研究了代码库3天了。
句法我了解下面代码的每一行;除了重要的是因为我不明白它的工作方式!
- types.h定义
u32
和uintptr
(我已经看过它们) - 当C和C 代码混合时,需要IFDEF __cplusplus。特别是因为
extern C
是C 特异的。如果GCC具有-fno-exceptions
参数
,则可以省略 -
volatile
用于防止编译器进行任何优化,因为该地址必须是完美的,因为它是写入/从寄存器中/读取的。
所有的话,我仍然不知道该代码实际上是如何写或从寄存器中读取的。
#include <circle/types.h>
#ifdef __cplusplus
extern "C" {
#endif
static inline u32 read32 (uintptr nAddress)
{
return *(u32 volatile *) nAddress;
}
static inline void write32 (uintptr nAddress, u32 nValue)
{
*(u32 volatile *) nAddress = nValue;
}
#ifdef __cplusplus
}
#endif
#endif
*(unsigned int *)
是什么意思?这是如何用于读写寄存器的?nAddress
是否必须是物理地址
您正在寻找"内存映射输入输出"。
CPU与外部硬件交谈的最常见方法是通过内存总线 - 用于访问正常内存的相同总线。
首先,请记住,CPU与内存的互动不仅涉及读取和写入,还涉及诸如总线错误处理(无效访问),仲裁(多个访问相同内存的设备)和路由之类的东西(CPU可能希望访问多个多个内存设备)。为了处理此问题,使用A BUS协议。
要写或读取外部存储器CPU必须启动A 交易。它的确切顺序是由使用的总线协议定义的,但通常涉及以下步骤:
- 发送转移地址,类型,长度等。
- 接收响应 - 允许或拒绝(总线错误)。
- 如果允许交易传输实际数据。
启动转移的设备称为 master 或启动器,而负责处理交易的设备称为 slave 或目标。
确定从属处理事务的设备称为解码器或路由器。因此,交易通常会从主转到解码器,然后再到从设备。
总线协议当然提供了一种将数据传输到设备或从设备传输的方法。该设备可以是存储设备或其他任何设备。对于存储设备,其控制器通过编写或从内存单元格数字编写或读取数据来处理转换。
如果您熟悉面向对象的编程,则可以通过接口来考虑CPU连接到外部设备, 允许在指定地址读取和写作。该接口的实现可以做任何事情。这是完成内存映射I/O的方式 - CPU连接到一堆设备,每个设备都在特定地址范围内接收交易。将数据写入一个地址,将通过存储设备接收该数据,该数据将其存储到内存单元格数组,将数据写入另一个地址,可以通过SD Controller接收,并将其解释为" send send_status命令到SD卡"。
如果您也熟悉现代操作系统,则可以想到"一切都是文件"抽象。有些文件只是普通文件,例如他们充当记忆。其他文件不同。就像在Linux上阅读/proc/cpuinfo
一样,您可以为您提供有关CPU的信息一样,在某些地址上阅读可以为您提供有关IRQ当前正在待处理的信息或告诉您邮箱目前有多少消息的信息。
公交协议的示例是AXI和AHB。AHB更简单,AXI更复杂,更快。在覆盆子Pi的情况下,很可能是将CPU连接到硬件的AXI协议。
因此,关于您的问题,这两个功能用于通过内存映射的I/O访问外部设备的寄存器。您正确正确的一切:
-
volatile
用于防止编译器删除,重新排序或以任何方式更改这些内存访问 - 没有此硬件将无法执行我们想要的操作。 -
u32
之所
(unsigned int *)
是一种铸造到unsigned int
指针的类型。取消运算符*
用于访问该指针指向的内存位置。
- 无法将结构注册为增强几何体3D点
- 如何使用AngelScript注册SFML Vector2运算符
- 在遍历处理程序的向量时注册和注销处理程序
- 有没有任务栏API可以立即应用注册表更改
- 使用QJsEngine在Qt中注册自定义类型
- 检查注册表项是否链接到(或副本)另一个注册表项
- 如何使用 TStyleManager::UnRegisterStyle() 取消注册样式
- WINAPI 注册应用程序重新启动时不清除打开的套接字
- SFML 碰撞永远不会在我的系统中注册
- 尝试从C++访问 UWP 的电子邮件邮件类会导致"REGDB_E_CLASSNOTREG类未注册"错误
- 用于创建/注册虚拟存储设备的 IOKit 驱动程序
- 如何添加预防措施以绕过未注册Microsoft.ACE.OLEDB.12.0?
- 为什么两个矢量元素的地址有这么大的差距?
- 进程外 EXE 的免注册 COM
- 如何注册Qt C++对象以在QML中使用它
- 在Qt中注册自定义元类型的别名类型
- 禁用地址共享注册表不起作用
- 如何从注册表项中提取配置单元和注册表名称
- C++库和自注册类:客户端应用程序中的工厂映射为空
- 固定有关C/C 的知识差距并注册访问