mb2hal.h
1 #include <stdlib.h> 2 #include <signal.h> 3 #include <sys/time.h> 4 #include <string.h> 5 #include <unistd.h> 6 #include <pthread.h> 7 8 #include "rtapi.h" 9 #ifdef RTAPI 10 #include "rtapi_app.h" 11 #endif 12 #include "rtapi_string.h" 13 #include "rtapi_errno.h" 14 #include "hal.h" 15 #include "inifile.h" 16 17 #include <modbus.h> 18 19 #define MB2HAL_MAX_LINKS 32 20 #define MB2HAL_MAX_DEVICE_LENGTH 32 21 #define MB2HAL_DEFAULT_TCP_PORT 502 22 #define MB2HAL_DEFAULT_MB_RESPONSE_TIMEOUT_MS 500 23 #define MB2HAL_DEFAULT_MB_BYTE_TIMEOUT_MS 500 24 #define MB2HAL_DEFAULT_TCP_PORT 502 25 #define MB2HAL_MAX_FNCT02_ELEMENTS 100 26 #define MB2HAL_MAX_FNCT03_ELEMENTS 100 27 #define MB2HAL_MAX_FNCT04_ELEMENTS 100 28 #define MB2HAL_MAX_FNCT05_ELEMENTS 100 29 #define MB2HAL_MAX_FNCT06_ELEMENTS 1 30 #define MB2HAL_MAX_FNCT15_ELEMENTS 100 31 #define MB2HAL_MAX_FNCT16_ELEMENTS 100 32 33 #ifdef MODULE_VERBOSE 34 MODULE_VERBOSE(emc2, "component:mb2hal:Userspace HAL component to communicate with one or more Modbus devices"); 35 MODULE_VERBOSE(emc2, "license:LGPL"); 36 MODULE_LICENSE("LGPL"); 37 #endif 38 39 typedef enum { linkRTU, 40 linkTCP 41 } link_type_t; 42 43 typedef enum { mbtxERR, 44 mbtx_02_READ_DISCRETE_INPUTS, 45 mbtx_03_READ_HOLDING_REGISTERS, 46 mbtx_04_READ_INPUT_REGISTERS, 47 mbtx_06_WRITE_SINGLE_REGISTER, 48 mbtx_15_WRITE_MULTIPLE_COILS, 49 mbtx_16_WRITE_MULTIPLE_REGISTERS, 50 mbtxMAX 51 } mb_tx_fnct; //modbus transaction code 52 typedef enum { debugSILENT, debugERR, debugOK, debugDEBUG, debugMAX 53 } DEBUG_TYPE; //message levels 54 typedef enum { retOK, retOKwithWarning, retERR 55 } retCode; //funtions return codes 56 57 #define ERR(debug, fmt, args...) if(debug >= debugERR) {fprintf(stderr, "%s %s ERR: "fmt"\n", gbl.hal_mod_name, fnct_name, ## args);} 58 #define OK(debug, fmt, args...) if(debug >= debugOK) {fprintf(stdout, "%s %s OK: "fmt"\n", gbl.hal_mod_name, fnct_name, ## args);} 59 #define DBG(debug, fmt, args...) if(debug >= debugDEBUG) {fprintf(stdout, "%s %s DEBUG: "fmt"\n", gbl.hal_mod_name, fnct_name, ## args);} 60 61 //Modbus transaction structure (mb_tx_t) 62 //Store each transaction defined in INI config file 63 //Plus HAL and run time parameters for each transaction 64 typedef struct { 65 //cfg_* are link params only for INI config reading purpose 66 //then we use the parameters of mb_link_t 67 link_type_t cfg_link_type; //RTU (serial) or TCP 68 char cfg_link_type_str[10]; //str version of lp_link_type 69 char cfg_serial_device[MB2HAL_MAX_DEVICE_LENGTH]; //device: example "/dev/ttyS0" 70 int cfg_serial_baud; //bauds 71 char cfg_serial_parity[5]; //parity: "even", "odd", "none" 72 int cfg_serial_data_bit; //data bit 73 int cfg_serial_stop_bit; //stop bit 74 int cfg_serial_delay_ms; //delay between tx in serial lines 75 char cfg_tcp_ip[17]; //tcp address 76 int cfg_tcp_port; //tcp port number 77 //mb_* are Modbus transaction protocol related params 78 int mb_tx_slave_id; //MB device id 79 mb_tx_fnct mb_tx_fnct; //MB function code id 80 char mb_tx_fnct_name[64]; //str version of mb_tx_fnct 81 int mb_tx_1st_addr; //MB first register 82 int mb_tx_nelem; //MB n registers 83 char ** mb_tx_names; //MB register pin names. NULL if no names are specified 84 int mb_response_timeout_ms; //MB response timeout 85 int mb_byte_timeout_ms; //MB byte timeout 86 //cfg_* are others INI config params 87 double cfg_update_rate; //tx update rate 88 int cfg_debug; //tx debug level (program, may be also protocol) 89 //Modbus protocol debug 90 int protocol_debug; //Flag debug Modbus protocol 91 //internal processing values 92 int mb_tx_num; //each tx know it's own number 93 int mb_link_num; //each tx know it's own link 94 //internal processing values 95 double time_increment; //wait time between tx 96 double next_time; //next time for this tx 97 double last_time_ok; //last OK tx time 98 //HAL related params 99 char hal_tx_name[HAL_NAME_LEN + 1]; 100 hal_float_t **float_value; 101 hal_s32_t **int_value; 102 //hal_float_t *scale; //not yet implemented 103 //hal_float_t *offset; //not yet implemented 104 hal_bit_t **bit; 105 hal_u32_t **num_errors; //num of acummulated errors (0=last tx OK) 106 } mb_tx_t; 107 108 //Modbus link structure (mb_link_t) 109 //Group common transaction's links in one unique link 110 //Store each run time Modbus link parameters here 111 typedef struct { 112 //lp_* are real link params for real time use 113 link_type_t lp_link_type; //RTU (serial) or TCP 114 char lp_type_com_str[10]; //str version of lp_type_com 115 char lp_serial_device[MB2HAL_MAX_DEVICE_LENGTH]; //device: example "/dev/ttyS0" 116 int lp_serial_baud; //bauds 117 char lp_serial_parity; //parity: 'E', 'O', 'N' 118 //NOTE in mb_tx is "even", "odd", "none" 119 int lp_serial_data_bit; //data bit 120 int lp_serial_stop_bit; //stop bit 121 int lp_serial_delay_ms; //delay between tx in serial lines 122 char lp_tcp_ip[17]; //tcp address 123 int lp_tcp_port; //tcp port number 124 //run time processing values 125 int mb_link_num; //corresponding number of this link/thread 126 modbus_t *modbus; 127 pthread_t thrd; 128 } mb_link_t; 129 130 //Structure of global data (gbl_t) 131 //Reduce functions parameters using this common global structure. 132 typedef struct { 133 //INI config file 134 FILE *ini_file_ptr; 135 char *ini_file_path; 136 //INI config, common section 137 int init_dbg; 138 double slowdown; 139 //HAL related 140 int hal_mod_id; 141 char *hal_mod_name; 142 //mb_tx 143 mb_tx_t *mb_tx; 144 int tot_mb_tx; 145 //mb_links 146 mb_link_t *mb_links; 147 int tot_mb_links; 148 //others 149 const char *mb_tx_fncts[mbtxMAX]; 150 int quit_flag; 151 } gbl_t; 152 153 extern gbl_t gbl; 154 155 //mb2hal.c 156 void *link_loop_and_logic(void *thrd_link_num); 157 retCode is_this_tx_ready(const int this_mb_link_num, const int this_mb_tx_num, int *ret_available); 158 retCode get_tx_connection(const int mb_tx_num, int *ret_connected); 159 void set_init_gbl_params(); 160 double get_time(); 161 void quit_signal(int signal); 162 void quit_cleanup(void); 163 164 //mb2hal_init.c 165 retCode parse_main_args(int argc, char **argv); 166 retCode parse_ini_file(); 167 retCode parse_common_section(); 168 retCode parse_transaction_section(const int mb_tx_num); 169 retCode parse_tcp_subsection(const char *section, const int mb_tx_num); 170 retCode parse_serial_subsection(const char *section, const int mb_tx_num); 171 retCode check_int_in(int n_args, const int int_value, ...); 172 retCode check_str_in(int n_args, const char *str_value, ...); 173 retCode init_mb_links(); 174 retCode init_mb_tx(); 175 176 //mb2hal_hal.c 177 retCode create_HAL_pins(); 178 retCode create_each_mb_tx_hal_pins(mb_tx_t *mb_tx); 179 180 //mb2hal_modbus.c 181 retCode fnct_15_write_multiple_coils(mb_tx_t *this_mb_tx, mb_link_t *this_mb_link); 182 retCode fnct_02_read_discrete_inputs(mb_tx_t *this_mb_tx, mb_link_t *this_mb_link); 183 retCode fnct_04_read_input_registers(mb_tx_t *this_mb_tx, mb_link_t *this_mb_link); 184 retCode fnct_03_read_holding_registers(mb_tx_t *this_mb_tx, mb_link_t *this_mb_link); 185 retCode fnct_06_write_single_register(mb_tx_t *this_mb_tx, mb_link_t *this_mb_link); 186 retCode fnct_16_write_multiple_registers(mb_tx_t *this_mb_tx, mb_link_t *this_mb_link);