Răsfoiți Sursa

cleanup some things in echo_hw path

Reinhard Russinger 6 ani în urmă
părinte
comite
10cf3892ea
1 a modificat fișierele cu 27 adăugiri și 9 ștergeri
  1. 27 9
      src/modbus-rtu.c

+ 27 - 9
src/modbus-rtu.c

@@ -268,19 +268,34 @@ static void _modbus_rtu_ioctl_rts(modbus_t *ctx, int on)
 #endif
 
 static ssize_t _modbus_rtu_write_n_read(modbus_t *ctx, const uint8_t *req, int req_length) {
+ int rc;
  ssize_t w, r, i;
  uint8_t rb[512];
-
+ fd_set rset;
+ struct timeval tv;
+ 
  // Transmit
  w = write(ctx->s, req, req_length);
 
  // Read back written bytes if hw has echo
- r = 0;
- while (r < w)
-  r += read(ctx->s, rb + r, w - r);
+ FD_ZERO(&rset);
+ FD_SET(ctx->s, &rset);
+
+ r = w;
+ do {
+  tv.tv_sec = ctx->response_timeout.tv_sec;
+  tv.tv_usec = ctx->response_timeout.tv_usec;
+  rc = ctx->backend->select(ctx, &rset, &tv, r);
+  if(rc > 0){
+    ctx->backend->recv(ctx, rb + (w-r) , rc > r?r:rc); 
+    r -= rc;
+    }
+  }while( (rc > 0) && (r > 0));
+
  if (ctx->debug) {
-  for (i = 0; i < r; ++i)
-  fprintf(stderr, "|%02X|", rb[i]);
+  fprintf(stderr, "====> w: %d r: %d req_len %d |", w, r, req_length);
+  for (i = 0; i < (w - r); ++i)
+      fprintf(stderr, "%02X%c", rb[i], i == (w -r) -1 ?'|':'-');
   fprintf(stderr, "\n");
   fflush(stderr);
  }
@@ -416,6 +431,7 @@ static int _modbus_rtu_check_integrity(modbus_t *ctx, uint8_t *msg,
         
         if(ctx_rtu->echohw) {/* on active echomode empty receiver on crc error */
             int rc;
+            int inputchars = 0;
             fd_set rfds;
             struct timeval tv;    
         
@@ -430,15 +446,17 @@ static int _modbus_rtu_check_integrity(modbus_t *ctx, uint8_t *msg,
                 fflush(stderr);                    
             }
         
+#define MAX_INPUT_BUF_SIZE 64          
             do {
-               unsigned char cc[256]; /* dummy buffer für cleaning input */
+               unsigned char cc[MAX_INPUT_BUF_SIZE]; /* dummy buffer für cleaning input */
            
                tv.tv_sec = ctx->response_timeout.tv_sec;
                tv.tv_usec = ctx->response_timeout.tv_usec;
 
                rc = ctx->backend->select(ctx, &rfds, &tv, sizeof(cc));
-               if(rc > 0) ctx->backend->recv(ctx, msg + msg_length, rc);           
-               } while(rc > 0); /* read until transfer empty */
+               if(rc > 0) ctx->backend->recv(ctx, cc, rc);           
+               inputchars += rc;
+               } while((rc > 0) && (inputchars < MAX_INPUT_BUF_SIZE)); /* read until transfer empty */
             }
           
         if (ctx->debug) {