【问题标题】:Handle GPIO in User Space ARM9 Embedded Linux AM1808处理用户空间 ARM9 嵌入式 Linux AM1808 中的 GPIO
【发布时间】:2013-03-26 10:19:31
【问题描述】:

我必须将我的 GSM 模块与基于 ARM9 的 AM1808 接口。

我已将所有 GPIO 引脚分配给 Da850.c 以及 mux.h 文件。我成功创建了一个 uImage 并将该图像插入到我的闪存中。

我需要处理来自用户应用程序的一些 GPIO。

我知道我们可以从 Kerel 空间处理 GPIO,但我需要从用户空间处理。

例如,我为 GSM 模块的电源键分配了一个 GPIO。我需要通过应用程序更改引脚方式(HIGH 或 LOW)。

好的,我已经编写了以下代码来从用户空间访问它,

#include <stdio.h>
#include <time.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>
#include "GSMpwr.h"
#define BS_GSM_PWR_REGISTER 0x01E26014
#define BS_DCDS_MASK    0x00000004

int fd;  // Memory device descriptor
unsigned long *pPWR;

unsigned short GetGSMpwr(void)
{
    #if defined __HOST_ARM
    unsigned long dcd_value = *pPWR;
    return (pwr_value >> 7) & 0x01;
    #endif
}

void InitializeGSMpwr(void) 
{
    #if defined __HOST_ARM
    int page_size = getpagesize();
    unsigned int MAP_addr;
    unsigned int reg_addr;
    unsigned char *pTemp;             // Pointer to GSMpwr register

/*
 * Open memory and get pointer to GSMpwr register in the FPGA
 */

if((fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0)
{
        printf("failed to open /dev/mem");
        return;
}
else
{
    MAP_addr = (BS_GSM_PWR_REGISTER & ~(page_size - 1));
    pTemp = (unsigned char *)mmap(NULL, page_size,(PROT_READ |      PROT_WRITE),MAP_SHARED,fd,MAP_addr);

    if((pTemp == MAP_FAILED) || (pTemp == NULL))
    {
        printf("failed to map /dev/mem");
        return;
    }
    else
    {
    printf(“Memory Mapped at Address %p. \n”,pTemp);
    }

virt_addr = map_base + (control & MAP_MASK);



    reg_addr = (BS_GSM_PWR_REGISTER & (page_size - 1));
    pPWR = (unsigned long*)(pTemp + reg_addr);
    printf("GSM PWR PIN mapped in Application\n");
}

我只能通过此代码读取该引脚,现在我想将该引脚用作输出,并希望以 3 秒的时间间隔变高和变低。

【问题讨论】:

  • 我的回答很清楚,但是,您选择了不同的方法,不正确。这在用户空间不起作用,因为您的进程有自己的寻址空间。

标签: embedded arm embedded-linux


【解决方案1】:

最简单的方法是利用sysfs 中的 GPIO 支持,您可以在其中控制所有导出的 GPIO。请查看 Linux kernel GPIO documentation,特别是 Sysfs Interface for Userspace 部分。

sysfs (GPIO_SYSFS) 中启用 GPIO 支持后,GPIO 控制将很简单:

示例

GPIO=22

cd /sys/class/gpio
ls
echo $GPIO > /sys/class/gpio/export
ls

在第一个 ls 中注意 gpio22 不存在,但在您将 GPIO 22 导出到用户空间后会存在。

cd /sys/class/gpio/gpio$GPIO
ls

有文件可以设置方向和检索当前值。

echo "in" > direction
cat value

您可以配置 GPIO 进行输出,也可以设置值。

echo "out" > direction
echo 1 > value

示例取自here

【讨论】:

    【解决方案2】:

    我知道了,请找到以下代码,我得到了特定的 pin 地址,并且我已经访问了该 pin,例如,

    unsigned short   GetGSMpwr(void)
     {
        unsigned long pwr_value = *pPWR;
        printf("GSM_PWR:check Start : %ld",pwr_value);
    return (pwr_value >> 1) & 0x01;
     }
    
     unsigned short SetGSMpwr(void)
    {
        unsigned long pwr_value = *pPWR;
        printf("GSM_PWR:check Start : %ld",pwr_value);
       *pPWR = ~((pwr_value >> 1) & 0x01);
    }
    
    unsigned short ClrGSMpwr(void) 
    {
        unsigned long pwr_value = *pPWR;
        printf("GSM_PWR:check Start : %ld",pwr_value);
       *pPWR = 256;
    }`
    

    【讨论】:

    • 我的回答非常清楚,可以涵盖您的特定问题。如果您有另一个不包括原始问题的问题 - 请创建一个单独的问题。不要将答案发布为 cmets 和/或问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多