All the examples and libraries (Python mostly) that I can find for
doing IO to the GPIO pins seem to handle only a bit at a time. This
is fine for things like driving relays and LEDs but makes little sense
for 8-bit data.
Are there any sets of 8 GPIO pins that can be used together easily for
outputting 8-bit data? ... and are there any Python IO libraries that
make doing this easy?
At present my Python code is carefully masking, shifting and
outputting the data bit by bit and I have a horrible suspicion that
the library I'm using is carefully doing the opposite before it does
the actual write to GPIO.
All the examples and libraries (Python mostly) that I can find for
doing IO to the GPIO pins seem to handle only a bit at a time. This
is fine for things like driving relays and LEDs but makes little sense
for 8-bit data.
Are there any sets of 8 GPIO pins that can be used together easily for
outputting 8-bit data?
From a hardware standpoint, some of the GPIOs are in the same bank and can
be updated in the same register write.
You have options of using the GPIO_DATAOUT, GPIO_SETDATAOUT and
GPIO_CLEARDATAOUT registers. Up to 32 GPIOs can be controlled by each of
these registers. The GPIO numbers are given in the format GPIOx_y where x
is the bank that will be in a single register and y is the offset within
the register.
Of course, it might be more practical for you to utilize the GPMC bus when
looking to do parallel operations, especially if you want to use DMA or
otherwise perform repeated accesses.
You can also use the PRU for fast parallel bus access.
... and are there any Python IO libraries that
make doing this easy?
I'm not aware of any that make it possible today, though it could be
possible. Most typically, from Linux userspace it is common to utilize the
SYSFS entries provided by the kernel to perform GPIO entries.
Adafruit_BBIO uses the SYSFS entries as can be seen at
.
PyBBIO uses 'mmap' as can be seen at
.
The 'mmap' method exposes the registers. Despite the PyBBIO library not
exposing a function today that would perform writes to multiple pins at
once, it should be possible to modify the code to expose new functions.
At present my Python code is carefully masking, shifting and
outputting the data bit by bit and I have a horrible suspicion that
the library I'm using is carefully doing the opposite before it does
the actual write to GPIO.
Thanks for that comprehensive answer - there's several things there I
may look into, in particular using python file i/o to read the data.
>
> At present my Python code is carefully masking, shifting and
> outputting the data bit by bit and I have a horrible suspicion that
> the library I'm using is carefully doing the opposite before it does
> the actual write to GPIO.
>
What library are you using?
The adafruit one as it seems to be the most univesally used one. I
looked down in the depths of its library code and it does seem to
write single bits actually.
Out of frustration with having to toggle each bit separately, I wrote a library which addresses the problem of scattered I/O pins and allows to use up to 32 independent lines as one word. Due to design of the I/O in the processor it is not possible to change at the same time pins scattered over multiple banks but, at least from the application point of view, all allocated pins are visible as an n-bit word. The library uses mmap to access the pins, so even with the translation layer between the application and the hardware it still should be faster than using file I/O on /sys entries.
Thanks Jacek, that looks very useful, especially as you've done a
HD44780-compatible LCD displays device driver as that's what I'm using
it for at the moment.
> [-- text/plain, encoding quoted-printable, charset: ISO-8859-1, 61 lines
--]
>
> Chris,
>
> Out of frustration with having to toggle each bit separately, I wrote a
> library which addresses the problem of scattered I/O pins and allows to
use
> up to 32 independent lines as one word. Due to design of the I/O in the
> processor it is not possible to change at the same time pins scattered
over
> multiple banks but, at least from the application point of view, all
> allocated pins are visible as an n-bit word. The library uses mmap to
> access the pins, so even with the translation layer between the
application
> and the hardware it still should be faster than using file I/O on /sys
> entries.
> The code is posted on github: https://github.com/piranha32/IOoo
>
Thanks Jacek, that looks very useful, especially as you've done a
HD44780-compatible LCD displays device driver as that's what I'm using
it for at the moment.
LCD is not the best example of use of the library, because you still have
to do some bit magic to set control signals and data lines in the I/O
block, but shows how you can abstract the interface from physical
allocation of bits.
However it still can save some time if you want to add an alphanumeric
display to your design.
With user space device drivers, you’re free to push as little or as much into the kernel as you like.
The normal practice is that a badly behaving user space application should not kill your complete system. Only the user space app should die. When you use user space drivers, you no longer have that protection. User space drivers are generally not a good idea unless you want to avoid the user/kernel switching delays.
When you use user space drivers, you no longer have that protection.
Since this is so off topic I’ll just say, anyone interested about this topic, there is plenty of tutorials and articles about sane user space device drivers, along with production quality open source drivers. The acceptance of the concept is somewhat new, and there are many misconceptions.
When you use user space drivers, you no longer have that protection.
Since this is so off topic I’ll just say, anyone interested about this topic, there is plenty of tutorials and articles about sane user space device drivers, along with production quality open source drivers. The acceptance of the concept is somewhat new, and there are many misconceptions.
Reading the article you sighted, there are several issues with UIO, namely no interrupt handling, no resource management, no memory management, etc. For example, you have to use a Kernel mode interrupt handler and then your user space UIO driver has to read and block until an interrupt occurs. After the interrupt occurs, the scheduler has to schedule your UIO driver to run before your driver can respond to the interrupt. That is going to be very slow compared to a kernel driver interrupt handler. The application on the user side has to take care of memory and resource management rather than relying on the core driver components already available in the kernel. I’m not saying that UIO isn’t a good idea. Understand the benefits and limitations of UIO before pursuing this direction.