Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Using interrupts on RPi #173
@Oitzu Np, and thanks for all of this so far!
I was just playing with interrupts little more, and was testing functions to en/disable interrupts also (similar to Arduino functions ) In testing it seems it was easiest to just lock/unlock in the interrupt function itself, which allows the following.
This should prevent any conflicts on the SPI BUS and seems to be working good for me with with various RF24 libs.
I'm not sure what your thoughts are here, but I can always accept the current pull and merge this stuff in if OK like this, otherwise feel free to modify and/or make suggestions.
First time hearing about conflicts, of which nature are this conflicts? Any example?
About "detaching" interrupts:
this pull request
Dec 18, 2015
Well I don't really know what I'm talking about, I'm just referencing documentation and testing so...
It seems like both options (detachInterrupt() and lock/pause interrupts) may be useful. The advantage of the mutex lock is that interrupts are not actually disabled, as per here
This basically seems to provide a nice system of queuing for interrupts, while automatically making queues, etc thread-safe, from what I understand of the documentation.
I referenced my latest commit to RF24Gateway above, since I was experiencing SPI conflicts, until adding the mutex lock/unlock functions. edit Just for clarification, I was debugging with GDB and it was hanging on BCM SPI functions.
It seems that, since the reading is done in a separate thread, writing to SPI can cause problems if it happens at the same time a read is incoming. This issue was only apparent via testing with RF24Gateway and RF24Mesh, and only with some active traffic.
Hm... i don't fully understand yet, how you want to use the mutex to queue interrupts.
The SPI problem makes sense to me, altough i thought the higher priority of the thread would prevent the main thread to write while the child is reading.
It makes to me more sense to lay a mutex on the spi to prevent simultan access to the bus from multiple threads.
That might work fine?
In more complex examples like RF24Network or RF24Gateway, in the update() function data is read into a buffer and written to the radio for routing, acks etc.
If a user decides to read from that buffer in a separate thread, it would be 'unprotected' (I think?... mostly testing with queues in RF24GW). This also makes the locking interface public, so users can use the same mutex for queues/data management.
I'm thinking if its done at the SPI layer, users or additional libs can use their own lock for queues etc. so it probably would work out about the same, just a bit more code to integrate separate locking?
Traditionally, on Arduino, interrupts are handled with separate functions, but it seems some form of locking can allow more fluid handling of radio functions using standard code with small modifications.
I seriously lost you at this point.
I'm at this point no longer sure what you want to achieve. ^^
In short, I am trying to achieve prevention of apparent conflicts.
In attempting to implement locking/unlocking at the SPI layer it seems to work, but I have additional problems managing data with separate locks.
Thread safe queues typically need to be implemented to pass data between threads. I was hoping to remove the need to implement anything to make queues thread-safe.
If you are still unsure, I can accept this pull request, as-is and mess around with a side fork, until I get this figured out better.
So after taking a break, I decided to put locking into SPI functions, remove all locking from higher libs and recompiled everything.
Still refuses to work properly in GDB, but without debugging it works fine??
I think I may have proven myself wrong in regards to the need for thread-safe queues, because I can't seem to make it crash or anything. I've left the additional rfInterrupts() rfNoInterrupts() functions for testing, but for now I thought it easiest to have the main interrupt functionality in the master branch.
banging head on desk
Uhh, I think I finally got the best of both worlds happening here, with automatic thread locking at the SPI level, and leaving the
Per the last commit, this automatically prevents spi conflicts, demonstrated via the rx_transfer.cpp example, by adding
My initial solution would have required users to manually lock before the network.write().
This all seems to be working, so
I was kind of thinking along those lines, but not quite that far. Sounds like a good idea! It may make interrupt handling a bit more portable & standardized too?
I just created a new interrupts branch for further dev, which is just a copy of the master, but you should have direct access to it, in case you feel like doing some more coding.
I don't see the spi transaction implementation that strong connected to the interrupt handling but more to multi-threading in general. (It would also affect other application that use multi-threading that are build on top of the rf24 lib)
Thats also the reason i moved the spi mutex handling completly to the spi files.
I pushed a little bit of code to show you how i imagined that.
added a commit
this pull request
Dec 20, 2015
All testing good so far.
You are probably aware, but one deceiving thing when testing interrupts to receive & disabling them is the radio buffer will fill up, and interrupts will stop happening. A simple solution is to call the interrupt handler manually before re-enabling or just do a read.
I've been messing with a few minor changes to bring the SPI transaction code more in-line with the Arduino API, and I'll push them in a min. for you to look at. I've tested lightly with Arduino and RPi, and will post and update if I find any bugs.