markqvist / RNode_Firmware

RNode is an open, free and flexible digital radio interface with many uses
https://unsigned.io/rnode
GNU General Public License v3.0
166 stars 56 forks source link

RNode Linux Daemon: Possible? #14

Closed interfect closed 2 years ago

interfect commented 2 years ago

I have a dead-simple LoRa setup with a SX1276-based HopeRF RFM95W hooked up to /dev/spidev0.0 and thus available from Linux userland. There are Python drivers to run the radio, such as pySX127x and my fork of same, but those kind of need to be built into the application to be useful.

RNode has a good ecosystem, but that software needs to speak the KISS RNode protocol and not straight SPI to the modem. And the RNode firmware here isn't really designed to be buildable as a Linux application.

How feasible would it be to add support to this project for a build mode that turns out a Linux daemon instead of an Arduino firmware, and which e.g. opens a Unix socket for KISS commands and talks to the modem over Linux SPI? With enough #ifdefs anything is possible.

How receptive would you be to a PR that adds that functionality?

Alternately, is there documentation of the samantics (arguments, return values, etc.) of the RNode command set that I could use to build an RNode-compatible soft-TNC daemon like I want on top of the Python driver I've been working with?

How happy would the RNode config tool and so on be if presented with a Unix socket instead of a serial device?

interfect commented 2 years ago

The other consideration is that the board I'm targeting doesn't hook up any of the DIOs from the modem, and so the modem needs to be polled over SPI to detect any events. I have that set up in my Python driver, but that would also have to be implemented as a build option here if I wanted to be able to build something that would work for my application.

From looking at the code here, it looks like right now only one DIO interrupt line is actually used for anything, so implementing a codepath for when it is not available might not actually be too hard.

interfect commented 2 years ago

I've started working on this in https://github.com/interfect/RNode_Firmware/tree/linux

I have the code building for Linux, and I have a plausible Linux implementation for the SPI code.

I still need to fill in a couple more components: a Linux version of the Serial interface (which might want to be backed by a PTY, since I don't think all the RNode tools know how to work over a network socket), and possibly a Linux file-backed persistent EEPROM, depending on how happy the code is working with an EEPROM that is always apparently 0.

markqvist commented 2 years ago

Hello interfect! Since you have already answered your own question about the feasibility of doing this by just going ahead and doing it, I will just say nice work man 👍 Very cool that you have it building for Linux already.

I have been wanting to do something like this (add generic LoRa module support for Linux boards that have SPI interfaces) for a while, but have not yet gotten around to it. This approach was definitely not my first thought on how to do it, but as you say, with enough compiler macros, anything is possible ;)

If you can get this to a working and stable state, without disrupting stability and functionality of the other build targets, I would accept a pull request on this, and even help add support in all the tools in the ecosystem. I would be quite pleased if we can make a conceptual divison of "physical" and "virtual" RNodes, since I think that will make it easier to deal with for users. As in: The RNode firmware can also function as a "virtual RNode" on a linux system with an SX1276 connected directly over SPI.

Regarding the Direct IO pins, it is correct that only one is currently used. This one is most definitely needed though, since it is the trigger for the "packet received" interrupt. A polling based approach might be good enough for implementations that only expect to see a packet every now and then, but for a general purpose data radio, it won't cut it. To work efficiently, the packet needs to be read out immediately from the SX1276 buffer, since you could potentially have less than a millisecond before the next packet needs to be written to the same buffer space in the SX1276.

You correctly assume the need for a file-backed virtual EEPROM. The tools depend on reading configuration parameters and such from the EEPROM, and are pretty strict with verifying checksums of it, since erroneous data here, or randomly flipped bits could lead to transmitting on wrong frequencies or at a power-level that the board could not handle. So the best approach is probably just to map the EEPROM to file somewhere and implement a simple wrapper function for it.

If it is at all possible to implement the host comms with a PTY backed "virtual serial port", it would probably be the best approach right now, since it will be considerable effort to allow all the tools in the ecosystem to speak to a domain socket or TCP port instead. Nothing difficult in it really, but it is going to be a few days of slave-labour-refactoring of everything, and I currently have a lot of other work on all the software that prioritises higher.

Regarding the RNode KISS protocol command set, it is not terribly well documented, apart from the info in the manual you can find at https://unsigned.io/rnode and on the github repository. All the commands are in the "Framing.h" file though, and by looking at the KISS code, it should be pretty easy to figure out the formatting. If something is not clear, just ask me and I can explain it.

I hope I didn't forget answering anything, and if there is more, just let me know, I will try to help you out as best as I can.

markqvist commented 2 years ago

Support for compiling for Linux is now in the experimental branch linux-daemon, thanks to the porting efforts of @interfect.