【问题标题】:getting segmentation fault on a beaglebone black在 beaglebone black 上出现分段错误
【发布时间】:2019-08-11 13:59:12
【问题描述】:

我是 beaglebone 和 linux 的新手,所以对于一个项目,我必须通过使用地址来控制 BBB 上的用户,并通过确保所有 gpio 端口都能够通过这个设置来具有未来使用的功能.但是当我运行它来打开和关闭用户 LED 时,我遇到了分段错误,我不知道为什么或我需要做什么来解决这个问题。我需要包括什么,或者我正在做什么,如果是这样,我应该怎么做?

#include <string.h>
#include <stdint.h>
#include <stdio.h>

typedef struct {
    volatile uint32_t REVISION;         //Address offset: 0x00
    volatile uint32_t rangeA[3];        //Address offset: 0x04-0x0C
    volatile uint32_t SYSCONFIG;        //Address offset: 0x10
    volatile uint32_t rangeB[3];        //Address offset: 0x14-0x1C
    volatile uint32_t EOI;              //Address offset: 0x20
    volatile uint32_t IRQSTATUS_RAW_0;  //Address offset: 0x24
    volatile uint32_t IRQSTATUS_RAW_1;  //Address offset: 0x28
    volatile uint32_t IRQSTATUS_0;      //Address offset: 0x2C
    volatile uint32_t IRQSTATUS_1;      //Address offset: 0x30
    volatile uint32_t IRQSTATUS_SET_0;  //Address offset: 0x34
    volatile uint32_t IRQSTATUS_SET_1;  //Address offset: 0x38
    volatile uint32_t IRQSTATUS_CLR_0;  //Address offset: 0x3C
    volatile uint32_t IRQSTATUS_CLR_1;  //Address offset: 0x40
    volatile uint32_t IRQWAKEN_0 ;      //Address offset: 0x44
    volatile uint32_t IRQWAKEN_1;       //Address offset: 0x48
    volatile uint32_t rangeC[26];       //Address offset: 0x4C-0x110
    volatile uint32_t SYSSTATUS;        //Address offset: 0x114
    volatile uint32_t rangeD[6];        //Address offset: 0x118-0x12C
    volatile uint32_t CTRL;             //Address offset: 0x130
    volatile uint32_t OE;               //Address offset: 0x134
    volatile uint32_t DATAIN;           //Address offset: 0x138
    volatile uint32_t DATAOUT;          //Address offset: 0x13C
    volatile uint32_t LEVELDETECT0;     //Address offset: 0x140
    volatile uint32_t LEVELDETECT1;     //Address offset: 0x144
    volatile uint32_t RISINGDETEDT;     //Address offset: 0x148
    volatile uint32_t FALLINGDETECT;    //Address offset: 0x14C
    volatile uint32_t DEBOUNCENABLE;    //Address offset: 0x150
    volatile uint32_t DEBOUNCINGTIME;   //Address offset: 0x154
    volatile uint32_t rangeE[14];       //Address offset: 0x158-0x18C
    volatile uint32_t CLEARDATAOUT;     //Address offset: 0x190
    volatile uint32_t SETDATAOUT;       //Address offset: 0x194
} GPIO_TypeDef;

#define GPIO0 ((GPIO_TypeDef *) 0x44E07000)
#define GPIO1 ((GPIO_TypeDef *) 0x4804C000)
#define GPIO2 ((GPIO_TypeDef *) 0x481AC000)
#define GPIO3 ((GPIO_TypeDef *) 0x481AE000)

int main()      //testing if this would work
{
    GPIO1->OE &= ~(1UL<<21);       // set  bits to output eneble
    while(1)
    {
        GPIO1->DATAOUT |= 1UL<<21;
        int delay = 0;
        while(delay < 15000)    // just really quick crappy delay
            delay++;
        GPIO1->DATAOUT &= ~(1UL<<21);
        printf("Blink!!\n");    //test to see if it works
    }
    return 0;
}

【问题讨论】:

  • 请在您的散文中添加一些标点符号和大写字母。 (虽然不是我投反对票。)
  • 我对 beagleboards 一无所知,但是您的代码应该如何摆脱 while(1) 循环?你的段错误在哪一行?
  • 我只是 ctrl c 来结束程序,因为这主要是一个测试,看看我是否可以让它按照我的意图写入地址。它只是为了让 LED 闪烁,而它一运行就给了我错误。
  • 我看不出所提供的代码有什么问题.. 你确定struct 和内存地址定义正确吗?
  • 我按照地址和处理器提供的偏移量(AM335x 1GHz ARM® Cortex-A8)参考手册将三次检查地址是否有误。

标签: c


【解决方案1】:

您分配的地址似乎是物理地址或总线地址;您的程序将使用虚拟地址或程序地址运行。您机器上的内核构建翻译页面,因此您的程序可以保持内核可以动态分配的内存地址的规范化视图。

您需要将寄存器的设备空间映射(使用 mmap())到您的程序中,并分配您的结构以指向它们。

您最终应该得到如下代码:

GPIO_TypeDef  *g0, *g1, ... ;
...
g0 = mmap(0, sizeof *g0,..., fd, 0);
...
g0->DataOut = 3;
...

ps:在风格上,前置 _TypeDef 违背了 typedef 机制的目的,即创建有意义的名称和自记录程序。 _t 的 idio(ma)?tic 使用只是稍微好一点,因为它不会浪费这么多的击键。请记住,有些程序员有视力障碍,每次遇到这种情况时都必须听辅助设备说“下划线大写 T y p e 大写 D e f”!

【讨论】:

    猜你喜欢
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 1970-01-01
    • 2014-07-27
    相关资源
    最近更新 更多