-
-
Notifications
You must be signed in to change notification settings - Fork 7k
Make SPI access atomic in Ethernet library #1334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
When using the Ethernet library combined with another library that does SPI access inside an interrupt handler, the Arduino could crash if that interrupted occured while the Ethernet library was doing an SPI transfer. This commit makes all Ethernet SPI transfers happen atomically (i.e., with the global interrupt flag cleared), preventing such conflicts by delaying all interrupts until after the SPI transfer. Closes: arduino#384
Dont disable global interrupts in Libs it's bad programming and is bad for timed sensitive apps that rely on other interrupts. |
Tricky thing: You are correct that this might cause a problem with timing sensitive applications, but if we don't disable interrupts, some other lib (RF22 in my case) can hijack the SPI bus and deadlock the Arduino entirely. I guess this could be fixed in an application by disabling interrupts before writing to the ethernet library, but this:
Which only leaves us with the option of making the atomic access optional (defaulting to atomic, I'd argue), but I'm not sure I really like this option (it will probably get messy code with lot of conditionals). Perhaps the messyness can be limited by making this a compile time option that does something like |
Spi write are fast and potentially used by many sensors, this mean race
|
I'll close this pullrequest for now, since it seems that this is not the correct solution for this. Perhaps making the SPI library know a bit more about the various SPI slaves and transfers in progress might help, but I guess there isn't any magical way to reliably use SPI transfers inside a interrupt routine... |
The Arduino SPI library can be improved to 1) handle multiple devices with different clock/phase/mode setting on the same bus, 2) allow usage from interrupt handlers, 3) perform the chip select and 4) USI implementation on ATtiny. To show how this could be achieved please see the Cosa/SPI driver. mikaelpatel/Cosa#10 and https://github.com/mikaelpatel/Cosa/blob/master/cores/cosa/Cosa/SPI.hh (SPI.cpp). Please find the on-line documentation here http://dl.dropboxusercontent.com/u/993383/Cosa/doc/html/da/d8d/classSPI.html. The driver base class is here http://dl.dropboxusercontent.com/u/993383/Cosa/doc/html/dc/dd2/classSPI_1_1Driver.html. |
@mikaelpatel, that code looks very good and exactly shows what I had in mind API-wise. Something like that really makes sense for the Arduino core IMHO, but the code can't be used as-is (since 1) Arduino core needs to keep the original SPI class around for backward-compatibility, 2) The Arduino core doesn't have abstractions like |
When using the Ethernet library combined with another library that does
SPI access inside an interrupt handler, the Arduino could crash if that
interrupted occured while the Ethernet library was doing an SPI
transfer.
This commit makes all Ethernet SPI transfers happen atomically (i.e.,
with the global interrupt flag cleared), preventing such conflicts by
delaying all interrupts until after the SPI transfer.
Closes: #384