根据规范,我知道以下信息:
JGPIO1 PIN# :10
SoC GPIO # : 71
USE select: IO 0x532[7] ( 0 = native function, 1 = GPIO )
IO select: IO 0x536[7] (0 = output, 1 = input )
Level: IO 0x540[7] ( 0 = low, 1= high )
在这种情况下,我想编写GPIO引脚#10。我可以参考任何示例或示例代码吗?
我可以通过RW-everything [1]做到这一点。但是,这是在Windows中。
我想在C和Linux环境中这样做。
请指教。
=============================================== ================
例如,如果我想设置
0x532的第7位到1
第0x536位的第7位为0
0x540处的第7位到1位。
答案 0 :(得分:2)
在Linux用户空间中,用于访问GPIO的典型方法是通过 / sys 伪文件系统(也称为sysfs)。这提供了一个有点便携的接口,试图最小化硬件依赖性并避免与设备驱动程序冲突。
要确定要在电路板上访问的GPIO编号,您必须查阅SoC文档。 / sys / class / gpio / 中的目录名称需要使用其硬件寄存器对应项进行标识。这些目录名称的格式为 gpiochip N,其中N表示该寄存器中的基本GPIO号。文件 gpiochipN / label 应该有助于识别寄存器,例如通过其(内存或端口)地址。
请注意,N可能不会以0开头。英特尔BayTrail系统可能将 gpiochip82 作为其第一个目录,因此编号最小的GPIO将为82.应添加寄存器的位数到基数以获得GPIO号。
有关正式文件,请参阅Documentation/gpio/sysfs.txt。
我可以通过RW-everything 1做到这一点。但是,这是在Windows中。
可能会编写类似的程序以在Linux下执行。然而,Linux程序(不同于以x86为中心的Windows)应该可以移植到其他架构,因此这种需要了解低级硬件细节的程序几乎不可能编写/维护。设备驱动程序的一个目的是隔离/模块化这些硬件细节,这样的程序试图绕过这些驱动程序!
此外,使用此类程序可能会导致系统不稳定或出现故障。在运行的系统上使用内存和/或设备寄存器是不安全的。 FWIW我编写了一个实用程序,报告一个特定SoC的引脚配置,但只有读取寄存器,从不修改任何设置。
请注意,大多数SoC文档(以及Linux)将引脚控制/配置视为与GPIO分离(但密切相关,如果不重叠)的子系统。引脚控制/配置通常包括:
GPIO子系统通常处理:
答案 1 :(得分:0)
许多嵌入式板都支持EAPI库-“嵌入式应用程序编程接口”。基本规范是由PICMG开发的。 Here's the doc.
如果您想通过用户空间程序控制和/或检测GPIO引脚,此API可能会为您提供最简单,最快的解决方案。
下面是使用EAPI打开/关闭任意GPO引脚的代码片段。 (设备本身的引脚号通常与板上接头连接器上的引脚号不匹配,因此您需要转换“外部”与“内部”引脚号。
bool
DvmA44I2CGPI::setOutput(int pinNum, bool pinOn)
{
if (pinNum > NUMPINS)
return false;
bool pinPhyVal = (mReversePolarity) ? !pinOn : pinOn;
uint32_t val = (pinPhyVal) ? EAPI_GPIO_HIGH : EAPI_GPIO_LOW;
uint32_t inputs, outputs;
EApiStatus_t rc;
if ((rc = EApiGPIOGetDirectionCaps(EAPI_ID_GPIO_BANK00, &inputs, &outputs)) != EAPI_STATUS_SUCCESS)
{
fprintf(stderr, "EApiGPIOGetDirectionCaps() Get Direction Failed: ");
printStatus(rc);
return false;
}
if ((rc = EApiGPIOSetLevel(mPinMap[pinNum-1], outputs, val)) != EAPI_STATUS_SUCCESS)
{
fprintf(stderr, "EApiGPIOSetLevel() Set Level Failed: ");
printStatus(rc);
return false;
}
return true;
}