[beagleboard] Fast read and write GPIO?

Hello,

I am needing to read 24 GPIO and write 24 GPIO 10,000 times per second.
Looking at clock rates of the processor(720MHz) and GPIO(100MHz) this seems
like it should be trivial but I haven't gotten close.

I have tried using a python script that uses MMAP but only get about 29KHz
(for one pin, for 48 it would be 600Hz):
#This is a test program that blinks USR1 LED
#Using MMAP
#See: www.alexanderhiam.com/tutorials/beaglebone-io-using-python-mmap/
#To exit the program use "ctrl" + "c"

from mmap import mmap
import time, struct

GPIO1_offset = 0x4804c000
GPIO1_size = 0x4804cfff-GPIO1_offset
GPIO_OE = 0x134
GPIO_SETDATAOUT = 0x194
GPIO_CLEARDATAOUT = 0x190
USR1 = 1<<22

with open("/dev/mem", "r+b" ) as f:
  mem = mmap(f.fileno(), GPIO1_size, offset=GPIO1_offset)

with open("/sys/kernel/debug/omap_mux/lcd_data1", 'wb') as f:
  f.write('27')

reg = struct.unpack("<L", mem[GPIO_OE:GPIO_OE+4])[0]
mem[GPIO_OE:GPIO_OE+4] = struct.pack("<L", reg & ~USR1)

try:
  while(True):
    mem[GPIO_SETDATAOUT:GPIO_SETDATAOUT+4] = struct.pack("<L", USR1)
    #time.sleep(0.5)
    mem[GPIO_CLEARDATAOUT:GPIO_CLEARDATAOUT+4] = struct.pack("<L", USR1)
    #time.sleep(0.5)

except KeyboardInterrupt:
  mem.close()

I've read things about using kernal modules but I am new to this and have
no idea how to use them.

Any ideas on how I can make access the GPIO Faster?

I believe the easiest thing to do would be to use the PRUs. They run
at 200MHz and have direct access to the pins, though I don't think you
can access 48 of them from the PRUs without going through some tricks.

A kernel module does make sense in a lot of ways.

For the reading, you might consider using the GPMC if you are reading
the bits all at once. You could simply do a 32-bit read and capture 24
bits of valid data. You could even tie the DMA to it and use a timer
to trigger the reads.

It would be trivial if you weren't doing a ton of context switches.
Take a look at 'strace <your program>' to see how many times you are
making system calls that cause context switches (and realize that
those aren't the only things that would trigger a context switch).

Have you consider working without an OS, such as with StarterWare
(http://beagleboard.org/project/starterware)?

I definitely need 48 GPIO so PRU is out.

I’ll look into GPMC.

Would using no operating system make it run faster? How would I run programs on it without an OS?

I definitely need 48 GPIO so PRU is out.

I’ll look into GPMC.

Would using no operating system make it run faster? How would I run programs on it without an OS?

What programs do you need to run? You’d be running just one, without an OS.

We only need to run one program. Are there any tutorial on how to use the beaglebone without an OS?

This is the link to starterware - http://www.ti.com/tool/starterware-sitara
I have read in this forum that people have got up to 240 nsec switching time to switch a GPIO pin using mmap.

A kernel should improve the speed.
There is another alternative to use xenomai patch (www.xenomai.org) and use real time handlers…
You can get some pointers here as well - https://www.osadl.org/fileadmin/dam/rtlws/12/Brown.pdf

If you’re looking at going the xenomai approach, check this out:

yapatel.org/wiki/index.php/Installing_Xenomai_on_a_beaglebone

So, is it true that PRU has this 48pins control limitation ?

I was going to experiment with PRU to solve my problem
(described here: https://groups.google.com/forum/?fromgroups=#!category-topic/beagleboard/beaglebone/8TgHjTrU7rA),
but this new information is puzzling me.

Thanks