1

我正在尝试在此指令http://41j.com/blog/2011/09/beagleboard-gpio-input-driverless/上学习处理器的扩展头配置

我有一个我无法理解的部分

volatile ulong *pinconf;
pinconf = (ulong*) mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x48000000);
pinconf[0x2168/4] = 0x001C001C;

谁能解释pinconf数组是如何工作的?它存储什么价值?

编辑:我真的不明白是什么pinconf[0x2168/4]意思。它是一个十六进制数组,它指的是什么值?

4

4 回答 4

2

pinconf 是内存映射文件/设备。查看您的链接代码,fd 是新打开的 /dev/mem 的描述符。因此,无论您在 pinconf 数组中写入什么,实际上都是以您在数组中使用的任何偏移量直接写入 /dev/mem。我假设这就是这段代码与 GPIO 硬件“对话”的方式。如果没有 GPIO 设备的内存映射,就很难知道正在写入的地址会发生什么。

看看 / dev/mem是什么。

并阅读有关内存映射 i/o 的信息,这就是它正在做的事情(有点),请参阅:http ://www.kernel.org/doc/htmldocs/uio-howto.html#userspace_driver

于 2012-11-15T13:18:18.880 回答
2

根据您的问题的标题,我认为您对访问数组时的十六进制表示法感到困惑。

十六进制只是另一种写数字的方式,不要让它给你太多。我可以写:

int a = 0xA;

或者

int a = 10;

他们的意思是一样的。所以在这种情况下:

pinconf[0x2168/4] = 0x001C001C;

只是:

pinconf[8552/4] = 1835036;

后者实际上更令人困惑,因为 pinconf 正在存储一个地址,该地址通常使用 4(或 8)个字节以十六进制写入,因此00继续处理其余的数字(1C001C

于 2012-11-15T13:23:31.990 回答
2

我是原始博客/代码作者,这就是我的意思:

为了回答您的主要观点,pinconf[0x2168/4] 指的是地址 0x48002168。pinconf 数组从地址 0x48000000 开始。它被定义为 ulong [1],在 ARM 处理器上为 4 个字节。我知道我想访问地址 pinconf+0x2168。要将地址 0x2168 转换为 pinconf 中的索引,我需要除以 4。


从头开始浏览代码:

volatile ulong *pinconf;

pinconf 被定义为一个 ulong (32bit int) 指针。它被定义为 volatile,这意味着我们代码之外的某些东西可能会改变它的值。它告诉编译器,每次我们使用该值时,我们都需要从内存中读取它,这会阻止编译器进行可能会搞砸的巧妙优化。

pinconf = (ulong*) mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x48000000);

这会将 pinconf 设置为指向地址 0x48000000。通常,您可以执行以下操作:

pinconf = (ulong*) 0x48000000;

使 pinconf 指向一个地址,但这不起作用。0x48000000 是一个受保护的地址,它只能被内核访问。mmap 魔法为您提供了一种从用户空间访问地址的方法。

pinconf[0x2168/4] = 0x001C001C;

我们已经讨论过这个,但这是向地址写入一个值:0x48000000+0x2168。值 0x48002168 来自 OMAP3 数据表,用于与 GPIO 系统进行内存映射 IO。我们除以 4 将地址 0x2168 转换为 pinconf 中的索引。

[1] 老实说,我可能应该使用 uint32_t。

于 2012-11-16T15:47:05.560 回答
1

pinconf 数组存储 ulong(无符号长)。

volatile ulong *pinconf;你定义一个指向 ulong 的指针。它指向数组的第一个元素。它是易失的,这意味着它可能会被外部“事件”更改并且不会被缓存。它可以链接 C 中的任何数组。

在这种情况下,它被映射到具有文件描述符 fd 的文件/设备。

于 2012-11-15T13:16:03.727 回答