RTEMS SPI Implementations
Sebastian Huber
sebastian.huber at embedded-brains.de
Thu Jan 31 06:46:53 UTC 2019
Hello William,
On 31/01/2019 05:28, William Busacker wrote:
> Hi all,
>
> Told myself that in the new year I'd finally get around to working on
> the Raspberry Pi's BSP some more, but before I start I have a couple
> questions I'd like to have answered, particularly about SPI. Not sure
> if this belongs in the devel list, figured users was a good place to
> start.
>
> Its been talked about before how the RPi SPI driver should be
> re-written at some point. Between the interrupt mis-handling, file
> descriptor bugs, and performance issues, I think there is enough cause
> to do a rewrite, but I'm not sure how exactly it should be done.
> Section 10 of the BSP and Driver guide blanket statements that the SPI
> bus drivers should use the SPI bus framework (dead link, likely lost
> in the cpukit move) and specifies that the API needs to be Linux
> user-space compatible. I understand the desire to be as linux-y as
> possible to make developing in RTEMS much more natural for those not
> used to real time systems, but in this case I'm not sure if it is the
> best move. Doubly so for the Raspberry Pi. (As I'm interested in the
> RPi in particular I'll be referencing that specific BSP forward)
>
> Since the RPi is marketed as an "entry" device for hobby electronics,
> it is either a gateway device or is being upgraded to from an Arduino.
> Brand new users trying to learn about SPI online (Sparkfun's blog post
> being very popular) and people coming from Arduino will be used to the
> model of 8/16 bits being traded with cs active end point. Put data in
> buffer, send/receive, read back, or do it all at once with a single
> function call. Arduino handles this flow quite nicely; configure an
> SPISettings object, "begin" transactions, do as many .transfers() as
> you want then when you're done "end" transaction. Granted Arduino
> purposefully simplifies things, it still is very representative to
> what actually occurs in hardware and is easy for a newcomer to grasp.
> Linux's SPI user-space driver introduces ioctl which in and of itself
> is complex and then makes all interaction through a file descriptor,
> limiting the user to either read /or/ write ability, not both at the
> same time.
>
> For the RPi, the vast majority of SPI examples are either in Python
> (which does use spidev) or in C using either the wiringPi or BCM2835
> libraries. Both the C libraries provide functionality more akin to
> Arduino's solution than the Linux kernel solution.
>
> There are also issues in operational terms of spidev.
> - Full duplex is impossible without digging into ioctl
> - Everything must be synchronous (sitting in its own task can help
> mimic interrupts but may not be the best solution)
> - spidev doesn't offer slave select polarity control
>
> What I was thinking as an alternative is something close to how the
> BCM2835
> <https://www.airspayce.com/mikem/bcm2835/group__spi.html#ga0127eab1b6c3f8bf127bdac474fdc0f9>
> library controls SPI. The library can't be directly put into the RTEMS
> project since it relies on Linux for other things, but its general
> approach is something I feel is a much better solution than using
> spidev. It grants far more insight into what the bus is doing as well
> as much tighter control over the device. I realize this means more
> documentation (something I also plan on attempting to tackle for RPi
> at some point), but I think thats a worthy tradeoff. Especially since
> it seems spidev was designed to fit Unix's
> I'll-get-around-to-it-when-I-feel-like-it approach to device control,
> compared to an rtos's Its my bus and I need it now!
Yes, ioctl() is a horrible interface, but the struct spi_ioc_transfer
transfer mechanism is good from my point of view. It offers full-duplex
transfers, per transfer settings and you can combine multiple transfers
in one request. The driver ensures that the SPI bus is only used for one
request at a time. If you like, then you can hide the ioctl() in a
wrapper function to get a type-safe API. Maybe you can also add another
IO control to accept asynchronous requests with a completion callback.
The APIs using multiple function calls to change settings and do a
transfer have all potential locking issues. Using a request with
multiple transfers has the benefit that you can issue the next transfer
within the interrupt handler. This avoids task switches.
--
Sebastian Huber, embedded brains GmbH
Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail : sebastian.huber at embedded-brains.de
PGP : Public key available on request.
Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
More information about the users
mailing list