我有以下寄存器地址:0x18040028。由于我对这些东西很新,我应该如何访问该寄存器地址,更改那一位然后将其写回(所有其他条目应该保持不变)? 我是否需要编写程序,还是可以从终端编写程序?
我在linux(openwrt)
上这样做感谢
答案 0 :(得分:0)
快速而肮脏的方法是尝试从/ dev / mem中删除内存区域。看到这两个问题:
Accessing hardware registers in Linux userspace
Accessing physical address from user space
但是,我不建议您为生产系统执行此操作。更清洁的是编写内核驱动程序。一种选择是编写一个使用ioremap和ioread / iowrite操作的常规内核模块,并通过sysfs公开寄存器。
我认为另一个特别灵活的选择是通过平台支持文件中的platform_device系统公开这些寄存器。
基本上你需要读取值,然后执行:
readvalue |= 1<<1;
然后将值写回寄存器。
答案 1 :(得分:0)
在许多Linux版本中,您可以使用sysfs直接访问GPIO引脚。特别是在openwrt上,它几乎总是暴露出来。
在openwrt设备的终端上,查看该文件夹是否存在:
ls -Al /sys/class/gpio
如果存在,您通常需要导出要访问的特定GPIO引脚。我看了http://www.black-swift.ru/files/AR9331.pdf但无法理解。问题是我不认为该寄存器上的特定引脚是这样暴露的 - 至少我找不到它。我必须在GPIO控制器上挖掘该系统才有机会弄明白。
要激活的 的UART引脚 - GPIO9(RX)和GPIO10(TX)。所以也许这些信息无论如何都会有用。
下面的选项2几乎可以保证工作;在我写完这部分之后,我发现了
根据您的内核版本,您可以直接使用该GPIO#,也可以添加偏移量。 尝试:
cat /sys/class/gpio/gpiochip*/base | head -n1
如果它返回一个数字,那就是偏移量。拿你的GPIO#,添加那个偏移量(以200为例)并将其用作你的GPIO#。
使用您的GPIO编号(无论有无偏移),输入以下内容(仅使用210作为示例; 200偏移,GPIO10)
echo "210" > /sys/class/gpio/export
然后GPIO引脚将在此目录中公开,再次使用210作为示例,/sys/class/gpio210/
导出后至少会创建两个文件,/sys/class/gpio240/value
和/sys/class/gpio240/direction
您可以使用cat与它们进行交互,例如cat /sys/class/gpio240/value
并使用echo:echo 1 > /sys/class/gpio240/value
在我放在底部的链接中,有很多关于通过sysfs访问gpio的信息。
如果您找到了正确的GPIO#,这将很容易,但如果没有(或者即使您这样做),请使用:
有人已经完成了所有工作。有关如何与该寄存器接口以禁用/启用UART的说明。它需要在名为io的openwrt安装中添加一个包,它们提供了一个切换该位值的脚本。你可以修改它,如果你想要回显,总是将它设置为某个值,等等。它是用bash编写的。
您可以添加脚本的内容或从/etc/rc.local调用脚本本身,它将在每次启动时运行;解决这个问题。
由于你已经知道你有AR9331,你可以删除很多脚本,例如:
#!/bin/bash -
# Bitwise operations: & = And, | = Or, ^ = xOr, << = Left Shift
func_addr="0x18040028"
func_value=0x`io -4 $func_addr | cut -f3 -d'
case_bit="1<<1"
# This is where you would make a change if you wanted to
# just set it to 1 every time.
# To always set it to a '1', change from xor ^ to or |; like this
# io -4 $func_addr $(printf "0x%8.8x" $(($func_value | $case_bit)))
# to always be 0 change the operator to and &, and use a mask
# with just bit 1 set to 0
mask32_b1="0xFFFFFFFD"
# io -4 $func_addr $(printf "0x%8.8x" $(($func_value $ $mask32_b1)))
# we using Bitwise xOr operation to switching bit# state (0 or 1)
io -4 $func_addr $(printf "0x%8.8x" $(($func_value ^ $case_bit)))
# read bit# state and depending on the state - print some info
if [ $(($func_value & $case_bit)) = $(($case_bit)) ]; then
echo "Hardware UART is turned OFF"
# You can use this line for automatic configuring GPIOs via sysfs
# or you can load other modules that use these GPIOs
else
echo "Hardware UART is turned ON"
fi
它可能是一个班轮(相当丑陋):
io -4 "0x18040028" $(printf "0x%8.8x" $(("0x"$((io -4 "0x18040028" | cut -f3 -d )) ^ "0x2")))
我无法测试任何这个,所以我可能在任何地方都犯了错误,但是如果你遵循那个指南,并且将修改设置为总是设置为1(我现在注释掉),那你应该好。确保您只留下一个选项来修改该注册表。
来源/更多信息:
OpenWrt Wiki
Working with GPIOs
Kernel.org