Is it possible to handle hardware interrupts from Elixir?
I ask because I need to respond to a button press. If I was coding to bare metal I would write an ISR, but of course there is BEAM sitting on Debian. If I can’t do an ISR can I have a process block until the hardware changes?
Longer: you might be able to achieve your goal using ports and cports. External programs that can be written in any language and communicate with the BEAM. You can read these messages as if they were from another process using a receive block.
I do not think that you can use NIFs properly here.
Also, since I’m on a mobile I can’t search appropriate links right now.
When sitting in user-space on a Linux system, I think GPIO sysfs is the way to go about it.
elixir_ale provides a nice Elixir abstraction on top of GPIO sysfs. I haven’t had time to play around with it yet, but from its documentation and the example it looks fairly straight forward.
The elixir_ale solution seems to be exactly what I need. It’s a soft real time system so I don’t need to process the interrupt the microsecond it is triggered. As long as I get it within say 100 or 200 ms that will do very well.
Oh, did you mean specifically send an async message when you receive a certain I2C message? For that, I think you’d want to set up your own worker that polls for I2C data and sends them as messages on whatever conditions you need.
I think that John is connecting his Pi to a chip that has an I2C interface and a separate interrupt signal that notifies the Pi when data is ready. Lots of chips do that since I2C doesn’t support async notifications. The pattern is to use ElixirALE.GPIO to detect the interrupt and send a message. Then in the message handler function, call into ElixirALE.I2C to read the new data.
Just as an aside, it would be cool if ElixirALE.I2C could do this for you. The problem is that the command you send to read the chip on interrupt depends on the chip. The updated I2C protocol, I3C, lets devices send interrupts w/o a separate GPIO, so it should be possible to do something nicer when it becomes available.
Thanks for those helpful comments. I did think about my situation more thoroughly last night and I realized that the ElixirALE.GPIO port converts pin state changes to messages, and my I2C chip (LPS25HB sensor) could be wired to a dedicated GPIO pin for that purpose.
Under the hood, on the RPi3B+, how do GPIO interrupts reach the ALE GPIO Port process ? Signals or OS Events ?
I think that your barometer should fine since it doesn’t sound like it has a high interrupt rate. I’m not sure what the real threshold is, but if I were looking at a >100Hz interrupt rate, I’d look at alternatives to handling the interrupts with ElixirALE.