c - 对 FINTEK F81866A 芯片组上的 GPIO 引脚进行编程

标签 c gpio

我有一个 Cincoze DE-1000工业 PC,具有 Fintek F81866A芯片组。我必须管理 DIO 引脚才能从物理按钮读取输入并设置开/关 LED。我有 C++ 编程的经验,但不是低级/硬件级的。

在 PC 随附的文档中,有以下 C 代码:

#define AddrPort 0x4E
#define DataPort 0x4F

//<Enter the Extended Function Mode>
WriteByte(AddrPort, 0x87)
WriteByte(AddrPort, 0x87) //Must write twice to entering Extended mode

//<Select Logic Device>
WriteByte(AddrPort, 0x07)
WriteByte(DataPort, 0x06)
//Select logic device 06h

//<Input Mode Selection> //Set GP74 to GP77 input mode
WriteByte(AddrPort, 0x80) //Select configuration register 80h
WriteByte(DataPort, 0x0X)
//Set (bit 4~7) = 0 to select GP 74~77 as Input mode.

//<input Value>
WriteByte(AddrPort, 0x82) // Select configuration register 82h
ReadByte(DataPort, Value) // Read bit 4~7(0xFx)= GP74 ~77 as High.

//<Leave the Extended Function Mode>
WriteByte(AddrPort, 0xAA)

据我了解,上面的代码应该读取四个输入 PIN 的值(所以它应该为每个 PIN 读取 1),但我真的很难理解它是如何工作的。我已经理解了逻辑(选择一个地址并读取/写入一个十六进制值),但我无法弄清楚什么样的 C 指令 WriteByte()ReadByte()是。另外,我不明白Value在哪里在线ReadByte(DataPort, Value)来自。它应该一起读取 4 个 PIN,所以它应该是某种“字节”类型,并且它的第 4-7 位应该包含 1,但我再次无法真正理解该行的含义。

我找到了一个 answer for a similar chip ,但这并没有帮助我理解。

请给我建议或指向我一些相关的文档。

最佳答案

那个芯片看起来很典型Super I/O controller ,它基本上是所有“慢”外围设备组合成单个芯片组的集线器。

Coreboot 有一个关于 how to access the super I/O 的 wiki 页面。 .

在PC架构上,端口I/O是通过特殊的CPU指令完成的,即inout .这些是特权指令,只能从内核模式驱动程序(Ring 0)或已被授予 I/O 权限的用户空间进程中使用。

幸运的是,这在 Linux 中很容易。查看 man page for outb and friends .

You use ioperm(2) or alternatively iopl(2) to tell the kernel to allow the user space application to access the I/O ports in question. Failure to do this will cause the application to receive a segmentation fault.



因此,我们可以将您的功能调整到这样的 Linux 环境中:
/* Untested: Use at your own risk! */
#include <sys/io.h>
#include <stdio.h>

#define ReadByte(port)          inb(port)
#define WriteByte(port, val)    outb(val, port)

int main(void)
{
    if (iopl(3) < 0) {
        fprintf(stderr, "Failed to get I/O privileges (are you root?)\n");
        return 2;
    }


    /* Your code using ReadByte / WriteByte here */
}

警告

在使用这种方法直接与 Super IO 对话时,您应该非常小心,因为您的操作系统几乎肯定有设备驱动程序也在与芯片对话。

实现这一点的正确方法是编写一个与其他内核代码正确协调的设备驱动程序,以避免并发访问设备。

Linux 内核至少提供对一些 super I/O 设备的 GPIO 访问;将其中之一移植到您的平台应该很简单。见 this pull request for the IT87xx chipset .

关于c - 对 FINTEK F81866A 芯片组上的 GPIO 引脚进行编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52670521/

相关文章:

c - 将字符串的第一个字节存储到另一个字符串中 : algorithm of LZW Compression

C++11 及更高版本 : shared_ptr for managing system resources provided by a low-level C library

c - STM32F103 GPIO 端口

c - 我的 C 程序无法检测乘号

c++ - 如何在 C 中制作重复的 ip header ?

c - void 名称(类型名称1,类型名称2,类型名称3[名称1][名称2]);

c - 逐字节打印

Linux 用户空间 GPIO 中断使用 sysfs

function - 什么是 Linux 中的 outb() 函数调用?

bash - 树莓派的 GPIO 命令无法通过 crontab 工作