BeagleBone kernel module for fast GPIO access

4,255 views
Skip to first unread message

Jerrill

unread,
Mar 23, 2012, 10:34:59 AM3/23/12
to beagl...@googlegroups.com
I'm working on a BeagleBone project that needs to drive a few GPIO pretty fast (driving a 110-bit shift register, chip selects, etc. with a full SR update occurring every 4 ms). I've got my add-on hardware proven out using sys/class/gpio but it's way too slow. My next thought before going off and changing the hardware design is to write a kernel module to do the heavy lifting of driving the GPIO pins.

My initial attempts at building just a "Hello, World!" type module ultimately lead to a dead end with a missing header file that doesn't exist. I'm sure I'm missing something pretty simple (like a define somewhere that needs to be adjusted) but I would be eternally grateful to anyone who can know down the learning curve a bit.

Does anyone have a working example of how to build a kernel module that flashes, say, the USR3 LED without using sys/class/gpio. Source code and Makefile would be great. Thanks in advance for any assistance, links, etc.

Jerrill

Paul Maddox

unread,
Mar 23, 2012, 10:40:11 AM3/23/12
to beagl...@googlegroups.com
I'd be interested in seeing some source code for this too.
it'd make a great "beginners guide to using GPIO".

-- To join: http://beagleboard.org/discuss
To unsubscribe from this group, send email to:
beagleboard...@googlegroups.com
Frequently asked questions: http://beagleboard.org/faq

Andrey Nechypurenko

unread,
Mar 23, 2012, 11:12:46 AM3/23/12
to beagl...@googlegroups.com
> Does anyone have a working example of how to build a kernel module that
> flashes, say, the USR3 LED without using sys/class/gpio. Source code and
> Makefile would be great. Thanks in advance for any assistance, links, etc.

You can take a look at the following source for the example how to
control PWM's on the BeagleBoard xM using direct memory writes:
https://www.gitorious.org/veter/vehicle/blobs/master/src/xenopwm.c
Actual GPIO toggling is in pwm_func() and all the required
initialization is in the initpwm() function.

You can also take a look at the following article for some more
details and context:
http://veter-project.blogspot.co.uk/2011/09/real-time-enough-about-pwms-and-shaky.html

Since many months I want to re-write the code as a kernel module
(xenomai RTDM driver) but did not get to it yet (it is just a hobby
project). Stars will come to the right position :-) maybe I would be
able to do it on this weekend. Anyway I will post results as soon as
they will be available.

Andrey.

David Goodenough

unread,
Mar 23, 2012, 11:27:58 AM3/23/12
to beagl...@googlegroups.com
> -- To join: http://beagleboard.org/discuss
> To unsubscribe from this group, send email to:
> beagleboard...@googlegroups.com
> Frequently asked questions: http://beagleboard.org/faq
Would you not be better off writing some PRUSS code, and doing the GPIO
from there?

David

Jason Kridner

unread,
Mar 23, 2012, 11:56:35 AM3/23/12
to beagl...@googlegroups.com

>Would you not be better off writing some PRUSS code, and doing the GPIO
>from there?

If just driving a shift register, using one of the synchronous serial
ports (such as McASP or SPI) would also make sense rather than using GPIO.
>


Jerrill

unread,
Mar 23, 2012, 12:10:53 PM3/23/12
to beagl...@googlegroups.com
I looked at the PRU module information in the Sitara Technical Reference Manual here:

http://www.ti.com/product/am3358

Yes, it looks like this peripheral is intended for exactly what I want to do, though I've never used the peripheral before and would have some studying to do.

My background is firmware development (in C and assembly) on microcontrollers like the MSP430, 8050, PIC, etc. So I'm comfortable digesting this sort of documentation. However I'm new to ARM and new to Embedded Linux. What I'm missing is the experience with Linux to know how to even begin to interface to a GPIO (much less a PRU) from the higher level abstraction layers of the OS. Right now there is this big wall between me and all the horsepower the micro offers and it's called Linux and I'm just don't know enough (yet) to get around it.

Right now, my understanding is that unless I want to compile a custom kernel, then I need to build a custom kernel module. I don't know how to do either off the top of my head, but I imagine that the learning curve on the kernel module is less steep. I've done both in the past with some of the more commercial Linux versions following dirt simple tutorials, but haven't had much success doing the same for the BeagleBone yet.

Any direction is welcome. Thanks.
Jerrill

 

On Friday, March 23, 2012 11:27:58 AM UTC-4, David Goodenough wrote:
On Friday 23 Mar 2012, Jerrill wrote:
> I'm working on a BeagleBone project that needs to drive a few GPIO pretty
> fast (driving a 110-bit shift register, chip selects, etc. with a full SR
> update occurring every 4 ms). I've got my add-on hardware proven out using
> sys/class/gpio but it's way too slow. My next thought before going off and
> changing the hardware design is to write a kernel module to do the heavy
> lifting of driving the GPIO pins.
>
> My initial attempts at building just a "Hello, World!" type module
> ultimately lead to a dead end with a missing header file that doesn't
> exist. I'm sure I'm missing something pretty simple (like a define
> somewhere that needs to be adjusted) but I would be eternally grateful to
> anyone who can know down the learning curve a bit.
>
> Does anyone have a working example of how to build a kernel module that
> flashes, say, the USR3 LED without using sys/class/gpio. Source code and
> Makefile would be great. Thanks in advance for any assistance, links, etc.
>
> Jerrill
>
> -- To join: http://beagleboard.org/discuss
> To unsubscribe from this group, send email to:
> beagleboard+unsubscribe@​googlegroups.com

Jerrill

unread,
Mar 23, 2012, 12:15:28 PM3/23/12
to beagl...@googlegroups.com
Yes, I designed the hardware so that I can use a SPI port as well but I do have some other chip select type IO I need to do. Again I still have the same problem with how to build a kernel module to run the SPI peripheral and the GPIO in for a close-to-realtime sort of application. Any tutorials are welcome.

Thanks.
Jerrill

Bas Laarhoven

unread,
Mar 23, 2012, 1:57:35 PM3/23/12
to beagl...@googlegroups.com, Jerrill
On 23-3-2012 17:10, Jerrill wrote:
I looked at the PRU module information in the Sitara Technical Reference Manual here:

http://www.ti.com/product/am3358

Yes, it looks like this peripheral is intended for exactly what I want to do, though I've never used the peripheral before and would have some studying to do.

My background is firmware development (in C and assembly) on microcontrollers like the MSP430, 8050, PIC, etc. So I'm comfortable digesting this sort of documentation. However I'm new to ARM and new to Embedded Linux. What I'm missing is the experience with Linux to know how to even begin to interface to a GPIO (much less a PRU) from the higher level abstraction layers of the OS. Right now there is this big wall between me and all the horsepower the micro offers and it's called Linux and I'm just don't know enough (yet) to get around it.

Right now, my understanding is that unless I want to compile a custom kernel, then I need to build a custom kernel module. I don't know how to do either off the top of my head, but I imagine that the learning curve on the kernel module is less steep. I've done both in the past with some of the more commercial Linux versions following dirt simple tutorials, but haven't had much success doing the same for the BeagleBone yet.

Any direction is welcome. Thanks.
Jerrill
 

Hi Jerill,

You don't need to build a custom kernel module to use the PRUSS. You only need the uio_pruss module and a user space application to load and start a PRU.
I don't know if the uio_pruss module is enabled and built by default nowadays. If not, then you'll need to compile a kernel, or obtain the module from someone else.
It will be a steep learning curve, but all information is available if you search the newsgroup or otherwise ask around. And it's fun to do. You'll also find that the PRU is a fine design with plenty of debugging capabilities. Myself, I'm controlling 4 stepper motors with one PRU and each runs up to 60 kHz steprate (a limitation of the motor drivers, much headroom available). Acceleration is also done in the PRU. Linux is only used for the not hard-realtime code.

Success,
Bas
---


Bas Laarhoven

unread,
Mar 23, 2012, 2:01:23 PM3/23/12
to beagl...@googlegroups.com, Jerrill
On 23-3-2012 18:57, Bas Laarhoven wrote:
On 23-3-2012 17:10, Jerrill wrote:
I looked at the PRU module information in the Sitara Technical Reference Manual here:

http://www.ti.com/product/am3358

Yes, it looks like this peripheral is intended for exactly what I want to do, though I've never used the peripheral before and would have some studying to do.

My background is firmware development (in C and assembly) on microcontrollers like the MSP430, 8050, PIC, etc. So I'm comfortable digesting this sort of documentation. However I'm new to ARM and new to Embedded Linux. What I'm missing is the experience with Linux to know how to even begin to interface to a GPIO (much less a PRU) from the higher level abstraction layers of the OS. Right now there is this big wall between me and all the horsepower the micro offers and it's called Linux and I'm just don't know enough (yet) to get around it.

Right now, my understanding is that unless I want to compile a custom kernel, then I need to build a custom kernel module. I don't know how to do either off the top of my head, but I imagine that the learning curve on the kernel module is less steep. I've done both in the past with some of the more commercial Linux versions following dirt simple tutorials, but haven't had much success doing the same for the BeagleBone yet.

Any direction is welcome. Thanks.
Jerrill
 

Hi Jerill,

Oops, sorry for the typo in your name!

dogisfat

unread,
Mar 23, 2012, 3:50:27 PM3/23/12
to beagl...@googlegroups.com
I have a working kernel module for toggling GPIO which was working on posting a guide to recreating. I don't know if it will be fast enough as the GPIO kernel module only toggles at a little greater than 2 MHz and is not as regular in period as a good pwm output or something of the like. 

Jack Mitchell

unread,
Mar 23, 2012, 3:58:58 PM3/23/12
to beagl...@googlegroups.com

To unsubscribe from this group, send email to:
beagleboard...@googlegroups.com
Frequently asked questions: http://beagleboard.org/faq

I would also be interested in seeing an example of something like this. If not a guide, then just some example code would be nice to get me started!

Regards,
Jack.

Jerrill

unread,
Mar 25, 2012, 10:32:21 PM3/25/12
to beagl...@googlegroups.com, Jerrill
On Friday, March 23, 2012 1:57:35 PM UTC-4, Bas Laarhoven wrote:
On 23-3-2012 17:10, Jerrill wrote:
I looked at the PRU module information in the Sitara Technical Reference Manual here:

http://www.ti.com/product/​am3358

Yes, it looks like this peripheral is intended for exactly what I want to do, though I've never used the peripheral before and would have some studying to do.

My background is firmware development (in C and assembly) on microcontrollers like the MSP430, 8050, PIC, etc. So I'm comfortable digesting this sort of documentation. However I'm new to ARM and new to Embedded Linux. What I'm missing is the experience with Linux to know how to even begin to interface to a GPIO (much less a PRU) from the higher level abstraction layers of the OS. Right now there is this big wall between me and all the horsepower the micro offers and it's called Linux and I'm just don't know enough (yet) to get around it.

Right now, my understanding is that unless I want to compile a custom kernel, then I need to build a custom kernel module. I don't know how to do either off the top of my head, but I imagine that the learning curve on the kernel module is less steep. I've done both in the past with some of the more commercial Linux versions following dirt simple tutorials, but haven't had much success doing the same for the BeagleBone yet.

Any direction is welcome. Thanks.
Jerrill
 

Hi Jerill,

You don't need to build a custom kernel module to use the PRUSS. You only need the uio_pruss module and a user space application to load and start a PRU.
I don't know if the uio_pruss module is enabled and built by default nowadays. If not, then you'll need to compile a kernel, or obtain the module from someone else.
It will be a steep learning curve, but all information is available if you search the newsgroup or otherwise ask around. And it's fun to do. You'll also find that the PRU is a fine design with plenty of debugging capabilities. Myself, I'm controlling 4 stepper motors with one PRU and each runs up to 60 kHz steprate (a limitation of the motor drivers, much headroom available). Acceleration is also done in the PRU. Linux is only used for the not hard-realtime code.

Success,
Bas
---


Bas,

The uio_pruss module sounds like it's the way I would like to go with my project. I did a locate for uio_pruss and pruss and pru and didn't find anything on the current Angstrom/Cloud9 SD card image, so I'm assuming that that means that it's not loaded by default.

I'm in the process of Googling to see what I need to do to find the source code and build the module (unless someone already has it built for 3.2.5+). If you have any information on where to get started (Linux newbie here... sorry...) I would greatly appreciate it.

Thank you in advance for any information you can provide.
Jerrill

 

Jack Mitchell

unread,
Mar 26, 2012, 4:14:45 AM3/26/12
to beagl...@googlegroups.com
-- To join: http://beagleboard.org/discuss
To unsubscribe from this group, send email to:
beagleboard...@googlegroups.com
Frequently asked questions: http://beagleboard.org/faq

Hi Jerrill,

I recently saw a commit by Koen enabling the PRU on the BeagleBone for the 3.2 kernel. Have you build the latest and greatest Angstrom image recently?

Regards,
Jack.

-- 

  Jack Mitchell (ja...@embed.me.uk)             
  Embedded Systems Engineer
  http://www.embed.me.uk

--

dl4...@googlemail.com

unread,
Mar 30, 2012, 2:38:41 AM3/30/12
to beagl...@googlegroups.com
Hi,

I made an example how to access the GPIO directly through mmap which is here:
https://groups.google.com/forum/?fromgroups#!searchin/beagleboard/GPIO$20(LED)$20access$20using$20mmap/beagleboard/pouZDig10Mw/MY7UkBoOy9MJ

In the same way, I tested the toggle rate, and each pulse was 228ns wide, means 4MHz. Straight forward code, set and reset in a simple sequence.

Cheers, Günter

jduhamel

unread,
Apr 3, 2012, 9:28:53 PM4/3/12
to beagl...@googlegroups.com
hi dogisfat,

please let me know when you post the guide

thanks

jmelson

unread,
Jul 16, 2012, 5:40:39 PM7/16/12
to beagl...@googlegroups.com


On Saturday, July 14, 2012 1:53:04 AM UTC-5, Hans wrote:
Yeah I'm trying to get faster GPIO throughput too and have been able to reach about 5MHz using mmap.  But this is still way slower than should be achievable because I can reach speeds of >25MHz by writing bare metal code for the BeagleBone.  Does anyone know if writing a kernel driver would allow access w/o mmap and maybe improve throughput?  
My understanding is that using mmap you are already accessing the GPIO hardware at the lowest level.  The trick they use to reduce power and
maybe complexity is to multiplex the GPIO by banks.  On the original Beagle Board  it is about 240 ns, apparently the bone cuts it to ~225 ns
with a faster clock, or maybe because it has fewer GPIO banks.  So, I don't think you can go faster via GPIO accesses.  When I started with this
I tried to figure out how to turn up the clock on the GPIO system, but I never got that to work.

At least what I've seen so far, there is no way to get 25 MHz out of the GPIO.  Now, the MMC peripherals can go faster, but they are serial, so
that may not increase speed much over a byte-wide GPIO port.

Jon

Koen Kooi

unread,
Aug 3, 2012, 2:08:29 AM8/3/12
to beagl...@googlegroups.com

Op 2 aug. 2012, om 22:05 heeft Hans <hans.a...@gmail.com> het volgende geschreven:

> But I've measured 25 MHz via GPIO by writing bare metal code for beaglebone so I know the chip can drive GPIO at least 25MHz. What is it about running under Angstrom and/or using mmap that's limiting us to 5 Mhz?

Userspace, just write a kernel driver, much better performance

Francois

unread,
Aug 3, 2012, 7:03:59 AM8/3/12
to beagl...@googlegroups.com
Would anyone have any example of how to write a kernel driver for gpio ?

On Friday, August 3, 2012 6:08:29 PM UTC+12, Koen Kooi wrote:

Andrew Bradford

unread,
Aug 3, 2012, 7:37:01 AM8/3/12
to beagl...@googlegroups.com, majes...@gmail.com
On Fri, 3 Aug 2012 04:03:59 -0700 (PDT)
Francois <majes...@gmail.com> wrote:

> Would anyone have any example of how to write a kernel driver for
> gpio ?

See LDD [1]. There's examples.

[1]: https://lwn.net/Kernel/LDD3/

-Andrew

jmelson

unread,
Aug 3, 2012, 12:28:19 PM8/3/12
to beagl...@googlegroups.com, majes...@gmail.com


On Friday, August 3, 2012 6:37:01 AM UTC-5, Andrew Bradford wrote:
On Fri, 3 Aug 2012 04:03:59 -0700 (PDT)
Francois <majes...@gmail.com> wrote:

> Would anyone have any example of how to write a kernel driver for
> gpio ?

See LDD [1].  There's examples.

It would be really helpful if there was a beagle-specific example.  I assume
there are include files that perform the same thing as mmap in the kernel
environment, but are probably different.

Thanks,

Jon

[1]: https://lwn.net/Kernel/LDD3/

-Andrew

jmelson

unread,
Aug 3, 2012, 12:29:26 PM8/3/12
to beagl...@googlegroups.com, majes...@gmail.com

xiooozzz

unread,
Aug 3, 2012, 12:31:03 PM8/3/12
to beagleboard
I can ensure you that by using module, at least 10MHz were achieved by me.
The MANNUAL says Bank0 can works under 100MHz with proper configuration of clk, but only bank0.
if you set the registers and get this real, inform me please.
Looking forward your seccess.
 
 
2012-08-04

xiooozzz

发件人:jmelson
发送时间:2012-07-17 05:40
主题:Re: [beagleboard] BeagleBone kernel module for fast GPIO access
收件人:"beagleboard"<beagl...@googlegroups.com>
抄送:
 

Hans

unread,
Aug 3, 2012, 12:41:37 PM8/3/12
to beagl...@googlegroups.com
Awesome, that's just what I wanted to hear.  I won't be trying to reach 100 MHz, but if I have time to play with clk config I'll let you know.

Cheers,
Hans


On Friday, August 3, 2012 9:31:03 AM UTC-7, iceburg wrote:
I can ensure you that by using module, at least 10MHz were achieved by me.
The MANNUAL says Bank0 can works under 100MHz with proper configuration of clk, but only bank0.
if you set the registers and get this real, inform me please.
Looking forward your seccess.
 
 
2012-08-04

xiooozzz

发件人:jmelson
发送时间:2012-07-17 05:40
主题:Re: [beagleboard] BeagleBone kernel module for fast GPIO access
收件人:"beagleboard"<beagleboard@googlegroups.com>
抄送:
 


On Saturday, July 14, 2012 1:53:04 AM UTC-5, Hans wrote:
Yeah I'm trying to get faster GPIO throughput too and have been able to reach about 5MHz using mmap.  But this is still way slower than should be achievable because I can reach speeds of >25MHz by writing bare metal code for the BeagleBone.  Does anyone know if writing a kernel driver would allow access w/o mmap and maybe improve throughput?  
My understanding is that using mmap you are already accessing the GPIO hardware at the lowest level.  The trick they use to reduce power and
maybe complexity is to multiplex the GPIO by banks.  On the original Beagle Board  it is about 240 ns, apparently the bone cuts it to ~225 ns
with a faster clock, or maybe because it has fewer GPIO banks.  So, I don't think you can go faster via GPIO accesses.  When I started with this
I tried to figure out how to turn up the clock on the GPIO system, but I never got that to work.

At least what I've seen so far, there is no way to get 25 MHz out of the GPIO.  Now, the MMC peripherals can go faster, but they are serial, so
that may not increase speed much over a byte-wide GPIO port.

Jon

-- To join: http://beagleboard.org/discuss
To unsubscribe from this group, send email to:

Koen Kooi

unread,
Aug 3, 2012, 1:38:38 PM8/3/12
to beagl...@googlegroups.com, majes...@gmail.com

Op 3 aug. 2012, om 18:28 heeft jmelson <el...@pico-systems.com> het volgende geschreven:

>
>
> On Friday, August 3, 2012 6:37:01 AM UTC-5, Andrew Bradford wrote:
> On Fri, 3 Aug 2012 04:03:59 -0700 (PDT)
> Francois <majes...@gmail.com> wrote:
>
> > Would anyone have any example of how to write a kernel driver for
> > gpio ?
>
> See LDD [1]. There's examples.
>
> It would be really helpful if there was a beagle-specific example

There would be *nothing* beagle specific about it, it's just plain old linux.

Dave H.

unread,
Aug 3, 2012, 7:36:47 PM8/3/12
to beagl...@googlegroups.com
Jerrill et al,

Here is a GPIO module and accompanying userspace test program I wrote for Linux running on a Nios2 core (soft core for Altera). 

The Makefile will build both.  (test = builds userspace program, module builds module, all builds both)

fwti_gpio_test.c is the userspace program source.
fwti_gpio.c is the module source.

There isn't much platform-specific in there. Where you see NIOS2 for the architecture and calls to the nios2 gcc tools, you will need to switch it to use the ARM stuff.

I am in the process of converting this to Beagle.  If you beat me to it, please send me your results!

Thanks,
Dave ...
gpio.tgz

Wesley

unread,
Aug 30, 2012, 5:05:56 PM8/30/12
to beagl...@googlegroups.com
I don't know if you finished but here are my results? I got up to 25MHz and I posted a discussion on it here:

https://groups.google.com/forum/#!topic/beagleboard/dyuax5415dc

~Wesley
Reply all
Reply to author
Forward
0 new messages