This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] AM3358:通过/dev/mem 进行的 BeagleBone Black GPIO 控制不起作用

Guru**** 2539500 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1007036/am3358-beaglebone-black-gpio-control-via-dev-mem-does-not-work

器件型号:AM3358

您好!

我正在尝试通过 BeagleBone Black 上的/dev/mem 控制 GPIO、但它获得了 SIGBUS。
但是、如果执行了一次'echo 117 >/sys/class/gpio/export '命令、则可以正常工作。
这个问题似乎只发生在 GPIO 模块3上。
它应该是行为吗?
我是否需要任何其他程序?

Simplen 复制方案如下。

#define _GNU_SOURCE
#include <inttypes.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <string.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>

#define AM335x_GPIO0_BASE      ((uint32_t *)0x44E07000)
#define AM335x_GPIO1_BASE      ((uint32_t *)0x4804C000)
#define AM335x_GPIO2_BASE      ((uint32_t *)0x481AC000)
#define AM335x_GPIO3_BASE      ((uint32_t *)0x481AE000)
#define GPIO_OE_OFF         (0x134/(sizeof(uint32_t *)))
#define AM335x_GPIO_LEN        ((size_t)0x1000)


const uint32_t *Base_Addrs[] = {AM335x_GPIO0_BASE, AM335x_GPIO1_BASE, AM335x_GPIO2_BASE, AM335x_GPIO3_BASE};
uint32_t *GPIO_Addrs[4]={};

_Bool bbb_gpio_init(void){
    int dev_map;
    if((dev_map = open("/dev/mem", O_RDWR)) < 0){
        perror("open");
        return(1);
    }

    for (uint8_t i=0; i<4; i++){
        if((GPIO_Addrs[i] = mmap(0, AM335x_GPIO_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, dev_map, (off_t)Base_Addrs[i])) == MAP_FAILED){
            fprintf(stderr, "Err: %s: Can not map GPIO register %p\n",__func__, Base_Addrs[i]);
            return(1);
        }
    }
    return(0);
}

int main(void){
    // GPIO configuration
    if(bbb_gpio_init()){
        fprintf(stderr, "Can not initialize bbb_gpio lib");
        exit(EXIT_FAILURE);
    }
    // set gpio3_21 to output
    uint32_t *ptr = GPIO_Addrs[3]+GPIO_OE_OFF;
    *ptr = (*ptr & ~(1<<21));
    return(0);
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    请详细说明您遇到的问题吗? 您在代码中的哪个位置获得了 SIGBUS?

    我在 BeagleBone Black 上试用了您的代码、效果很好。 我没有遇到任何错误。 此外、请参阅 有关 使用/dev/mem 进行 GPIO 控制的示例。  

    此致、

    _________

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jianzhong、

    感谢您的回复。
    看起来像读取*ptr 获得 SIGBUS。

    (gdb)运行
    启动程序:/root/test/c

    程序接收到信号 SIGBUS,总线错误。
    在 c.c:49的 main ()中为0x0040070e
    49         * ptr =(* ptr &~(1<<21));
    (gdb)打印 ptr
    $1 =(uint32_t *) b6ff5134

    此外、我注意到当应用程序获得 SIGBUS 时、dmesg 上出现以下错误。

    [4293.122577]未处理的故障:在 bb6f30134上的非线性蚀刻(0x1018)上的外部中止
    [4293.130303] PgD = 334963a0
    [4293.133023][b6f30134]* PgD=9b175831、* Pte=481ae103、* ppte=481aaea32

    此致、

    YUI

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yui、

    我使用最新的 Debian 映像(beagleboard.org/latest-images)在 BBB 上试用了您的程序、运行良好、没有任何问题。  

    然后、我使用 Processor-SDK Linux 6.3试用了它、并重现了您的问题。 我不确定到底是什么根本原因。 让我就此咨询内部专家、然后再与您联系。

    谢谢、此致、

    _________

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yui、

    我们的 GPIO 问题内部专家本周已结束。 我将于6月11日星期五至6月21日离开。 因此、进一步的响应将延迟。 很抱歉。

    此致、

    _________

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jianzhong、

    好的。 这不是一个紧急问题、因为存在解决方法。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    很抱歉、我们至今未能对此问题进行调查。 我将了解我们是否能够 解决这个问题、并尝试在本周结束前再次与您进行讨论。 否则、 您可能必须执行权变措施。

    此致、

    _________

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yui、

    问题是 GPIO 模块3的时钟未激活、因此无法访问寄存器。 如果不使用该模块、Processor SDK Linux 内核将会选通时钟、这意味着在您的情况下不使用任何 GPIO 模块3引脚。

    当您运行命令'echo 117 >...'时 使 GPIO 3处于活动状态、那么您的程序将正常工作。

    请注意:可以使用/dev/mem 进行程序原型设计、但强烈建议不要将其用于生产、因为它会产生大量问题、例如安全性和内核故障。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Bin、

    在使用 GPIO3之前、我必须启用 GPIO_CTRL 寄存器。 对吧?
    或者,是否要在 dtbo 文件上配置它?

    >请注意:可以使用/dev/mem 进行程序原型设计、但强烈建议不要将其用于生产

    感谢您的建议、但 sysfs GPIO 驱动程序对于我的应用程序来说太慢了。 我计划将地图面积限制在最小值。
    此外、我还学习 PRU 编程、以提高流程效率。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yui、

    很抱歉、我们的回复延迟了。我在 BeagleBone 社区中发现了有关同一问题的讨论: https://groups.google.com/g/beagleboard/c/_Xxpk05npuU/m/_5noVGFSaHkJ。 会上发布了一个解决方案、该解决方案在应用程序代码中启用 GPIO 时钟。

    我尝试过它、但它没有给出总线错误。  请尝试一下。

    此致、

    _________