在FriendlyARM板mini2440中编程GPIO的最佳方式是什么

Which is the best way for programming GPIOs in FriendlyARM board mini2440?

本文关键字:最佳 方式 是什么 GPIO 编程 FriendlyARM mini2440      更新时间:2023-10-16

我有一个带Linux 2.6的mini2440板,我必须在上面编程来控制安装的太阳能电池板。算法已经提供,我需要为ARM板编写代码。GUI是在Qt中完成的,我需要一个来编写实际控制的代码。我看到了从用户空间访问GPIO的方法,它很乏味。我质疑PWM的准确性。

我还可以使用哪些方法来为开/关和PWM应用程序编程GPIO?

一些朋友建议将控制代码编程为内核模块,但我不太确定我是否愿意跳进去。

一些朋友建议将控制代码编程为内核模块,但我不太确定我是否愿意跳进去。

我几乎可以肯定,如果它与硬件无关,它在Linux内核中会被拒绝。用户空间syscall和sysfs访问的目的是将您的自定义逻辑放在硬件抽象(OSI模型)之上的Linux中。

您需要做的是首先检查Linux内核是否为您的设备提供了所有硬件支持。然后你可以使用我的中间件类以C++的方式控制GPIO。最后,您可以编写一个小型主应用程序来测试内核和C++类。该应用程序只需要做一些简单的事情,比如实例化GPIO类,导出GPIO,然后写入值。

(这与您的PWM问题有何关系尚不清楚,但您似乎混淆了两个不同的内核驱动程序领域)

您可以根据Linux内核gpio文档通过sysfs执行类似于下面代码的操作。当然,您需要确保您的硬件gpio受到Linux内核的支持。

gpio.h

#ifndef FOOBAR_GENERALPURPOSEIO_H
#define FOOBAR_GENERALPURPOSEIO_H
namespace Foobar
{
class FOOBAR_EXPORT GeneralPurposeIO
{
public:
enum Direction {
Input,
Output
};
explicit GeneralPurposeIO(quint32 gpioNumber = 0);
~GeneralPurposeIO();
int gpioExport();
int gpioUnexport();
bool isGpioExported();
quint32 gpioNumber() const;
void setGpioNumber(quint32 gpioNumber);
Direction direction() const;
int setDirection(Direction direction);
qint32 value() const;
int setValue(qint32 value);
private:
class Private;
Private *const d;
};
}
#endif // FOOBAR_GENERALPURPOSEIO_H

gpio.cpp

#include "generalpurposeio.h"
#include <QtCore/QDebug>
#include <QtCore/QFile>
using namespace Foobar;
class GeneralPurposeIO::Private
{
public:
Private()
{
}
~Private()
{
}
static const QString gpioExportFilePath;
static const QString gpioUnexportFilePath;
static const QString gpioDirectionFilePath;
static const QString gpioValueFilePath;
static const QString gpioFilePath;
quint32 gpioNumber;
};
const QString GeneralPurposeIO::Private::gpioExportFilePath = "/sys/class/gpio/export";
const QString GeneralPurposeIO::Private::gpioUnexportFilePath = "/sys/class/gpio/unexport";
const QString GeneralPurposeIO::Private::gpioDirectionFilePath = "/sys/class/gpio/gpio%1/direction";
const QString GeneralPurposeIO::Private::gpioValueFilePath = "/sys/class/gpio/gpio%1/value";
const QString GeneralPurposeIO::Private::gpioFilePath = "/sys/class/gpio/gpio%1";
GeneralPurposeIO::GeneralPurposeIO(quint32 gpioNumber)
: d(new Private)
{
d->gpioNumber = gpioNumber;
}
GeneralPurposeIO::~GeneralPurposeIO()
{
}
/*
* Exports the desired gpio number.
*
* Note: Unfortunately, it is not possible to just call this method "export"
* since that is a reserved keyword in C++. Systematically the unexport method
* cannot be called "unexport" either for consistency.
*/
int GeneralPurposeIO::gpioExport()
{
if (isGpioExported()) {
// TODO: Proper error mutator mechanism for storing different error
// enumeration values internally that can be requested by the API user
qDebug() << "Cannot export the gpio pin since it is already exported:" << d->gpioNumber;
return -1;
}
QFile gpioExportFile(d->gpioExportFilePath);
if (!gpioExportFile.open(QIODevice::Append)) {
qDebug() << "Cannot open the gpio export file:" << d->gpioExportFilePath;
return -1;
}
/*
* Seek to begining of the file
*/
gpioExportFile.seek(0);
/*
* Write our value of "gpioPinNumber" to the file
*/
if (gpioExportFile.write(QByteArray::number(d->gpioNumber)) == -1) {
qDebug() << Q_FUNC_INFO << "Error while writing the file:" << d->gpioExportFilePath;
gpioExportFile.close();
return -1;
}
gpioExportFile.close();
return 0;
}
int GeneralPurposeIO::gpioUnexport()
{
if (!isGpioExported()) {
// TODO: Proper error mutator mechanism for storing different error
// enumeration values internally that can be requested by the API user
qDebug() << "Cannot unexport the gpio pin since it is not exported yet:" << d->gpioNumber;
return -1;
}
QFile gpioUnexportFile(d->gpioUnexportFilePath);
if (!gpioUnexportFile.open(QIODevice::Append)) {
qDebug() << "Cannot open the gpio export file:" << d->gpioUnexportFilePath;
return -1;
}
/*
* Seek to begining of the file
*/
gpioUnexportFile.seek(0);
/*
* Write our value of "gpioPinNumber" to the file
*/
if (gpioUnexportFile.write(QByteArray::number(d->gpioNumber)) == -1) {
qDebug() << Q_FUNC_INFO << "Error while writing the file:" << d->gpioUnexportFilePath;
gpioUnexportFile.close();
return -1;
}
gpioUnexportFile.close();
return 0;
}
bool GeneralPurposeIO::isGpioExported()
{
if (!QFile(d->gpioFilePath.arg(d->gpioNumber)).exists()) {
return false;
}
return true;
}
quint32 GeneralPurposeIO::gpioNumber() const
{
return d->gpioNumber;
}
void GeneralPurposeIO::setGpioNumber(quint32 gpioNumber)
{
d->gpioNumber = gpioNumber;
}
GeneralPurposeIO::Direction GeneralPurposeIO::direction() const
{
// TODO: Implement me
return GeneralPurposeIO::Output;
}
int GeneralPurposeIO::setDirection(Direction direction)
{
if (!isGpioExported()) {
if (gpioExport() == -1) {
return -1;
}
}
/*
* Set the direction
*/
QFile gpioDirectionFile(d->gpioDirectionFilePath.arg(d->gpioNumber));
if (!gpioDirectionFile.open(QIODevice::ReadWrite)) {
qDebug() << "Cannot open the relevant gpio direction file:" << d->gpioDirectionFilePath;
return -1;
}
int retval = 0;
/*
* Seek to begining of the file
*/
gpioDirectionFile.seek(0);
switch (direction) {
case Output:
if (gpioDirectionFile.write("high") == -1) {
qDebug() << Q_FUNC_INFO << "Error while writing the file:" << d->gpioDirectionFilePath;
retval = -1;
}
break;
case Input:
if (gpioDirectionFile.write("low") == -1) {
qDebug() << Q_FUNC_INFO << "Error while writing the file:" << d->gpioDirectionFilePath;
retval = -1;
}
break;
default:
break;
}
gpioDirectionFile.close();
return retval;
}
qint32 GeneralPurposeIO::value() const
{
// TODO: Implement me
return 0;
}
int GeneralPurposeIO::setValue(qint32 value)
{
if (direction() != GeneralPurposeIO::Output) {
qDebug() << "Cannot set the value for an input gpio pin:" << d->gpioNumber;
return -1;
}
/*
* Set the value
*/
QFile gpioValueFile(d->gpioValueFilePath.arg(d->gpioNumber));
if (!gpioValueFile.open(QIODevice::ReadWrite)) {
qDebug() << "Cannot open the relevant gpio value file:" << d->gpioValueFilePath.arg(d->gpioNumber);
gpioValueFile.close();
return -1;
}
/*
* Seek to begining of the file
*/
gpioValueFile.seek(0);
if (gpioValueFile.write(QByteArray::number(value)) == -1) {
qDebug() << Q_FUNC_INFO << "Error while writing the file:" << d->gpioValueFilePath.arg(d->gpioNumber);
gpioValueFile.close();
return -1;
}
gpioValueFile.close();
return 0;
}