First Working Master with Adaptronic simulator

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers modbus.h Source File

modbus.h

00001 /*
00002  * Copyright &#65533; 2001-2008 St&#65533;phane Raimbault <stephane.raimbault@gmail.com>
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU Lesser Public License as published by
00006  * the Free Software Foundation; either version 3 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU Lesser Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #pragma once
00019 
00020 #include <stdint.h>
00021 //#include <termios.h>
00022 //#include <arpa/inet.h>
00023 
00024 
00025 #define MODBUS_TCP_DEFAULT_PORT 502
00026 
00027 #define HEADER_LENGTH_RTU           0
00028 #define PRESET_QUERY_LENGTH_RTU     6
00029 #define PRESET_RESPONSE_LENGTH_RTU  2
00030 
00031 #define HEADER_LENGTH_TCP           6
00032 #define PRESET_QUERY_LENGTH_TCP    12
00033 #define PRESET_RESPONSE_LENGTH_TCP  8
00034 
00035 #define CHECKSUM_LENGTH_RTU      2
00036 #define CHECKSUM_LENGTH_TCP      0        
00037 
00038 /* It's not really the minimal length (the real one is report slave ID
00039  * in RTU (4 bytes)) but it's a convenient size to use in RTU or TCP
00040  * communications to read many values or write a single one.
00041  * Maximum between :
00042  * - HEADER_LENGTH_TCP (6) + slave (1) + function (1) + address (2) +
00043  *   number (2)
00044  * - HEADER_LENGTH_RTU (0) + slave (1) + function (1) + address (2) +
00045  *   number (2) + CRC (2)
00046 */
00047 #define MIN_QUERY_LENGTH        12
00048 
00049 /* Page 102, Application Notes of PI&#65533;MBUS&#65533;300: 
00050  *  The maximum length of the entire message must not exceed 256
00051  *  bytes.
00052  */
00053 #define MAX_MESSAGE_LENGTH     256
00054 
00055 #define MAX_STATUS             800
00056 #define MAX_REGISTERS          100
00057 
00058 #define REPORT_SLAVE_ID_LENGTH 75
00059 
00060 /* Time out between trames in microsecond */
00061 #define TIME_OUT_BEGIN_OF_TRAME 500000
00062 #define TIME_OUT_END_OF_TRAME   500000
00063 
00064 #ifndef FALSE
00065 #define FALSE 0
00066 #endif
00067 
00068 #ifndef TRUE
00069 #define TRUE 1
00070 #endif
00071 
00072 #ifndef OFF
00073 #define OFF 0
00074 #endif
00075 
00076 #ifndef ON
00077 #define ON 1
00078 #endif
00079 
00080 /* Function codes */
00081 #define FC_READ_COIL_STATUS          0x01  /* discretes inputs */
00082 #define FC_READ_INPUT_STATUS         0x02  /* discretes outputs */
00083 #define FC_READ_HOLDING_REGISTERS    0x03  
00084 #define FC_READ_INPUT_REGISTERS      0x04
00085 #define FC_FORCE_SINGLE_COIL         0x05
00086 #define FC_PRESET_SINGLE_REGISTER    0x06
00087 #define FC_READ_EXCEPTION_STATUS     0x07
00088 #define FC_FORCE_MULTIPLE_COILS      0x0F
00089 #define FC_PRESET_MULTIPLE_REGISTERS 0x10
00090 #define FC_REPORT_SLAVE_ID           0x11
00091 
00092 /* Protocol exceptions */
00093 #define ILLEGAL_FUNCTION        -0x01
00094 #define ILLEGAL_DATA_ADDRESS    -0x02
00095 #define ILLEGAL_DATA_VALUE      -0x03
00096 #define SLAVE_DEVICE_FAILURE    -0x04
00097 #define SERVER_FAILURE          -0x04
00098 #define ACKNOWLEDGE             -0x05
00099 #define SLAVE_DEVICE_BUSY       -0x06
00100 #define SERVER_BUSY             -0x06
00101 #define NEGATIVE_ACKNOWLEDGE    -0x07
00102 #define MEMORY_PARITY_ERROR     -0x08
00103 #define GATEWAY_PROBLEM_PATH    -0x0A
00104 #define GATEWAY_PROBLEM_TARGET  -0x0B
00105 
00106 /* Local */
00107 #define COMM_TIME_OUT           -0x0C
00108 #define PORT_SOCKET_FAILURE     -0x0D
00109 #define SELECT_FAILURE          -0x0E
00110 #define TOO_MANY_DATA           -0x0F
00111 #define INVALID_CRC             -0x10
00112 #define INVALID_EXCEPTION_CODE  -0x11
00113 #define CONNECTION_CLOSED       -0x12
00114 
00115 /* Internal using */
00116 #define MSG_LENGTH_UNDEFINED -1
00117 
00118 typedef enum { RTU, TCP } type_com_t;
00119 typedef enum { FLUSH_OR_RECONNECT_ON_ERROR, NOP_ON_ERROR } error_handling_t;
00120 
00121 /* This structure is byte-aligned */
00122 typedef struct {
00123         /* Descriptor (tty or socket) */
00124         int fd;
00125         /* Communication mode: RTU or TCP */
00126         type_com_t type_com;
00127         /* Flag debug */
00128         int debug;
00129         /* Header length used for offset */
00130         int header_length;
00131         /* Checksum length RTU = 2 and TCP = 0 */
00132         int checksum_length;
00133         /* TCP port */
00134         int port;
00135         /* Device: "/dev/ttyS0", "/dev/ttyUSB0" or "/dev/tty.USA19*"
00136            on Mac OS X for KeySpan USB<->Serial adapters this string
00137            had to be made bigger on OS X as the directory+file name
00138            was bigger than 19 bytes. Making it 67 bytes for now, but
00139            OS X does support 256 byte file names. May become a problem
00140            in the future. */
00141 #ifdef __APPLE_CC__
00142         char device[64];
00143 #else
00144         char device[16];
00145 #endif
00146         /* Bauds: 9600, 19200, 57600, 115200, etc */
00147         int baud;
00148         /* Data bit */
00149         uint8_t data_bit;
00150         /* Stop bit */
00151         uint8_t stop_bit;
00152         /* Parity: "even", "odd", "none" */
00153         char parity[5];
00154         /* In error_treat with TCP, do a reconnect or just dump the error */
00155         uint8_t error_handling;
00156         /* IP address */
00157         char ip[16];
00158         /* Save old termios settings */
00159        // struct termios old_tios;
00160 } modbus_param_t;
00161 
00162 typedef struct {
00163         int nb_coil_status;
00164         int nb_input_status;
00165         int nb_input_registers;
00166         int nb_holding_registers;
00167         uint8_t *tab_coil_status;
00168         uint8_t *tab_input_status;
00169         uint16_t *tab_input_registers;
00170         uint16_t *tab_holding_registers;
00171 } modbus_mapping_t;
00172 
00173 
00174 /* All functions used for sending or receiving data return:
00175    - the numbers of values (bits or word) if success (0 or more)
00176    - less than 0 for exceptions errors
00177 */
00178 
00179 /* Reads the boolean status of coils and sets the array elements in
00180    the destination to TRUE or FALSE */
00181 int read_coil_status(modbus_param_t *mb_param, int slave,
00182                      int start_addr, int nb, uint8_t *dest);
00183 
00184 /* Same as read_coil_status but reads the slaves input table */
00185 int read_input_status(modbus_param_t *mb_param, int slave,
00186                       int start_addr, int nb, uint8_t *dest);
00187 
00188 /* Reads the holding registers in a slave and put the data into an
00189    array */
00190 int read_holding_registers(modbus_param_t *mb_param, int slave,
00191                            int start_addr, int nb, uint16_t *dest);
00192 
00193 /* Reads the input registers in a slave and put the data into an
00194    array */
00195 int read_input_registers(modbus_param_t *mb_param, int slave,
00196                          int start_addr, int nb, uint16_t *dest);
00197 
00198 /* Turns ON or OFF a single coil in the slave device */
00199 int force_single_coil(modbus_param_t *mb_param, int slave,
00200                       int coil_addr, int state);
00201 
00202 /* Sets a value in one holding register in the slave device */
00203 int preset_single_register(modbus_param_t *mb_param, int slave,
00204                            int reg_addr, int value);
00205 
00206 /* Sets/resets the coils in the slave from an array in argument */
00207 int force_multiple_coils(modbus_param_t *mb_param, int slave,
00208                          int start_addr, int nb, const uint8_t *data);
00209 
00210 /* Copies the values in the slave from the array given in argument */
00211 int preset_multiple_registers(modbus_param_t *mb_param, int slave,
00212                               int start_addr, int nb, const uint16_t *data);
00213 
00214 /* Returns the slave id! */
00215 int report_slave_id(modbus_param_t *mb_param, int slave, uint8_t *dest);
00216 
00217 /* Initializes the modbus_param_t structure for RTU.
00218    - device: "/dev/ttyS0"
00219    - baud:   9600, 19200, 57600, 115200, etc
00220    - parity: "even", "odd" or "none" 
00221    - data_bits: 5, 6, 7, 8 
00222    - stop_bits: 1, 2
00223 */
00224 void modbus_init_rtu(modbus_param_t *mb_param, const char *device,
00225                      int baud, const char *parity, int data_bit,
00226                      int stop_bit);
00227                      
00228 /* Initializes the modbus_param_t structure for TCP.
00229    - ip : "192.168.0.5" 
00230    - port : 1099
00231 
00232    Set the port to MODBUS_TCP_DEFAULT_PORT to use the default one
00233    (502). It's convenient to use a port number greater than or equal
00234    to 1024 because it's not necessary to be root to use this port
00235    number.
00236 */
00237 
00238 /* By default, the error handling mode used is RECONNECT_ON_ERROR.
00239 
00240    With RECONNECT_ON_ERROR, the library will attempt an immediate
00241    reconnection which may hang for several seconds if the network to
00242    the remote target unit is down.
00243 
00244    With NOP_ON_ERROR, it is expected that the application will
00245    check for network error returns and deal with them as necessary.
00246 
00247    This function is only useful in TCP mode.
00248  */
00249 void modbus_set_error_handling(modbus_param_t *mb_param, error_handling_t error_handling);
00250 
00251 /* Establishes a modbus connexion.
00252    Returns -1 if an error occured. */
00253 int modbus_connect(modbus_param_t *mb_param);
00254 
00255 /* Closes a modbus connection */
00256 void modbus_close(modbus_param_t *mb_param);
00257 
00258 /* Activates the debug messages */
00259 void modbus_set_debug(modbus_param_t *mb_param, int boolean);
00260 
00261 /**
00262  * SLAVE/CLIENT FUNCTIONS 
00263  **/
00264 
00265 /* Allocates 4 arrays to store coils, input status, input registers and
00266    holding registers. The pointers are stored in modbus_mapping structure. 
00267 
00268    Returns: TRUE if ok, FALSE on failure
00269  */
00270 int modbus_mapping_new(modbus_mapping_t *mb_mapping,
00271                        int nb_coil_status, int nb_input_status,
00272                        int nb_holding_registers, int nb_input_registers);
00273 
00274 /* Frees the 4 arrays */
00275 void modbus_mapping_free(modbus_mapping_t *mb_mapping);
00276 
00277 
00278 /* Listens for any query from a modbus master in TCP 
00279    Not tested in RTU communication. */
00280 int modbus_listen(modbus_param_t *mb_param, uint8_t *query, int *query_length);
00281 
00282 /* Manages the received query.
00283    Analyses the query and constructs a response.
00284 
00285    If an error occurs, this function construct the response
00286    accordingly.
00287 */
00288 void modbus_manage_query(modbus_param_t *mb_param, const uint8_t *query,
00289                          int query_length, modbus_mapping_t *mb_mapping);
00290 
00291 
00292 /** 
00293  * UTILS FUNCTIONS
00294  **/
00295 
00296 /* Sets many input/coil status from a single byte value (all 8 bits of
00297    the byte value are setted) */
00298 void set_bits_from_byte(uint8_t *dest, int address, const uint8_t value);
00299 
00300 /* Sets many input/coil status from a table of bytes (only the bits
00301    between address and address + nb_bits are setted) */
00302 void set_bits_from_bytes(uint8_t *dest, int address, int nb_bits,
00303                          const uint8_t *tab_byte);
00304 
00305 /* Gets the byte value from many input/coil status.
00306    To obtain a full byte, set nb_bits to 8. */
00307 uint8_t get_byte_from_bits(const uint8_t *src, int address, int nb_bits);
00308 
00309  int build_query_basis_rtu(int slave, int function,
00310                                  int start_addr, int nb,
00311                                  uint8_t *query);
00312  int modbus_send(modbus_param_t *mb_param, uint8_t *query,
00313                        int query_length);
00314            
00315  int modbus_receive(modbus_param_t *mb_param, 
00316                           uint8_t *query,
00317                           uint8_t *response);
00318                  int receive_msg(modbus_param_t *mb_param,
00319                        int msg_length_computed,
00320                        uint8_t *msg, int *p_msg_length);     
00321