Recently, at the Industry Solutions Department of Savoir-faire Linux, we decided to investigate the possibility of adding support for RS-485 to the BeagleBone with ensured short turnaround delay. It turns out that some of our clients out there could be interested in having BeagleBones support the RS-485 standard, as long as short turnaround delay is ensured. As we’ll see, this is an essential condition.
The BeagleBone is a little board which costs almost nothing and features an Ethernet port, USB hosting, MMC I/O and two 46-pin expansion headers where free GPIO, I²C and UART pins are available, amongst other things.
Photo : Rain Rabbit
At the core of this board is a Texas Instruments AM3358 system on a chip embedding an ARM Cortex-A8 processor. This SoC runs Linux with no effort at 720 MHz. There’s also the more recent BeagleBone Black, or BBB, which adds HDMI, has a slightly upgraded SoC (AM3359), runs at 1 GHz, has 2 GB of integrated Flash memory and consumes less power than its white counterpart.
Photo : adafruit
RS-485 (or more formally, TIA-485-A) is an electrical standard defining a multidrop half-duplex serial bus over a single twisted pair of wires. Since RS-485 is half-duplex, only one device at a time may write on the bus. At least 32 different devices may be connected to the same pair of wires in a network:
Moreover, at 100 kbps, the twisted pair may be as long as 1200 meters (about 4000′) with no repeaters. Compare this to RS-232: supports only two devices, maximum length of cable is usually 15 m, is full-duplex and thus requires at least 3 wires (reception, transmission and ground). RS-485’s twisted pair uses differential signalling (just like USB), which means it is highly immune to electromagnetic interference.
All those characteristics of RS-485 make it a great, cheap solution for industrial control systems: factories with lots of sensors, metering instruments, control valves, actuators, etc. RS-485 is also used as a vehicle bus in many aircraft cabins and as the physical layer of DMX512, the protocol driving the lighting systems of virtually all music venues and theatres.
Now, some theory
The half-duplex nature of RS-485 means each device is either receiving or transmitting, but never at the same time. It also means that only one device is transmitting at a given time on the network since there would be electrical conflicts otherwise. This is why the RS-485 transceivers (chips that write/read Rx/Tx lines from a UART to write/read the differential signalling of RS-485) take an additional input from the device: the data direction. By using this input, we can enable/disable the transmitter of the transceiver, which is the only way to "stop writing" on the pair of wires.
The protocols built on top of RS-485 (which only defines electrical characteristics) are usually of the master-slave type. This is the typical sequence for a master-slave communication over RS-485:
- The master takes the bus and writes a message (e.g., read pressure), including a header with a destination ID, which all slaves read
- When the last bit of the message is written, the master has to release the bus as soon as possible
- The destination slave device recognizes its ID from the message header and takes the bus (all other devices continue reading)
- The device writes its response message to the master (all other slave devices read this message, but ignore it)
- When the last bit of the message is written, the slave device has to release the bus as soon as possible
- The master recognizes the message is intended for it and treats it, depending on the application
The time-critical steps here are #2 and #5: it’s really important for any device that’s writting on the bus to release it as soon as the message is sent. The time interval between the moment the last bit of the serial communication is completely written and the moment the bus is released is called the turnaround delay. Having a too long turnaround delay can be fatal: two devices will write on the bus at the same time and data corruption will occur. On the other hand, you need to make sure the last bit of a message is completely written on the bus before releasing it.
What we are trying to do here is to have a UART, available in Linux userspace on the BeagleBone, that will automatically assert a data direction signal to release the bus when it’s not transmitting. We need to really make sure nothing could stop the real-time assertion of this data direction signal when it’s needed in order to avoid any possible data corruption. Once we have that, the protocols relying on RS-485 may be implemented in userspace. We also want to avoid introducing extra components since this would mean yet another part on the bill of materials for a custom board, and yet another part that could stop functionning.
In the light of the aforementioned constraints, we may already eliminate the following solutions:
- AM335x UARTs. Those cores do not directly support RS-485 and therefore, on Linux, their driver cannot ensure a real-time assertion of the data direction signal. Although the driver is able to handle "end of transmission" interrupts from the UARTs, nothing guarantees their latency on Linux. It goes without saying that the turnaround delay could, under specific run-time circumstances, be too long.
- External UARTs. A few UART integrated circuits implement a real-time RS-485 data direction signal. However, this solution adds an external part, which we want to avoid as much as possible.
Of course, we will always need an external RS-485 transceiver, regardless of the UART we use, since the BeagleBone cannot read/write the RS-485 differential signalling.
I am now going to look into the existing solutions for real-time RS-485 support on AM335x SoCs. In my next post, I will publish the results of this investigation and present possible ways of improving actual implementations if needed.