Bus error on access to memory mapped GPIO[023]

2,977 views
Skip to first unread message

Jacek Radzikowski

unread,
Jun 11, 2013, 10:41:10 PM6/11/13
to beagleboard
Hello,

I'm getting bus errors whenever my program tries to access registers
controlling pins on GPIOs 0,2 or 3. I'm not trying to set pinmuxing, I
try to write to registers controlling the pins.
GPIO1 works fine and I can enable outputs by writing to the OE
register and change the values on the pins by writing to the OUT
register.

Here are some details of my simple test program:
The base addresses for the GPIO blocks are defined as follows:
const uint32_t gpioAddrs[] =
{ 0x44E07000, 0x4804C000, 0x481AC000, 0x481AE000 };

The memory blocks are mapped to process address space with the following mmap:
gpios[i] = (uint32_t *) mmap(NULL, 0xfff,
PROT_READ | PROT_WRITE, MAP_SHARED, gpioFd, gpioAddrs[i]);

Printing values from OE, IN and OUT registers:
printf("i=%i\n",i);
printf("OUT[%i]=0x%08x\n",i,gpios[i][DATA_OUT_REG/4]);
printf("IN[%i]=0x%08x\n",i,gpios[i][DATA_IN_REG/4]);
printf("OE[%i]=0x%08x\n",i,gpios[i][GPIO_OE_REG/4]);

The full source is on gist:
https://gist.github.com/piranha32/4fd285cc8333eeb4ec39

Program works fine when 'i' is set to 1, crashes for 'i' set to 0,2 or 3.
Am I missing something obvious, or is this an overzealous memory protection?

Board: BBBlack
Kernel: Linux beaglebone 3.8.13 #1 SMP Fri Jun 7 09:49:12 CEST 2013
armv7l GNU/Linux

thx,
j.


--
Given a choice between two theories, take the one which is funnier

Jacek Radzikowski

unread,
Jun 12, 2013, 9:19:14 AM6/12/13
to beagl...@googlegroups.com
On Wed, Jun 12, 2013 at 8:24 AM, Mark Barton <ma...@atldes.com> wrote:
> On 6/11/13 10:41 PM, Jacek Radzikowski wrote:
>>
>> Hello,
>>
>> I'm getting bus errors whenever my program tries to access registers
>> controlling pins on GPIOs 0,2 or 3. I'm not trying to set pinmuxing, I
>> try to write to registers controlling the pins.
[...]
> Not sure if this is your problem, but when I started working with the black
> I noticed that not all clocks were enabled for the GPIO devices. At the time
> I configured the registers directly in my test driver until I am able to get
> a handle on setting them properly using device tree. Here is what I did
> using ioremap:

Did you have to enable the clocks manually even with pinmuxes set on
those pins through device tree?

Mark Barton

unread,
Jun 12, 2013, 10:14:39 AM6/12/13
to beagl...@googlegroups.com
I did this right after I received the board at the
end of last month. I built Angstrom rather than
using the version supplied with the board and at
that time was not familiar enough with DT to know
what it did or did not enable. I manually checked
the clock setting for GPIO0 and GPIO2 and found
they were not enable in that specific version of
Angstrom. I have not had time to see if they are
actually enabled in the latest and greatest
version though.


Jacek Radzikowski

unread,
Jun 12, 2013, 10:53:21 AM6/12/13
to beagl...@googlegroups.com
On Wed, Jun 12, 2013 at 10:14 AM, Mark Barton <ma...@atldes.com> wrote:
> On 6/12/13 9:19 AM, Jacek Radzikowski wrote:
>>
>> On Wed, Jun 12, 2013 at 8:24 AM, Mark Barton<ma...@atldes.com> wrote:
>>>
>>> On 6/11/13 10:41 PM, Jacek Radzikowski wrote:
>>>>
>>>> Hello,
>>>>
>>>> I'm getting bus errors whenever my program tries to access registers
>>>> controlling pins on GPIOs 0,2 or 3. I'm not trying to set pinmuxing, I
>>>> try to write to registers controlling the pins.
>>
>> [...]
>>>
>>> Not sure if this is your problem, but when I started working with the
>>> black
>>> I noticed that not all clocks were enabled for the GPIO devices. At the
>>> time
>>> I configured the registers directly in my test driver until I am able to
>>> get
>>> a handle on setting them properly using device tree. Here is what I did
>>> using ioremap:
>>
>> Did you have to enable the clocks manually even with pinmuxes set on
>> those pins through device tree?
> I did this right after I received the board at the end of last month. I
> built Angstrom rather than using the version supplied with the board and at
> that time was not familiar enough with DT to know what it did or did not
> enable. I manually checked the clock setting for GPIO0 and GPIO2 and found
> they were not enable in that specific version of Angstrom. I have not had
> time to see if they are actually enabled in the latest and greatest version
> though.

I have the most recent version of kernel and only gpio1 works. I did
some experiments with enabling GPIOs with overlays, but with no luck
(setting status to OK, assigning some pins). Do you have an idea what
else can be set in the overlay to enable the modules?
Source of my overlay: https://gist.github.com/piranha32/4abc8312339ad47d32d0

Mark Barton

unread,
Jun 12, 2013, 1:27:47 PM6/12/13
to beagl...@googlegroups.com
Sorry I really don't know. I would have guessed
the clocks are enabled whenever at least one GPIO
port is configured and enabled.

Jacek Radzikowski

unread,
Jun 12, 2013, 1:59:05 PM6/12/13
to beagl...@googlegroups.com
> Sorry I really don't know. I would have guessed the clocks are enabled
> whenever at least one GPIO port is configured and enabled.

That was also my impression, however enabling the ports in device tree
is not sufficient, even using bone-pinmux-helper. After exporting a
pin through /sys/class/gpio/export the associated GPIO starts to work
properly, so application of the overlay does not activate the port.

I'm going to file a bug report but before I'll do that, can anybody
confirm that I'm not missing anything important from the overlays?
Overlay for GPIOs using bone-pinmux-helper:
https://gist.github.com/piranha32/1df4f675c59e50ed3e08
Overlay "ok-ing" gpios: https://gist.github.com/piranha32/4abc8312339ad47d32d0

Luigi Rinaldi

unread,
Jun 13, 2013, 4:42:36 AM6/13/13
to beagl...@googlegroups.com
I had the same problem, I resolved it exporting at least one pin for each GPIO. After that I can access GPIO0, GPIO2 and GPIO3 with mmap.
It's not about pinmux, maybe the problem is the clock.
Try to do this:
# echo 5 > /sys/class/gpio/export
# echo 65 > /sys/class/gpio/export
# echo 105 > /sys/class/gpio/export
You can do it also in C++ or Python.

Luigi Rinaldi.

Igor Borges Tavares

unread,
Nov 18, 2014, 12:50:12 PM11/18/14
to beagl...@googlegroups.com
Luigi very good, I also had this problem, and your solution worked for me also.

But I still do not understand why it is necessary to export at least one pin on each port to be able to access the GPIO with mmap.
Someone can explain me?

Mark Barton

unread,
Jun 12, 2013, 8:24:48 AM6/12/13
to beagl...@googlegroups.com
On 6/11/13 10:41 PM, Jacek Radzikowski wrote:
Jacek,
Not sure if this is your problem, but when I
started working with the black I noticed that not
all clocks were enabled for the GPIO devices. At
the time I configured the registers directly in my
test driver until I am able to get a handle on
setting them properly using device tree. Here is
what I did using ioremap:

/* Global variables of the driver */
#define CM_PER_BASE 0x44e00000
#define CM_WKUP_BASE 0x44e00400
#define GPIO0_CLK_CONFIG_OFFSET 0x8


// Enable GPIO0 Clocks
pCm_wkup_base = ioremap(CM_WKUP_BASE, MMAP_SIZE);
pGpio0_clk_config = pCm_wkup_base +
GPIO0_CLK_CONFIG_OFFSET;
*((volatile unsigned int *)pGpio0_clk_config)
= 2;
iounmap(pCm_wkup_base);

//Enable GPIO2 clocks
pCm_per_base = ioremap(CM_PER_BASE, MMAP_SIZE);
pGpio2_clk_config = pCm_per_base +
GPIO2_CLK_CONFIG_OFFSET;
*((volatile unsigned int *)pGpio2_clk_config)
= 2;
iounmap(pCm_per_base);

HTH,
Mark

Patricia N.

unread,
Jan 22, 2016, 8:00:37 AM1/22/16
to BeagleBoard, igorb...@gmail.com
Hello everyone,

I am a little bit late in this topic, but I would like to share what I have found.
The problem is basically the clock. Once we boot our BBB, clocking systems for GPIO 1, 2 and 3 are disabled (GPIO0 will be always enabled).

We can enable them by:
- Exporting any pin on each port (and then the system enables the clock automatically);
- Modifying and setting some bits in the register CM_PER_GPIOx_CLKCTRL (AM335x Technical Ref Manual - pages 1195, 1196 and 1197).


Some registers from CM_PER (Clock Management - Peripherals) will enable the clock for each module.
You can find GPIO1 with an offset 0xAC, for example.
Setting bit 1 will enable the clock for this module so that we will be able to read/write GPIO0 through memory mapping.


You can change the values from this register by mapping it, just like you did for setting/clearing a bit on a gpio.



Hope it helps!


Regards,
Patricia.

igorb...@gmail.com

unread,
Jan 25, 2016, 5:03:07 PM1/25/16
to BeagleBoard, igorb...@gmail.com, patrici...@gmail.com
Great answer!

It came a little late for the project that I was working lol.

But even so, it was a good explanation and will still help many people.

Thanks,

misagh.mo...@gmail.com

unread,
May 19, 2018, 10:17:01 AM5/19/18
to BeagleBoard
Thanks Luigi ! That helped me so much. It's a great clue!
Reply all
Reply to author
Forward
0 new messages