GPIO toggle Kernel Module for Beaglebone


So I tested to see how fast the GPIO toggle rate of the Beaglebone could get when using a kernel module. When using user space it was only about 4-5 MHz and once I did the kernel module it got up to 25 MHz. Since I had a difficult time getting the kernel source tree on the beaglebone and compiling everything here is some documentation and code for those who want to build kernel modules/device drivers on the beaglebone and also user program interaction with the kernel module.

gpio.c is the kernel code
gpio.h is the header file for both gpio.c and ioctl.c
ioctl.c is the user code

Here is my Makefile in case you want it also

gpio.c (4 KB)

gpio.h (402 Bytes)

ioctl.c (1.31 KB)

Kernel Module Documentation.txt (11.1 KB)

Hi Wesley,

Seems like a good start, is there any reason you didn't use the GPIO lib? Possibly for speed?It would be interesting to see if there was much difference.

Well done for having a go and getting it working!


I’ve moved my class away from using bitbake for kernel work. Here[1] are the instructions we use to prepare for kernel work.



On the folder that you have setup-scripts downloaded, use chown to take ownership of the folder. Something like ‘chown -r [username]:[username] setup-scripts’ if you’re above the folder. Replace [username] with your username.

Nice ! I’ve been using the PRUSS on the BB. Each instruction which don’t go out of local memory takes 5ns, so basically using one of the GPIO lines hooked to the PRUSS you could achieve more than 25[Mhz]

SET r30.t15
CLR r30.t15

Should takes 15ns (33% duty cycle) that would be 66 [Mhz]

SET r30.t15
XOR r0, r0, 0
CLR r30.t15

Should take 20ns (%50 duty cycle) at 50 [Mhz]

PRUSS seems pretty useful for bit-banging, right now I’m trying to use it to make a “soft” i2s decoder to spare McASP0 for audio cape.

Thank you so much for your reply,I could solve my problem,

Thank you so much for your reply,I could solve my problem,

does this kernel module will help me for my linux kernel 3.8.13-bone47 which is installed in my beagelbone black

thanking you

sumik chakka


I took a look to your code and I have a question.

I don’t understand these 3 instruction…

  gpioSetAddr = baseAddr + (0x4804c194 - MMAP_OFFSET);
  gpioClearAddr = baseAddr + (0x4804c190 - MMAP_OFFSET);
  directionAddr = baseAddr + (0x4804c134 - MMAP_OFFSET);

baseAddr I understood that is the address returned by ioremap and 0x4804c194,0x4804c190 and 0x4804c134 are the address of registers OE, SET_DATAOUT and CLEAR_DATAOUT took from datasheet. But why you subtracted MMAP_OFFSET from this addresses?

Best Regards,
Mihai Seba

Hi Wesley,

I’m interested in checking this out!

The download links are broken, are you able to post new links?

Hope you’re having a top day :smiley:


Hi Rudy!

Bitbanging from kernel module puts a lot of load on the ARM CPU and slows down the whole system.

Find an example on how to toggle a fast PRU GPIO at this link. It runs at user space, no reboot nor administrator privileges necessary. The code limits the toggling frequency down to 40 MHz in order to get good measurements by the eCAP feature. When you remove the NOOPs from the PRU ASM code you can get up to 200 MHz toggling frequency (=100 MHz pulse train @ 50 % duty cycle).


Hi Rudy! I’m not sure where the link was supposed to point to but I found the following an
excellent guide to experimenting the PRU’s using the 4.14 series kernel. (you would have to
update for this to apply)

Bill Bitner

Thank you guys!! Have a great rest of the week :v: