Jason Engelman
/
Adaptronictmp
First Working Master with Adaptronic simulator
Embed:
(wiki syntax)
Show/hide line numbers
modbus.h
00001 /* 00002 * Copyright � 2001-2008 St�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�MBUS�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
Generated on Wed Jul 20 2022 21:56:37 by 1.7.2