对FINTEK F81866A芯片组上的GPIO引脚进行编程 [英] Programming GPIO pins on a FINTEK F81866A chipset

查看:520
本文介绍了对FINTEK F81866A芯片组上的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),但是我真的很难理解它的实际工作原理.我已经理解了逻辑(选择地址并向其读取/写入十六进制值),但是我无法弄清楚WriteByte()ReadByte()是什么类型的C指令.另外,我不明白ReadByte(DataPort, Value)行中的Value的来源.它应该一起读取4个PIN,因此应该是某种字节"类型,并且在其4-7位中应包含1,但是我仍然无法真正理解该行的含义.

我找到了类似芯片的答案,但是它没有帮助我理解.

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

解决方案

该芯片看起来很典型 超级I/O 控制器,基本上是所有慢速"外围设备都组合到单个芯片组中的集线器.

Coreboot有一个Wiki页面,该页面讨论如何访问超级I/O . /p>


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

幸运的是,在Linux中这很容易.查看 outb和朋友的手册页.

您使用ioperm(2)或iopl(2)告诉内核允许用户空间应用程序访问有问题的I/O端口.否则,将导致应用程序收到分段错误.

因此我们可以将您的功能调整到这样的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访问;将其中之一移植到您的平台应该很简单.请参见对IT87xx芯片组的拉取请求.

I have a Cincoze DE-1000 industrial PC, that features a Fintek F81866A chipset. I have to manage the DIO pins to read the input from a phisical button and to set on/off a LED. I have experience in C++ programming, but not at low/hardware level.

On the documentation accompanying the PC, there is the following C code:

#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)

As far as I understood, the above code should read the value of the four input PINs (so it should read 1 for each PIN), but I am really struggling to understand how it actually works. I have understood the logic (selecting an address and reading/writing an hex value to it), but I cannot figure out what kind of C instructions WriteByte() and ReadByte() are. Also, I do not understand where Value in the line ReadByte(DataPort, Value) comes from. It should read the 4 PINs all together, so it should be some kind of "byte" type and it should contain 1 in its bits 4-7, but again I cannot really grasp the meaning of that line.

I have found an answer for a similar chip, but it did not help me in understanding.

Please advice me or point me to some relevant documentation.

解决方案

That chip looks like a fairly typical Super I/O controller, which is basically the hub where all of the "slow" peripherals are combined into a single chipset.

Coreboot has a wiki page that talks about how to access the super I/O.


On the PC architecture, Port I/O is accomplished using special CPU instructions, namely in and out. These are privileged instructions, which can only be used from a kernel-mode driver (Ring 0), or a userspace process which has been given I/O privileges.

Luckily, this is easy in Linux. Check out the 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.

So we could adapt your function into a Linux environment like this:

/* 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 */
}

Warning

You should be very careful when using this method to talk directly to the Super IO, because your operating system almost certainly has device drivers that are also talking to the chip.

The right way to accomplish this is to write a device driver that properly coordinates with other kernel code to avoid concurrent access to the device.

The Linux kernel provides GPIO access to at least some Super I/O devices; it should be straightforward to port one of these to your platform. See this pull request for the IT87xx chipset.

这篇关于对FINTEK F81866A芯片组上的GPIO引脚进行编程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆