3

我正在编写一个简单的程序来设置和清除一个引脚(目的是将该引脚用作自定义 spi_CS)。我能够导出该引脚(gpio1_17,端口 9 引脚 23 bb 白色)并通过文件系统使用它,但我必须更快地驱动它。

这是代码:

uint32_t *gpio;

int fd = open("/dev/mem", O_RDWR|O_SYNC);
if (fd < 0){
    fprintf(stderr, "Unable to open port\n\r");
    exit(fd);
}

gpio =(uint32_t *) mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO1_offset); // start of GPIOA

if(gpio == (void *) -1) {
    printf("Memory map failed.\n");
    exit(0);
} else {
    printf("Memory mapped at address %p.\n", gpio);
}

printf("\nGPIO_OE:%X\n",gpio[GPIO_OE/4]);
gpio[GPIO_OE/4]=USR1;
printf("\nGPIO_OE:%X\n",gpio[GPIO_OE/4]);

printf("\nGPIO_CLEARDATAOUT:%X\n",gpio[GPIO_CLEARDATAOUT/4]);
gpio[GPIO_CLEARDATAOUT/4]=USR1;
printf("\nGPIO_CLEARDATAOUT:%X\n",gpio[GPIO_CLEARDATAOUT/4]);


sleep(1);

printf("\nGPIO_SETDATAOUT%X\n",gpio[GPIO_SETDATAOUT/4]);
gpio[GPIO_DATAOUT/4]=USR1;
printf("\nGPIO_SETDATAOUT%X\n",gpio[GPIO_SETDATAOUT/4]);

#define GPIO1_offset  0x4804c000
#define GPIO1_size  0x4804cfff-GPIO1_offset
#define GPIO_OE  0x134
#define GPIO_SETDATAOUT  0x194
#define GPIO_CLEARDATAOUT  0x190
#define GPIO_DATAOUT 0x13C
#define USR1  1<<17

我能够输出启用该引脚,因为如果我在运行程序之前将其设置为高电平,则该 ping 会变为低电平。但我无法设置和重置它。有任何想法吗?

4

1 回答 1

-1

为什么直接修改寄存器?将它用作 linux GPIO 会更容易:

#define GPIO_1_17                  "49"                        

int gpio;
status_codes stat = STATUS_SUCCESS;

//Export our GPIOs for use
if((gpio = open("/sys/class/gpio/export", O_WRONLY)) >= 0) {
    write(gpio, GPIO_1_17, strlen(GPIO_1_17));
    close(gpio);
} else {
    stat = STATUS_GPIO_ACCESS_FAILURE;
    break;
}

//Set the direction and pull low
if((gpio = open("/sys/class/gpio/gpio" GPIO_1_17 "/direction", O_WRONLY)) >= 0) {
    write(gpio, "out", 3);  // Set out direction
    close(gpio);
} else {
    stat = STATUS_GPIO_ACCESS_FAILURE;
    break;
}
if((gpio = open("/sys/class/gpio/gpio" GPIO_1_17 "/value", O_WRONLY)) >= 0) {
    write(gpio, "0", 1);    // Pull low
    close(gpio);
} else {
    stat = STATUS_GPIO_ACCESS_FAILURE;
    break;
}

然后只需确保它在您的 init 中被复用为 gpio。

就您上面提到的 mmap 方法而言,您的地址看起来是正确的。参考手册中的地址是字节地址,并且您使用的是 32 位指针,因此您所拥有的内容是正确的。但是,这条线:gpio[GPIO_OE/4]=USR1 使 GPIO1 上的每个引脚都成为输出,除了 17 之外,它作为输入(0 = 输出和 1 = 输入)。你可能是这个意思:gpio[GPIO_OE/4] &= ~USR1

我也相信你的意思是 gpio[GPIO_SETDATAOUT/4]=USR1; 而不是 gpio[GPIO_DATAOUT/4]=USR1; 它们都会导致 GPIO1_17 被设置;但是,使用您所拥有的也将 GPIO1 上的所有其他引脚设置为 0。

我肯定会推荐使用设计的内核接口,因为也由内核控制的映射东西可能会自找麻烦。

祝你好运!:)

编辑: 我的错误刚刚意识到你说你为什么不直接通过文件系统驱动它,因为你需要更快地驱动它!您可能还需要考虑编写/修改 SPI 驱动程序,以便在您追求速度的情况下在内核领域完成这些工作。omap gpio 接口在那里也很容易使用,只需请求和设置:)。

于 2015-06-09T12:42:09.727 回答