mmap 和访问 ARM 处理器中的 GPIO 配置寄存器
我正在努力从 Linux 用户空间读取(和写入)硬件寄存器。目标是配置一些 GPIO 引脚并能够设置和读取这些引脚。
根据处理器(飞思卡尔的 imx27)的规范,控制 GPIO 的寄存器组的物理地址是 0x10015000
我的假设是我可以使用这样的东西:
unsigned long *gpio;
fd = open("/dev/mem", O_RDWR);
gpio = (unsigned long *) mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x10015000);
我现在期望能够读取数据并将数据设置到寄存器中处理器。问题是,无论我读取哪个位置,我总是得到 0。
例如,物理位置 0x10015220 中的寄存器包含一个寄存器,显示哪些引脚在我们中作为 GPIO。默认为 0xFFFFFFFF。读取此寄存器时,我预计会得到与 0 不同的内容:
printf("PTC_GIUS: 0x%08lX\n", gpio[0x220]);
给出 PTC_GIUS: 0x00000000
。
我哪里出错了?
Im struggling to read(and write) to HW registers from Linux user space. The goal is to configure some GPIO pins from and be able to set and read this pins.
According to the spec for the processor(imx27 from Freescale) the physical address for the register bank controlling GPIO this is 0x10015000
My assumption was that I could use something like this:
unsigned long *gpio;
fd = open("/dev/mem", O_RDWR);
gpio = (unsigned long *) mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x10015000);
I now expected to be able to read and set data to the registers in the processor. The problem is that it does not matter which location I read, I always get 0.
For example register in physical location 0x10015220 contains a register showing which pins are in us as GPIO. This Defaults to 0xFFFFFFFF. Reading this register I expected to get something different than 0:
printf("PTC_GIUS: 0x%08lX\n", gpio[0x220]);
gives PTC_GIUS: 0x00000000
.
Where am I going wrong ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
/dev/mem
上的mmap
应该可以工作。您是否尝试过以 root 身份运行代码?也许某些安全措施正在阻止您的程序访问地址空间。还要确保您传递了 GPIO 空间的正确物理地址。您使用的方法可以在我运行 Linux 的 Cortex-A8 ARM 板上运行,没有任何问题。
如果你不能让它工作,除了为 gpio 找到或编写一个设备驱动程序之外,你无能为力(顺便说一句,编写一个设备驱动程序并不难)。
幸运的是,有人已经为你做到了这一点。您的文件系统中是否存在名为
/dev/gpio
的节点?如果是这样,您已经有司机了。在
/dev/gpio
上进行谷歌搜索将为您提供有关如何使用它的所有详细信息。您还可以找到简单的 GPIO 驱动程序的源代码,您可以对其进行修改以满足您的需要。The
mmap
on/dev/mem
should work. Have you tried running your code as root? Maybe some security is preventing your program from accessing the address-space. Also make sure you've passed the correct physical address of your GPIO-Space.The approach you've used works on my Cortex-A8 ARM-board running linux without problems.
If you can't get it working there is not much you can do except finding or writing a device-driver for the gpio (writing one is not that hard btw.).
With a bit of luck someone already did that for you. Does a node named
/dev/gpio
exist in your filesystem? If so you already have a driver.A google search on
/dev/gpio
will give you all details on how to use it. You may also find the source for a simple gpio driver that you can modify to suit your needs.另外,如果您使用 2009 年及之后的内核源代码,并且希望内存访问权限设置为
O_SYNC
标志,则应打开/dev/mem
不被缓存。Also, if you're using a kernel source code from 2009 and on, you should open
/dev/mem
with theO_SYNC
flag set, if you want your memory access to be uncached.如果您使用的是最新版本的 Linux 内核,它可能会阻止对
/dev/mem
设备的访问。对该设备的用户模式访问已被弃用且危险。它主要用于用户模式访问 X 中的视频内存。在嵌入式项目中,访问内存映射硬件(如 GPIO)非常有用。检查内核编译标志的
CONFIG_STRICT_DEVMEM
或限制访问/dev/mem
的其他标志。它可能会错误地阻止对此内存范围的访问。然而,正如 Nils 提到的,最好的解决方案是为 iMX27 找到一个 GPIO 模块或编写自己的模块。
If you are using a recent version of the Linux kernel it may be blocking access to the
/dev/mem
device. User mode access to that device is deprecated and dangerous. It is used mainly for user mode access to video memory within X. In embedded projects it can be useful to have access to memory mapped hardware (like GPIO).Check your Kernel compile flags for
CONFIG_STRICT_DEVMEM
or other flags that restrict access to/dev/mem
. It could be mistakenly blocking access to this memory range.However, as Nils mentioned the best solution is to find a gpio module for the iMX27 or write your own.