trab_rs485(4)

NAME
trab_rs485 - device driver for the TRAB RS485 interface

SYNOPSIS
#include <linux/trab_rs485.h>

DESCRIPTION
The driver provides read/write access to the RS485 bus. The driver always acts as the master on the RS485 bus. The implementation of the hardware results in half-duplex operation, i.e. all writes are followed by an automatic read to receive the node's response to the command. The driver can perform periodic polling of the nodes on the RS485 bus to prevent watchdog timeouts on the nodes. The poll interval can be set independently for each node using the ioctl() interface. If, for at least one node on the bus, the bytes returned from the most recent poll are different from those returned in the previous poll then the driver can signal this by setting an exception in the poll() or select() call. The write() interface limits the number of outstanding writes to ten (10) to avoid overfilling the queue. The read() interface returns data queued up from the nodes in response to previous write() accesses. To avoid exhausting kernel memory the application must issue a read() call after every write(). The trab_rs485 driver is interfaced to the user space via a device node. The device node has the major number of 240 and the minor number of 0.

FUNCTIONS
In general, the TRAB_RS485 driver's functions behave as used with other drivers. A function return value of (-1) indicates an error, in which case an appropriate error code can be found in errno. The TRAB_RS485 driver supports the following driver calls:

open()
    The device may be opened for reading and writing. There is no limit to the number of applications which may have the device open.
    Error codes:
    none

close()
    Error codes:
    none

read()
    The read() call returns the next entry from the queue of node responses which resulted from previous write() calls. It is not possible to specify a particular node from which to read.
    The second argument in the read() call must be a pointer to a struct rs485_data defined in linux/trab_rs485.h as follows:
    	#define MAX_BYTES 64
    	struct rs485_data
    	{
    		char target_node;
    		char command_byte;
    		int tx_count;
    		int rx_expected;
    		unsigned char tx_data[MAX_BYTES];
    		unsigned char rx_data[MAX_BYTES];
    		int result;
    	};
    The third argument in the read() call must be a sizeof(struct rs485_data).
    If the read() succeeds then rx_expected bytes of data are returned in the byte array rx_data. In addition a driver-specific error code is returned in result with one of the following values defined in linux/trab_rs485.h as follows:
    	#define RESULT_OK 0 /* no error */
    	#define RESULT_TO 1 /* timeout while reading */
    	#define RESULT_CRC 2 /* bad CRC */
    	#define RESULT_CNT 3 /* read count incorrect */
    	#define RESULT_SER 4 /* error on the serial line */
    The data returned are invalid in the case where result is not set to RESULT_OK.
    In both blocking and non-blocking modes, read() returns sizeof(struct rs485_data), if no error occurs. Otherwise, it returns (-1) and sets an appropriate errno value.
    Error codes:
    EAGAIN - the device was opened in non-blocking mode and no data are available.
    EFAULT - copying the data to the application failed.
    EINTR - the call was interrupted by a signal.

write()
    The write() call accepts data from an application, adds it to a driver-internal write queue (limited to 10 entries) and immediately tries to start the transfer.
    The second argument in the write() call must be a pointer to a struct rs485_data defined in linux/trab_rs485.h as shown above under read().
    It is the responsiblity of the applicaion to fill in the target_node (the number of the target node on the RS485 bus), command_byte (the value of the command field), tx_count (the number of bytes to be sent to the node, may be 0) and rx_expected (the number of bytes expected in the reply from the node, may be 0) fields and the byte array tx_data (the bytes to send to the target node) with valid values, depending on the node being addressed and the command being issued. It is beyond the scope of this manual page to discuss the RS485 protocols supported by various nodes.
    Note that the driver automatically calculates the CRC and adds it to the data being sent to the node.
    The third argument in the write() call must be a sizeof(struct rs485_data).
    write() returns sizeof(struct rs485_data), if no error occurs. write() returns 0 if the write queue is already full. Otherwise, it returns (-1) and sets an appropriate errno value.
    Error codes:
    EFAULT - copying the data from the application failed.
    EINTR - the call was interrupted by a signal.
    ENOMEM - the driver could not allocate temporary storage.

ioctl()
    The following IOCTL commands are supported:
    RS485_SET_WDOG
    Sets the interval for polling the node to prevent the watchdog from triggering, in milliseconds. Note that, due to delays which can be caused by automatic retries in the driver, the timeout should be set to about 100 milliseconds less than the actual timeout.
    Duplicate entries are automatically handled by the driver so that it is safe to issue multiple ioctl() calls for the same node in order to change the timeout or the command used for polling.
    The third argument in the ioctl() call must be a pointer to a struct rs485_wdog defined in linux/trab_rs485.h as follows:
    	#define DUMMY_BYTES (sizeof(unsigned long) + sizeof(int)
    			+ sizeof(struct rs485_wdog *))
    	struct rs485_wdog {
    		int timo; /* maximum timeout in milliseconds */
    		struct rs485_data rs485_wdog_data;
    		/* to make the size match */
    		char dummy[DUMMY_BYTES];
    	};
    Note that the byte array dummy is merely for padding and should not be accessed by the application.
    The application must issue this ioctl() call for every node which must be periodically polled before acessing it for read or write.
    It is the responsibility of the application to fill in the fields of rs485_wdog_data with valid values for a command which can safely be issued to the target node at regular intervals. See the description of the write() call for more information about the fields in the structure.
    This IOCTL can fail with the following errno value:
    ENOMEM - the driver could not allocate temporary storage
    RS485_WDOG_PERIOD
    ioctl() call to set the period within which the application must re-trigger the watchdogs set up using RS485_SET_WDOG. If the application fails to re-trigger the watchdogs within the desired period, then the watchdogs are disabled. This is a safety feature.
    Note that any watchdogs set up will not become active until this ioctl() is issued to the driver !
    The third argument in the ioctl() call must be a pointer to an integer and contains the desired period in seconds.
    RS485_WDOG_TRIGGER
    ioctl() to re-trigger the watchdogs in the driver. This ioctl() takes no arguments.
    RS485_GET_COUNT
    Returns the number of nodes whose return value has changed since the last poll. The integer returned can be used in a loop with the RS485_GET_STATUS
    ioctl() call to read all new return values from all affected nodes.
    The third argument in the ioctl() call must be a pointer to an integer.
    RS485_GET_STATUS
    Returns the unread return value for the next node whose return value has changed since the last poll.
    The third argument in the ioctl() call must be a pointer to a struct rs485_data.
    The new return value is returned in the byte array rx_data in the struct rs485_data.
    The description given for the values returned by the read() call above also applies to this IOCTL.
    Note that the driver maintains no history of values returned as a result of polling acions - the bytes returned are always from the most recently completed poll.
    Error codes for all the IOCTL commands:
    EINVAL - an unrecognized IOCTL was issued to the driver.
    EFAULT - copying the data to/from the application failed.

poll()
    The poll() function implemented by the TRAB_RS485 driver lets the application wait for an event to occur on the file descriptor.
    poll() returns (POLLOUT | POLLWRNORM) without blocking whenever the write queue contains fewer than ten (10) entries, meaning that the device ready for writing.
    poll() returns (POLLIN | POLLRDNORM) whenever data is available for reading. This can block.
    poll() returns POLLPRI (in the exception mask) whenever the bytes returned from the latest poll for at least one node have changed. This can block.