Commit 1660f89490e1eed3f25fe0163d132a9380250dcd

Authored by Stéphane Raimbault
1 parent 07ae7c91

Various changes

- declare some functions static
- use uint8_t and uint16_t in various places to reduce memory use, the transition is not complete and will break compilation of some applications
- add some new functions to get/set bits from one or many bytes:
  o set_bits_from_byte
  o set_bits_from_bytes
  o get_byte_from_bits
- the server (slave) detects a connection closing
Showing 2 changed files with 181 additions and 111 deletions
modbus/modbus.c
... ... @@ -32,6 +32,7 @@
32 32 #include <stdio.h>
33 33 #include <string.h>
34 34 #include <stdlib.h>
  35 +#include <stdint.h>
35 36 #include <termios.h>
36 37 #include <sys/time.h>
37 38 #include <unistd.h>
... ... @@ -57,7 +58,7 @@
57 58  
58 59 #define UNKNOWN_ERROR_MSG "Not defined in modbus specification"
59 60  
60   -static const int SIZE_TAB_ERROR_MSG = 12;
  61 +static const uint8_t NB_TAB_ERROR_MSG = 12;
61 62 static const char *TAB_ERROR_MSG[] = {
62 63 /* 0x00 */ UNKNOWN_ERROR_MSG,
63 64 /* 0x01 */ "Illegal function code",
... ... @@ -74,7 +75,7 @@ static const char *TAB_ERROR_MSG[] = {
74 75 };
75 76  
76 77 /* Table of CRC values for high-order byte */
77   -static unsigned char table_crc_hi[] = {
  78 +static uint8_t table_crc_hi[] = {
78 79 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
79 80 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
80 81 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
... ... @@ -104,7 +105,7 @@ static unsigned char table_crc_hi[] = {
104 105 };
105 106  
106 107 /* Table of CRC values for low-order byte */
107   -static unsigned char table_crc_lo[] = {
  108 +static uint8_t table_crc_lo[] = {
108 109 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
109 110 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
110 111 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
... ... @@ -135,8 +136,7 @@ static unsigned char table_crc_lo[] = {
135 136  
136 137 /* Local declaration */
137 138 static int read_reg_response(modbus_param_t *mb_param,
138   - int *data_dest,
139   - unsigned char *query);
  139 + uint16_t *data_dest, uint8_t *query);
140 140  
141 141 /* Treats errors and flush or close connection if necessary */
142 142 static void error_treat(int ret, const char *string, modbus_param_t *mb_param)
... ... @@ -157,7 +157,7 @@ static void error_treat(int ret, const char *string, modbus_param_t *mb_param)
157 157  
158 158 /* Computes the size of the expected response */
159 159 static unsigned int compute_response_size(modbus_param_t *mb_param,
160   - unsigned char *query)
  160 + uint8_t *query)
161 161 {
162 162 int response_size_computed;
163 163 int offset;
... ... @@ -171,7 +171,7 @@ static unsigned int compute_response_size(modbus_param_t *mb_param,
171 171 int coil_count = (query[offset + 4] << 8) | query[offset + 5];
172 172 response_size_computed = 3 +
173 173 (coil_count / 8) + ((coil_count % 8) ? 1 : 0);
174   - }
  174 + }
175 175 break;
176 176 case FC_READ_HOLDING_REGISTERS:
177 177 case FC_READ_INPUT_REGISTERS:
... ... @@ -192,8 +192,9 @@ static unsigned int compute_response_size(modbus_param_t *mb_param,
192 192 }
193 193  
194 194 /* Buils a RTU header */
195   -int build_query_packet_rtu(int slave, int function, int start_addr,
196   - int count, unsigned char *packet)
  195 +static int build_query_packet_rtu(uint8_t slave, uint8_t function,
  196 + uint16_t start_addr, uint16_t count,
  197 + uint8_t *packet)
197 198 {
198 199 packet[0] = slave;
199 200 packet[1] = function;
... ... @@ -206,13 +207,14 @@ int build_query_packet_rtu(int slave, int function, int start_addr,
206 207 }
207 208  
208 209 /* Builds a TCP header */
209   -int build_query_packet_tcp(int slave, int function, int start_addr,
210   - int count, unsigned char *packet)
  210 +static int build_query_packet_tcp(uint8_t slave, uint8_t function,
  211 + uint16_t start_addr, uint16_t count,
  212 + uint8_t *packet)
211 213 {
212   - static unsigned short t_id = 0;
  214 + static uint16_t t_id = 0;
213 215  
214 216 /* Transaction ID */
215   - if (t_id < USHRT_MAX)
  217 + if (t_id < UINT16_MAX)
216 218 t_id++;
217 219 else
218 220 t_id = 0;
... ... @@ -235,9 +237,9 @@ int build_query_packet_tcp(int slave, int function, int start_addr,
235 237 return PRESET_QUERY_SIZE_TCP;
236 238 }
237 239  
238   -int build_query_packet(modbus_param_t *mb_param, int slave,
239   - int function, int start_addr,
240   - int count, unsigned char *packet)
  240 +static int build_query_packet(modbus_param_t *mb_param, uint8_t slave,
  241 + uint8_t function, uint16_t start_addr,
  242 + uint16_t count, uint8_t *packet)
241 243 {
242 244 if (mb_param->type_com == RTU)
243 245 return build_query_packet_rtu(slave, function, start_addr,
... ... @@ -248,7 +250,8 @@ int build_query_packet(modbus_param_t *mb_param, int slave,
248 250 }
249 251  
250 252  
251   -int build_response_packet_rtu(int slave, int function, int byte_count, unsigned char *packet)
  253 +static int build_response_packet_rtu(uint8_t slave, uint8_t function,
  254 + uint8_t byte_count, uint8_t *packet)
252 255 {
253 256 packet[0] = slave;
254 257 packet[1] = function;
... ... @@ -258,9 +261,10 @@ int build_response_packet_rtu(int slave, int function, int byte_count, unsigned
258 261 return PRESET_RESPONSE_SIZE_RTU+1;
259 262 }
260 263  
261   -int build_response_packet_tcp(int slave, int function, int byte_count, unsigned char *packet)
  264 +static int build_response_packet_tcp(uint8_t slave, uint8_t function,
  265 + uint8_t byte_count, uint8_t *packet)
262 266 {
263   - static unsigned short t_id = 0;
  267 + static uint16_t t_id = 0;
264 268  
265 269 /* Transaction ID */
266 270 if (t_id < USHRT_MAX)
... ... @@ -285,8 +289,8 @@ int build_response_packet_tcp(int slave, int function, int byte_count, unsigned
285 289 return PRESET_RESPONSE_SIZE_TCP+1;
286 290 }
287 291  
288   -int build_response_packet(modbus_param_t *mb_param, int slave,
289   - int function, int byte_count, unsigned char *packet)
  292 +static int build_response_packet(modbus_param_t *mb_param, uint8_t slave,
  293 + uint8_t function, uint8_t byte_count, uint8_t *packet)
290 294 {
291 295 if (mb_param->type_com == RTU)
292 296 return build_response_packet_rtu(slave, function, byte_count, packet);
... ... @@ -295,9 +299,9 @@ int build_response_packet(modbus_param_t *mb_param, int slave,
295 299 }
296 300  
297 301 /* Sets the length of TCP message in the message */
298   -void set_packet_length_tcp(unsigned char *packet, size_t packet_size)
  302 +void set_packet_length_tcp(uint8_t *packet, size_t packet_size)
299 303 {
300   - unsigned short mbap_length;
  304 + uint16_t mbap_length;
301 305  
302 306 /* Substract MBAP header length */
303 307 mbap_length = packet_size - 6;
... ... @@ -307,11 +311,11 @@ void set_packet_length_tcp(unsigned char *packet, size_t packet_size)
307 311 }
308 312  
309 313 /* Fast CRC */
310   -static unsigned short crc16(unsigned char *buffer,
311   - unsigned short buffer_length)
  314 +static uint16_t crc16(uint8_t *buffer,
  315 + uint16_t buffer_length)
312 316 {
313   - unsigned char crc_hi = 0xFF; /* high CRC byte initialized */
314   - unsigned char crc_lo = 0xFF; /* low CRC byte initialized */
  317 + uint8_t crc_hi = 0xFF; /* high CRC byte initialized */
  318 + uint8_t crc_lo = 0xFF; /* low CRC byte initialized */
315 319 unsigned int i; /* will index into CRC lookup */
316 320  
317 321 /* pass through message buffer */
... ... @@ -326,14 +330,14 @@ static unsigned short crc16(unsigned char *buffer,
326 330  
327 331 /* If CRC is correct returns 0 else returns INVALID_CRC */
328 332 int check_crc16(modbus_param_t *mb_param,
329   - unsigned char *msg,
  333 + uint8_t *msg,
330 334 int msg_size)
331 335 {
332 336 int ret;
333 337  
334 338 if (mb_param->type_com == RTU) {
335   - unsigned short crc_calc;
336   - unsigned short crc_received;
  339 + uint16_t crc_calc;
  340 + uint16_t crc_received;
337 341  
338 342 crc_calc = crc16(msg, msg_size - 2);
339 343 crc_received = (msg[msg_size - 2] << 8) | msg[msg_size - 1];
... ... @@ -357,11 +361,11 @@ int check_crc16(modbus_param_t *mb_param,
357 361 }
358 362  
359 363 /* Sends a query/response over a serial or a TCP communication */
360   -static int modbus_send(modbus_param_t *mb_param, unsigned char *query,
  364 +static int modbus_send(modbus_param_t *mb_param, uint8_t *query,
361 365 size_t query_size)
362 366 {
363 367 int write_ret;
364   - unsigned short s_crc;
  368 + uint16_t s_crc;
365 369 int i;
366 370  
367 371 if (mb_param->type_com == RTU) {
... ... @@ -396,9 +400,9 @@ static int modbus_send(modbus_param_t *mb_param, unsigned char *query,
396 400 }
397 401  
398 402 /* Computes the size of the header following the function code */
399   -int compute_query_size_header(int function)
  403 +static uint8_t compute_query_size_header(uint8_t function)
400 404 {
401   - int byte;
  405 + uint8_t byte;
402 406  
403 407 if (function <= FC_FORCE_SINGLE_COIL)
404 408 /* Read and single write */
... ... @@ -416,10 +420,10 @@ int compute_query_size_header(int function)
416 420 }
417 421  
418 422 /* Computes the size of the data to write in the query */
419   -int compute_query_size_data(modbus_param_t *mb_param, unsigned char *msg)
  423 +static uint8_t compute_query_size_data(modbus_param_t *mb_param, uint8_t *msg)
420 424 {
421   - int function = msg[mb_param->header_length + 1];
422   - int byte;
  425 + uint8_t function = msg[mb_param->header_length + 1];
  426 + uint8_t byte;
423 427  
424 428 if (function == FC_FORCE_MULTIPLE_COILS ||
425 429 function == FC_PRESET_MULTIPLE_REGISTERS)
... ... @@ -464,7 +468,7 @@ int compute_query_size_data(modbus_param_t *mb_param, unsigned char *msg)
464 468 - msg_size: number of characters received. */
465 469 int receive_msg(modbus_param_t *mb_param,
466 470 int msg_size_computed,
467   - unsigned char *msg,
  471 + uint8_t *msg,
468 472 int *msg_size)
469 473 {
470 474 int select_ret;
... ... @@ -472,7 +476,7 @@ int receive_msg(modbus_param_t *mb_param,
472 476 fd_set rfds;
473 477 struct timeval tv;
474 478 int size_to_read;
475   - unsigned char *p_msg;
  479 + uint8_t *p_msg;
476 480 enum { FUNCTION, BYTE, COMPLETE };
477 481 int state;
478 482  
... ... @@ -504,6 +508,8 @@ int receive_msg(modbus_param_t *mb_param,
504 508 }
505 509  
506 510 size_to_read = msg_size_computed;
  511 +
  512 + select_ret = 0;
507 513 WAIT_DATA();
508 514  
509 515 /* Read the msg */
... ... @@ -519,6 +525,9 @@ int receive_msg(modbus_param_t *mb_param,
519 525 if (read_ret == -1) {
520 526 error_treat(read_ret, "Read port/socket failure", mb_param);
521 527 return PORT_SOCKET_FAILURE;
  528 + } else if (read_ret == 0) {
  529 + printf("Connection closed\n");
  530 + return CONNECTION_CLOSED;
522 531 }
523 532  
524 533 /* Sums bytes received */
... ... @@ -593,8 +602,8 @@ int receive_msg(modbus_param_t *mb_param,
593 602 Note: All functions used to send or receive data with modbus return
594 603 these values. */
595 604 static int modbus_check_response(modbus_param_t *mb_param,
596   - unsigned char *query,
597   - unsigned char *response)
  605 + uint8_t *query,
  606 + uint8_t *response)
598 607 {
599 608 int response_size;
600 609 int response_size_computed; int offset = mb_param->header_length;
... ... @@ -648,7 +657,7 @@ static int modbus_check_response(modbus_param_t *mb_param,
648 657 0x80 + function */
649 658 if (0x80 + query[offset + 1] == response[offset + 1]) {
650 659  
651   - if (response[offset + 2] < SIZE_TAB_ERROR_MSG) {
  660 + if (response[offset + 2] < NB_TAB_ERROR_MSG) {
652 661 error_treat(0,
653 662 TAB_ERROR_MSG[response[offset + 2]],
654 663 mb_param);
... ... @@ -675,12 +684,12 @@ static int modbus_check_response(modbus_param_t *mb_param,
675 684 return response_size;
676 685 }
677 686  
678   -int response_io_status(int address, int count,
679   - int nb_io_status, unsigned char *tab_io_status,
680   - unsigned char *response, int offset)
  687 +static int response_io_status(uint8_t address, uint16_t count,
  688 + uint8_t *tab_io_status,
  689 + uint8_t *response, int offset)
681 690 {
682   - unsigned char shift = 0;
683   - unsigned char byte = 0;
  691 + uint8_t shift = 0;
  692 + uint8_t byte = 0;
684 693 int i;
685 694  
686 695 for (i = address; i < address+count; i++) {
... ... @@ -702,7 +711,7 @@ int response_io_status(int address, int count,
702 711  
703 712 /* Manages the received query.
704 713 Analyses the query and constructs a response */
705   -void manage_query(modbus_param_t *mb_param, unsigned char *query,
  714 +void manage_query(modbus_param_t *mb_param, uint8_t *query,
706 715 int query_size, modbus_mapping_t *mb_mapping)
707 716 {
708 717 int offset = mb_param->header_length;
... ... @@ -712,7 +721,7 @@ void manage_query(modbus_param_t *mb_param, unsigned char *query,
712 721 /* FIXME count/data */
713 722 int count;
714 723 int data;
715   - unsigned char response[MAX_PACKET_SIZE];
  724 + uint8_t response[MAX_PACKET_SIZE];
716 725 int byte_count;
717 726 int i;
718 727  
... ... @@ -723,16 +732,14 @@ void manage_query(modbus_param_t *mb_param, unsigned char *query,
723 732 count = (query[offset+4] << 8) + query[offset+5];
724 733 byte_count = (count / 8.0) + ((count % 8) ? 1 : 0);
725 734 offset = build_response_packet(mb_param, slave, function, byte_count, response);
726   - offset = response_io_status(address, count,
727   - mb_mapping->nb_coil_status, mb_mapping->tab_coil_status,
  735 + offset = response_io_status(address, count, mb_mapping->tab_coil_status,
728 736 response, offset);
729 737 break;
730 738 case FC_READ_INPUT_STATUS:
731 739 count = (query[offset+4] << 8) + query[offset+5];
732 740 byte_count = (count / 8.0) + ((count % 8) ? 1 : 0);
733 741 offset = build_response_packet(mb_param, slave, function, byte_count, response);
734   - offset = response_io_status(address, count,
735   - mb_mapping->nb_input_status, mb_mapping->tab_input_status,
  742 + offset = response_io_status(address, count, mb_mapping->tab_input_status,
736 743 response, offset);
737 744 break;
738 745 case FC_READ_HOLDING_REGISTERS:
... ... @@ -784,7 +791,7 @@ void manage_query(modbus_param_t *mb_param, unsigned char *query,
784 791 - 0 if OK, or a negative error number if the request fails
785 792 - query, message received
786 793 - query_size, size in bytes of the message */
787   -int modbus_listen(modbus_param_t *mb_param, unsigned char *query, int *query_size)
  794 +int modbus_listen(modbus_param_t *mb_param, uint8_t *query, int *query_size)
788 795 {
789 796 int ret;
790 797  
... ... @@ -798,14 +805,14 @@ int modbus_listen(modbus_param_t *mb_param, unsigned char *query, int *query_siz
798 805  
799 806 /* Reads IO status */
800 807 static int read_io_status(modbus_param_t *mb_param, int slave, int function,
801   - int start_addr, int count, int *data_dest)
  808 + int start_addr, int count, uint8_t *data_dest)
802 809 {
803 810 int query_size;
804 811 int query_ret;
805 812 int response_ret;
806 813  
807   - unsigned char query[MIN_QUERY_SIZE];
808   - unsigned char response[MAX_PACKET_SIZE];
  814 + uint8_t query[MIN_QUERY_SIZE];
  815 + uint8_t response[MAX_PACKET_SIZE];
809 816  
810 817 query_size = build_query_packet(mb_param, slave, function,
811 818 start_addr, count, query);
... ... @@ -843,7 +850,7 @@ static int read_io_status(modbus_param_t *mb_param, int slave, int function,
843 850 /* Reads the boolean status of coils and sets the array elements
844 851 in the destination to TRUE or FALSE. */
845 852 int read_coil_status(modbus_param_t *mb_param, int slave, int start_addr,
846   - int count, int *data_dest)
  853 + const int count, uint8_t *data_dest)
847 854 {
848 855 int status;
849 856  
... ... @@ -859,7 +866,7 @@ int read_coil_status(modbus_param_t *mb_param, int slave, int start_addr,
859 866  
860 867 /* Same as read_coil_status but reads the slaves input table */
861 868 int read_input_status(modbus_param_t *mb_param, int slave, int start_addr,
862   - int count, int *data_dest)
  869 + const int count, uint8_t *data_dest)
863 870 {
864 871 int status;
865 872  
... ... @@ -874,12 +881,12 @@ int read_input_status(modbus_param_t *mb_param, int slave, int start_addr,
874 881  
875 882 /* Reads the data from a modbus slave and put that data into an array */
876 883 static int read_registers(modbus_param_t *mb_param, int slave, int function,
877   - int start_addr, int count, int *data_dest)
  884 + int start_addr, int count, uint16_t *data_dest)
878 885 {
879 886 int query_size;
880 887 int status;
881 888 int query_ret;
882   - unsigned char query[MIN_QUERY_SIZE];
  889 + uint8_t query[MIN_QUERY_SIZE];
883 890  
884 891 query_size = build_query_packet(mb_param, slave, function,
885 892 start_addr, count, query);
... ... @@ -896,7 +903,7 @@ static int read_registers(modbus_param_t *mb_param, int slave, int function,
896 903 /* Reads the holding registers in a slave and put the data into an
897 904 array */
898 905 int read_holding_registers(modbus_param_t *mb_param, int slave,
899   - int start_addr, int count, int *data_dest)
  906 + int start_addr, int count, uint16_t *data_dest)
900 907 {
901 908 int status;
902 909  
... ... @@ -913,7 +920,7 @@ int read_holding_registers(modbus_param_t *mb_param, int slave,
913 920 /* Reads the input registers in a slave and put the data into
914 921 an array */
915 922 int read_input_registers(modbus_param_t *mb_param, int slave,
916   - int start_addr, int count, int *data_dest)
  923 + int start_addr, int count, uint16_t *data_dest)
917 924 {
918 925 int status;
919 926  
... ... @@ -930,10 +937,10 @@ int read_input_registers(modbus_param_t *mb_param, int slave,
930 937  
931 938 /* Reads the response data from a slave and puts the data into an
932 939 array */
933   -static int read_reg_response(modbus_param_t *mb_param, int *data_dest,
934   - unsigned char *query)
  940 +static int read_reg_response(modbus_param_t *mb_param, uint16_t *data_dest,
  941 + uint8_t *query)
935 942 {
936   - unsigned char response[MAX_PACKET_SIZE];
  943 + uint8_t response[MAX_PACKET_SIZE];
937 944 int response_ret;
938 945 int offset;
939 946 int i;
... ... @@ -953,10 +960,10 @@ static int read_reg_response(modbus_param_t *mb_param, int *data_dest,
953 960 }
954 961  
955 962 /* Gets the raw data from the input stream */
956   -static int preset_response(modbus_param_t *mb_param, unsigned char *query)
  963 +static int preset_response(modbus_param_t *mb_param, uint8_t *query)
957 964 {
958 965 int ret;
959   - unsigned char response[MAX_PACKET_SIZE];
  966 + uint8_t response[MAX_PACKET_SIZE];
960 967  
961 968 ret = modbus_check_response(mb_param, query, response);
962 969  
... ... @@ -970,7 +977,7 @@ static int set_single(modbus_param_t *mb_param, int slave, int function,
970 977 int status;
971 978 int query_size;
972 979 int query_ret;
973   - unsigned char query[MAX_PACKET_SIZE];
  980 + uint8_t query[MAX_PACKET_SIZE];
974 981  
975 982 query_size = build_query_packet(mb_param, slave, function,
976 983 addr, value, query);
... ... @@ -1014,7 +1021,7 @@ int preset_single_register(modbus_param_t *mb_param, int slave,
1014 1021 appropriatly */
1015 1022 int force_multiple_coils(modbus_param_t *mb_param, int slave,
1016 1023 int start_addr, int coil_count,
1017   - int *data_src)
  1024 + uint8_t *data_src)
1018 1025 {
1019 1026 int i;
1020 1027 int byte_count;
... ... @@ -1024,7 +1031,7 @@ int force_multiple_coils(modbus_param_t *mb_param, int slave,
1024 1031 int query_ret;
1025 1032 int pos = 0;
1026 1033  
1027   - unsigned char query[MAX_PACKET_SIZE];
  1034 + uint8_t query[MAX_PACKET_SIZE];
1028 1035  
1029 1036 if (coil_count > MAX_WRITE_COILS) {
1030 1037 printf("WARNING Writing to too many coils\n");
... ... @@ -1064,7 +1071,7 @@ int force_multiple_coils(modbus_param_t *mb_param, int slave,
1064 1071  
1065 1072 /* Copies the values in an array to an array on the slave */
1066 1073 int preset_multiple_registers(modbus_param_t *mb_param, int slave,
1067   - int start_addr, int reg_count, int *data_src)
  1074 + int start_addr, int reg_count, uint16_t *data_src)
1068 1075 {
1069 1076 int i;
1070 1077 int query_size;
... ... @@ -1072,7 +1079,7 @@ int preset_multiple_registers(modbus_param_t *mb_param, int slave,
1072 1079 int status;
1073 1080 int query_ret;
1074 1081  
1075   - unsigned char query[MAX_PACKET_SIZE];
  1082 + uint8_t query[MAX_PACKET_SIZE];
1076 1083  
1077 1084 if (reg_count > MAX_WRITE_REGS) {
1078 1085 printf("WARNING Trying to write to too many registers\n");
... ... @@ -1101,14 +1108,14 @@ int preset_multiple_registers(modbus_param_t *mb_param, int slave,
1101 1108  
1102 1109 /* Returns the slave id ! */
1103 1110 int report_slave_id(modbus_param_t *mb_param, int slave,
1104   - unsigned char *data_dest)
  1111 + uint8_t *data_dest)
1105 1112 {
1106 1113 int query_size;
1107 1114 int query_ret;
1108 1115 int response_ret;
1109 1116  
1110   - unsigned char query[MIN_QUERY_SIZE];
1111   - unsigned char response[MAX_PACKET_SIZE];
  1117 + uint8_t query[MIN_QUERY_SIZE];
  1118 + uint8_t response[MAX_PACKET_SIZE];
1112 1119  
1113 1120 query_size = build_query_packet(mb_param, slave, FC_REPORT_SLAVE_ID,
1114 1121 0, 0, query);
... ... @@ -1519,46 +1526,45 @@ int modbus_connect(modbus_param_t *mb_param)
1519 1526 holding registers. The pointers are stored in modbus_mapping structure.
1520 1527  
1521 1528 Returns: TRUE if ok, FALSE on failure
1522   -
1523 1529 */
1524 1530 int modbus_mapping_new(modbus_mapping_t *mb_mapping,
1525 1531 int nb_coil_status, int nb_input_status,
1526   - int nb_input_registers, int nb_holding_registers)
  1532 + int nb_holding_registers, int nb_input_registers)
1527 1533 {
1528 1534 /* 0X */
1529 1535 mb_mapping->nb_coil_status = nb_coil_status;
1530   - mb_mapping->tab_coil_status = (unsigned char *) malloc(nb_coil_status * sizeof(unsigned char));
1531   - memset(mb_mapping->tab_coil_status, 0, nb_coil_status * sizeof(unsigned char));
  1536 + mb_mapping->tab_coil_status = (uint8_t *) malloc(nb_coil_status * sizeof(uint8_t));
  1537 + memset(mb_mapping->tab_coil_status, 0, nb_coil_status * sizeof(uint8_t));
1532 1538 if (mb_mapping->tab_coil_status == NULL)
1533 1539 return FALSE;
1534 1540  
1535 1541 /* 1X */
1536 1542 mb_mapping->nb_input_status = nb_input_status;
1537   - mb_mapping->tab_input_status = (unsigned char *) malloc(nb_input_status * sizeof(unsigned char));
1538   - memset(mb_mapping->tab_input_status, 0, nb_input_status * sizeof(unsigned char));
  1543 + mb_mapping->tab_input_status = (uint8_t *) malloc(nb_input_status * sizeof(uint8_t));
  1544 + memset(mb_mapping->tab_input_status, 0, nb_input_status * sizeof(uint8_t));
1539 1545 if (mb_mapping->tab_input_status == NULL) {
1540 1546 free(mb_mapping->tab_coil_status);
1541 1547 return FALSE;
1542 1548 }
1543 1549  
1544   - /* 3X */
1545   - mb_mapping->nb_input_registers = nb_input_registers;
1546   - mb_mapping->tab_input_registers = (unsigned short *) malloc(nb_input_registers * sizeof(unsigned short));
1547   - memset(mb_mapping->tab_input_registers, 0, nb_input_registers * sizeof(unsigned short));
1548   - if (mb_mapping->tab_input_registers == NULL) {
  1550 + /* 4X */
  1551 + mb_mapping->nb_holding_registers = nb_holding_registers;
  1552 + mb_mapping->tab_holding_registers = (uint16_t *) malloc(nb_holding_registers * sizeof(uint16_t));
  1553 + memset(mb_mapping->tab_holding_registers, 0, nb_holding_registers * sizeof(uint16_t));
  1554 + if (mb_mapping->tab_holding_registers == NULL) {
1549 1555 free(mb_mapping->tab_coil_status);
1550 1556 free(mb_mapping->tab_input_status);
1551 1557 return FALSE;
1552 1558 }
1553 1559  
1554   - /* 4X */
1555   - mb_mapping->nb_holding_registers = nb_holding_registers;
1556   - mb_mapping->tab_holding_registers = (unsigned short *) malloc(nb_holding_registers * sizeof(unsigned short));
1557   - memset(mb_mapping->tab_holding_registers, 0, nb_holding_registers * sizeof(unsigned short));
1558   - if (mb_mapping->tab_holding_registers == NULL) {
  1560 + /* 3X */
  1561 + mb_mapping->nb_input_registers = nb_input_registers;
  1562 + mb_mapping->tab_input_registers = (uint16_t *) malloc(nb_input_registers * sizeof(uint16_t));
  1563 + memset(mb_mapping->tab_input_registers, 0, nb_input_registers * sizeof(uint16_t));
  1564 + if (mb_mapping->tab_input_registers == NULL) {
1559 1565 free(mb_mapping->tab_coil_status);
1560 1566 free(mb_mapping->tab_input_status);
1561   - free(mb_mapping->tab_input_registers);
  1567 + free(mb_mapping->tab_holding_registers);
1562 1568 return FALSE;
1563 1569 }
1564 1570  
... ... @@ -1570,11 +1576,11 @@ void modbus_mapping_free(modbus_mapping_t *mb_mapping)
1570 1576 {
1571 1577 free(mb_mapping->tab_coil_status);
1572 1578 free(mb_mapping->tab_input_status);
1573   - free(mb_mapping->tab_input_registers);
1574 1579 free(mb_mapping->tab_holding_registers);
  1580 + free(mb_mapping->tab_input_registers);
1575 1581 }
1576 1582  
1577   -/* Listens for any query from a modbus master */
  1583 +/* Listens for any query from a modbus master in TCP */
1578 1584 int modbus_init_listen_tcp(modbus_param_t *mb_param)
1579 1585 {
1580 1586 int ret;
... ... @@ -1660,3 +1666,51 @@ void modbus_set_debug(modbus_param_t *mb_param, int boolean)
1660 1666 {
1661 1667 mb_param->debug = boolean;
1662 1668 }
  1669 +
  1670 +/** Utils **/
  1671 +
  1672 +/* Set many inputs/coils form a single byte value (all 8 bits of the
  1673 + byte value are setted) */
  1674 +void set_bits_from_byte(uint8_t *dest, uint16_t address, const uint8_t value)
  1675 +{
  1676 + int i;
  1677 +
  1678 + for (i=0; i<8; i++) {
  1679 + dest[address+i] = (value & (1 << i)) ? ON : OFF;
  1680 + }
  1681 +}
  1682 +
  1683 +/* Set many inputs/coils from a table of bytes (only the bits between
  1684 + address and address + nb_bits are setted) */
  1685 +void set_bits_from_bytes(uint8_t *dest, uint16_t address, uint16_t nb_bits, const uint8_t tab_byte[])
  1686 +{
  1687 + int i;
  1688 + int shift = 0;
  1689 +
  1690 + for (i=address; i < address + nb_bits; i++) {
  1691 + dest[i] = tab_byte[(i - address) / 8] & (1 << shift) ? ON : OFF;
  1692 + /* gcc doesn't like: shift = (++shift) % 8; */
  1693 + shift++;
  1694 + shift %= 8;
  1695 + }
  1696 +}
  1697 +
  1698 +/* Get the byte value from many inputs/coils.
  1699 + To obtain a full byte, set nb_bits to 8. */
  1700 +uint8_t get_byte_from_bits(const uint8_t *src, uint16_t address, int nb_bits)
  1701 +{
  1702 + int i;
  1703 + uint8_t value = 0;
  1704 +
  1705 + if (nb_bits > 8) {
  1706 + printf("Error: nb_bits is too big\n");
  1707 + nb_bits = 8;
  1708 + }
  1709 +
  1710 + for (i=0; i<nb_bits; i++) {
  1711 + value |= (src[address+i] << i);
  1712 + }
  1713 +
  1714 + return value;
  1715 +}
  1716 +
... ...
modbus/modbus.h
... ... @@ -20,6 +20,7 @@
20 20 #ifndef _MODBUS_H_
21 21 #define _MODBUS_H_
22 22  
  23 +#include <stdint.h>
23 24 #include <termios.h>
24 25 #include <arpa/inet.h>
25 26  
... ... @@ -103,6 +104,7 @@
103 104 #define TOO_MANY_DATAS -0x0F
104 105 #define INVALID_CRC -0x10
105 106 #define INVALID_EXCEPTION_CODE -0x11
  107 +#define CONNECTION_CLOSED -0x12
106 108  
107 109 /* Internal using */
108 110 #define MSG_SIZE_UNDEFINED -1
... ... @@ -158,10 +160,10 @@ typedef struct {
158 160 int nb_input_status;
159 161 int nb_input_registers;
160 162 int nb_holding_registers;
161   - unsigned char *tab_coil_status;
162   - unsigned char *tab_input_status;
163   - unsigned short *tab_input_registers;
164   - unsigned short *tab_holding_registers;
  163 + uint8_t *tab_coil_status;
  164 + uint8_t *tab_input_status;
  165 + uint16_t *tab_input_registers;
  166 + uint16_t *tab_holding_registers;
165 167 } modbus_mapping_t;
166 168  
167 169 /* All functions used for sending or receiving data return :
... ... @@ -172,22 +174,21 @@ typedef struct {
172 174 /* Reads the boolean status of coils and sets the array elements in
173 175 the destination to TRUE or FALSE */
174 176 int read_coil_status(modbus_param_t *mb_param, int slave,
175   - int start_addr, int count, int *dest);
  177 + int start_addr, int count, uint8_t *dest);
176 178  
177 179 /* Same as read_coil_status but reads the slaves input table */
178 180 int read_input_status(modbus_param_t *mb_param, int slave,
179   - int start_addr, int count, int *dest);
  181 + int start_addr, int count, uint8_t *dest);
180 182  
181 183 /* Reads the holding registers in a slave and put the data into an
182 184 array */
183 185 int read_holding_registers(modbus_param_t *mb_param, int slave,
184   - int start_addr, int count, int *dest);
185   -
  186 + int start_addr, int count, uint16_t *dest);
186 187  
187 188 /* Reads the input registers in a slave and put the data into an
188 189 array */
189 190 int read_input_registers(modbus_param_t *mb_param, int slave,
190   - int start_addr, int count, int *dest);
  191 + int start_addr, int count, uint16_t *dest);
191 192  
192 193 /* Turns on or off a single coil on the slave device */
193 194 int force_single_coil(modbus_param_t *mb_param, int slave,
... ... @@ -200,15 +201,14 @@ int preset_single_register(modbus_param_t *mb_param, int slave,
200 201 /* Takes an array of ints and sets or resets the coils on a slave
201 202 appropriatly */
202 203 int force_multiple_coils(modbus_param_t *mb_param, int slave,
203   - int start_addr, int coil_count, int *data);
  204 + int start_addr, int coil_count, uint8_t *data);
204 205  
205 206 /* Copy the values in an array to an array on the slave */
206 207 int preset_multiple_registers(modbus_param_t *mb_param, int slave,
207   - int start_addr, int reg_count, int *data);
  208 + int start_addr, int reg_count, uint16_t *data);
208 209  
209 210 /* Returns some useful information about the modbus controller */
210   -int report_slave_id(modbus_param_t *mb_param, int slave,
211   - unsigned char *dest);
  211 +int report_slave_id(modbus_param_t *mb_param, int slave, uint8_t *dest);
212 212  
213 213 /* Initialises a parameters structure
214 214 - device : "/dev/ttyS0"
... ... @@ -259,18 +259,34 @@ void modbus_set_debug(modbus_param_t *mb_param, int boolean);
259 259 /* Slave/client functions */
260 260 int modbus_mapping_new(modbus_mapping_t *mb_mapping,
261 261 int nb_coil_status, int nb_input_status,
262   - int nb_input_registers, int nb_holding_registers);
  262 + int nb_holding_registers, int nb_input_registers);
263 263 void modbus_mapping_free(modbus_mapping_t *mb_mapping);
264 264  
265 265 int modbus_init_listen_tcp(modbus_param_t *mb_param);
266 266  
267   -int modbus_listen(modbus_param_t *mb_param, unsigned char *query, int *query_size);
  267 +int modbus_listen(modbus_param_t *mb_param, uint8_t *query, int *query_size);
268 268  
269   -void manage_query(modbus_param_t *mb_param, unsigned char *query,
  269 +void manage_query(modbus_param_t *mb_param, uint8_t *query,
270 270 int query_size, modbus_mapping_t *mb_mapping);
271 271  
272 272 /* Not implemented :
273 273 - read_exception_status()
274 274 */
275 275  
  276 +/** Utils **/
  277 +
  278 +/* Set many inputs/coils form a single byte value (all 8 bits of the
  279 + byte value are setted) */
  280 +void set_bits_from_byte(uint8_t *dest, uint16_t address,
  281 + const uint8_t value);
  282 +
  283 +/* Set many inputs/coils from a table of bytes (only the bits between
  284 + address and address + nb_bits are setted) */
  285 +void set_bits_from_bytes(uint8_t *dest, uint16_t address, uint16_t nb_bits,
  286 + const uint8_t *tab_byte);
  287 +
  288 +/* Get the byte value from many inputs/coils.
  289 + To obtain a full byte, set nb_bits to 8. */
  290 +uint8_t get_byte_from_bits(const uint8_t *src, uint16_t address, int nb_bits);
  291 +
276 292 #endif /* _MODBUS_H_ */
... ...