Variables start_addr and count were read from query_packet using function mb_ntoh_safe. It looks like some compilers change the pointer alignment if the first byte starts at an odd address. Because mb_ntoh_safe uses pointers slave address and count (number of registers) were not read correctly from the buffer when several modbus slaves were present in network. In this temporary solution pointer aritmetics is replaced by simple 256 multiplication.
authorbmakuc <blaz.makuc@smarteh.si>
Wed, 27 Nov 2019 14:53:22 +0100
changeset 4 99009b24d401
parent 3 1223f413e054
child 5 6e94a1dddc5f
Variables start_addr and count were read from query_packet using function mb_ntoh_safe. It looks like some compilers change the pointer alignment if the first byte starts at an odd address. Because mb_ntoh_safe uses pointers slave address and count (number of registers) were not read correctly from the buffer when several modbus slaves were present in network. In this temporary solution pointer aritmetics is replaced by simple 256 multiplication.
mb_slave.c
--- a/mb_slave.c	Mon Feb 11 11:07:01 2019 +0100
+++ b/mb_slave.c	Wed Nov 27 14:53:22 2019 +0100
@@ -312,8 +312,10 @@
      *   requiring the user to use addressing starting off at 0! 
      */
   /* start_addr = mb_ntoh(u16_v(query_packet[2])) + 1; */
-  mb_ntoh_safe(u16_v(query_packet[2]), &start_addr);
-  mb_ntoh_safe(u16_v(query_packet[4]), &count); 
+//  mb_ntoh_safe(u16_v(query_packet[2]), &start_addr);
+//  mb_ntoh_safe(u16_v(query_packet[4]), &count); 
+  start_addr = query_packet[2] * 256 + query_packet[3]; /* Temporary pointer alignment fix */
+  count = query_packet[4] * 256 + query_packet[5];      /* Temporary pointer alignment fix */
 
   #ifdef DEBUG
   printf("handle_read_input_bits() called. slave=%d, function=%d, start_addr=%d, count=%d\n", 
@@ -376,8 +378,10 @@
   resp_packet = *resp_packet_ptr;
   
   /* See equivalent comment in handle_read_bits() */ 
-  mb_ntoh_safe(u16_v(query_packet[2]), &start_addr);
-  mb_ntoh_safe(u16_v(query_packet[4]), &count);
+//  mb_ntoh_safe(u16_v(query_packet[2]), &start_addr);
+//  mb_ntoh_safe(u16_v(query_packet[4]), &count);
+  start_addr = query_packet[2] * 256 + query_packet[3]; /* Temporary pointer alignment fix */
+  count = query_packet[4] * 256 + query_packet[5];      /* Temporary pointer alignment fix */
 
   #ifdef DEBUG
   printf("handle_read_output_words() called. slave=%d, function=%d, start_addr=%d, count=%d\n", 
@@ -432,7 +436,8 @@
   resp_packet = *resp_packet_ptr;
   
   /* See equivalent comment in handle_read_bits() */ 
-  mb_ntoh_safe(u16_v(query_packet[2]), &start_addr);
+//  mb_ntoh_safe(u16_v(query_packet[2]), &start_addr);
+  start_addr = query_packet[2] * 256 + query_packet[3]; /* Temporary pointer alignment fix */
 
   #ifdef DEBUG
   printf("handle_write_output_bit() called. slave=%d, function=%d, start_addr=%d\n", 
@@ -477,8 +482,9 @@
   resp_packet = *resp_packet_ptr;
   
   /* See equivalent comment in handle_read_bits() */ 
-  mb_ntoh_safe(u16_v(query_packet[2]), &start_addr);
-  
+//  mb_ntoh_safe(u16_v(query_packet[2]), &start_addr);
+  start_addr = query_packet[2] * 256 + query_packet[3]; /* Temporary pointer alignment fix */
+ 
   #ifdef DEBUG
   printf("handle_write_output_word() called. slave=%d, function=%d, start_addr=%d\n", 
          query_packet[0], query_packet[1], start_addr);
@@ -520,8 +526,10 @@
   resp_packet = *resp_packet_ptr;
   
   /* See equivalent comment in handle_read_bits() */ 
-  mb_ntoh_safe(u16_v(query_packet[2]), &start_addr);
-  mb_ntoh_safe(u16_v(query_packet[4]), &count); 
+//  mb_ntoh_safe(u16_v(query_packet[2]), &start_addr);
+//  mb_ntoh_safe(u16_v(query_packet[4]), &count); 
+  start_addr = query_packet[2] * 256 + query_packet[3]; /* Temporary pointer alignment fix */
+  count = query_packet[4] * 256 + query_packet[5];      /* Temporary pointer alignment fix */
 
   #ifdef DEBUG
   printf("handle_write_output_bits() called. slave=%d, function=%d, start_addr=%d, count=%d\n", 
@@ -566,9 +574,11 @@
   resp_packet = *resp_packet_ptr;
   
   /* See equivalent comment in handle_read_bits() */ 
-  mb_ntoh_safe(u16_v(query_packet[2]), &start_addr);
-  mb_ntoh_safe(u16_v(query_packet[4]), &count); 
-  
+//  mb_ntoh_safe(u16_v(query_packet[2]), &start_addr);
+//  mb_ntoh_safe(u16_v(query_packet[4]), &count); 
+  start_addr = query_packet[2] * 256 + query_packet[3]; /* Temporary pointer alignment fix */
+  count = query_packet[4] * 256 + query_packet[5];      /* Temporary pointer alignment fix */
+
   if ((count > MAX_WRITE_REGS) || (count < 1) || (count*2 != query_packet[6]) )
     {*error_code = ERR_ILLEGAL_DATA_VALUE; return -1;}