guohui 1 год назад
Родитель
Сommit
ceb6bc87ef
3 измененных файлов с 97 добавлено и 40 удалено
  1. 78 39
      pro/src/cascade.c
  2. 18 1
      pro/src/modbus_handle.c
  3. 1 0
      pro/src/modbus_handle.h

+ 78 - 39
pro/src/cascade.c

@@ -432,13 +432,13 @@ static int slave_save(cascade_handle_t *cas)
 }
 /////////////////////////////////////////////////////////////////////////////////////////
 
-static int mb_init(cascade_handle_t *cas, char *path, int type, int addr, uint32_t baud)
+static int mb_init(cascade_handle_t *cas, char *path, int mode, int addr, uint32_t baud)
 {
     int r=0;
 
-    r = g_modbus_init(&cas->m, path, baud, type, addr, (type>0)?"master":"slave", 1);
+    r = g_modbus_init(&cas->m, path, baud, mode, addr, (mode==MODBUS_MASTER)?"master":"slave", 1);
     if(r==0) {
-        if(type>0) {
+        if(mode==MODBUS_SLAVE) {
             LOGD("___ set slave addr: %d\n", addr);
             cas->addr = addr;
             g_modbus_set_slave(&cas->m, addr);
@@ -466,9 +466,7 @@ static int _mb_scan(cascade_handle_t *cas, int addr)
     int r;
     uint16_t tmp;
 
-    //g_modbus_set_timeout(&cas->m, 100);
     r = g_modbus_read_x_reg(&cas->m, addr, CASCADE_REG_SCAN, 1, &tmp);
-    //g_modbus_set_timeout(&cas->m, 1500);
 
     return r;
 }
@@ -510,6 +508,17 @@ static int _mb_reply(cascade_handle_t *cas, uint8_t *buff, int reqlen, modbus_ma
 {
     return g_modbus_reply(&cas->m, buff, reqlen, map);
 }
+static int _mb_get_timeout(cascade_handle_t *cas)
+{
+    int r,ms=0;
+    r = g_modbus_get_timeout(&cas->m, &ms);
+    return ms;
+}
+static int _mb_set_timeout(cascade_handle_t *cas, int ms)
+{
+    return g_modbus_set_timeout(&cas->m, ms);
+}
+
 ////////////////////////////////////////////////////////////
 static void print_data(uint8_t *data, int len)
 {
@@ -583,14 +592,38 @@ static int mb_hdr(uint8_t *data, int datalen, mb_hdr_t *h)
 
     return 0;
 }
+#define SCAN_TIMEOUT_MS     200
+#define RW_TIMEOUT_MS       100
+static int mb_scan(cascade_handle_t *cas, int addr)
+{
+    int r,timeout=0;
+    uint16_t tmp;
+
+    pthread_mutex_lock(&cas->mutex3);
+    timeout = _mb_get_timeout(cas);
+    _mb_set_timeout(cas, SCAN_TIMEOUT_MS);
+    r = _mb_scan(cas, addr);
+    _mb_set_timeout(cas, timeout);
+    pthread_mutex_unlock(&cas->mutex3);
+
+    return r;
+}
+
 static int mb_read(cascade_handle_t *cas, int addr, data_t *d)
 {
-    int r=0,finish=0;
-    int xlen,rlen=0,oncelen=MB_MAX_LEN;
+    int i,r=0,finish=0,timeout=0;
+    int rl,xlen,rlen=0,oncelen=MB_MAX_LEN;
     uint16_t buff[MODBUS_RTU_MAX_ADU_LENGTH];
 
-    pthread_mutex_lock(&cas->mutex3);
-    if(d->dlen>0) {
+    if(d->dlen<=0) {
+        return -1;
+    }
+
+    for(i=0; i<10; i++) {
+        pthread_mutex_lock(&cas->mutex3);
+        timeout = _mb_get_timeout(cas);
+        _mb_set_timeout(cas, RW_TIMEOUT_MS);
+        r = 0; rlen = 0;
         while(1) {
             if(rlen+oncelen>d->dlen) {
                 xlen = d->dlen-rlen;
@@ -600,17 +633,17 @@ static int mb_read(cascade_handle_t *cas, int addr, data_t *d)
             }
             xlen += xlen%2;
 
-            r = _mb_read(cas, addr, CASCADE_REG_READ, buff, xlen/2);
-            if(r<0) {
-                LOGE("___ _mb_read failed, %s, rlen: %d\n", modbus_strerror(errno), rlen);
+            rl = _mb_read(cas, addr, CASCADE_REG_READ, buff, xlen/2);
+            if(rl<0) {
+                LOGE("___ _mb_read failed, %s, rlen: %d, retry: %d\n", modbus_strerror(errno), rlen, i);
                 r = -1; break;
             }
-            if(rlen+r*2>=d->dlen) {
+            if(rlen+rl*2>=d->dlen) {
                 xlen = d->dlen-rlen;
                 finish = 1;
             }
             else {
-                xlen = r*2;
+                xlen = rl*2;
             }
 
             memcpy((char*)d->data+rlen, buff, xlen);
@@ -620,22 +653,30 @@ static int mb_read(cascade_handle_t *cas, int addr, data_t *d)
                 break;
             }
         }
+        _mb_set_timeout(cas, timeout);
+        pthread_mutex_unlock(&cas->mutex3);
+        if(r==0) {
+            break;
+        }
     }
-    else {
-        r = -1;
-    }
-    pthread_mutex_lock(&cas->mutex3);
     
     return r;
 }
 static int mb_write(cascade_handle_t *cas, int addr, data_t *d)
 {
-    int r=0;
-    int xlen,wlen=0,oncelen=MB_MAX_LEN;
+    int i,r=0,timeout=0;
+    int wl,xlen,wlen=0,oncelen=MB_MAX_LEN;
     uint16_t buff[MODBUS_RTU_MAX_ADU_LENGTH];
 
-    pthread_mutex_lock(&cas->mutex3);
-    if(d->dlen>0) {
+    if(d->dlen<=0) {
+        return -1;
+    }
+
+    for(i=0; i<10; i++) {
+        pthread_mutex_lock(&cas->mutex3);
+        timeout = _mb_get_timeout(cas);
+        _mb_set_timeout(cas, RW_TIMEOUT_MS);
+        r = 0; wlen = 0;
         while(1) {
             if(wlen+oncelen>d->dlen) {
                 xlen = d->dlen-wlen;
@@ -646,24 +687,25 @@ static int mb_write(cascade_handle_t *cas, int addr, data_t *d)
             xlen += xlen%2;
 
             memcpy(buff, d->data+wlen, xlen);
-            r = _mb_write(cas, addr, CASCADE_REG_WRITE, buff, xlen/2);
-            if(r<0) {
-                LOGE("___ _mb_write, addr: %d, reg: %d, cnt: %d, %s\n", addr, CASCADE_REG_WRITE, xlen/2, modbus_strerror(errno));
+            wl = _mb_write(cas, addr, CASCADE_REG_WRITE, buff, xlen/2);
+            if(wl<0) {
+                LOGE("___ _mb_write failed, addr: %d, reg: %d, cnt: %d, %s, retry: %d\n", addr, CASCADE_REG_WRITE, xlen/2, modbus_strerror(errno), i);
                 r = -1; break;
             }
-            if(wlen+r*2>=d->dlen) {
+            if(wlen+wl*2>=d->dlen) {
                 break;
             }
             else {
-                xlen = r*2;
+                xlen = wl*2;
             }
             wlen += xlen;
         }
+        _mb_set_timeout(cas, timeout);
+        pthread_mutex_unlock(&cas->mutex3);
+        if(r==0) {
+            break;
+        }
     }
-    else {
-        r = -1;
-    }
-    pthread_mutex_unlock(&cas->mutex3);
     
     return r;
 }
@@ -694,13 +736,14 @@ static int mb_receive(cascade_handle_t *cas)
 
 #if 1
     //do not know why slave can receive all address data
-    //LOGD("____mb_receive, %d\n", h.addr);
+    //LOGD("____mb_receive, %d, %d\n", h.addr, cas->addr);
     if(h.addr>0 && h.addr!=cas->addr) {
         return -1;
     }
 #endif
 
-    switch(h.reg) {
+    //LOGD("____mb_receive, reg: %d, rc: %d\n", h.reg, rc);
+    switch(h.reg) { 
         case CASCADE_REG_SCAN:
         {
             r = _mb_reply(cas, buff, rc, cas->map);
@@ -853,7 +896,7 @@ static int mb_receive(cascade_handle_t *cas)
 /////////////////////////////////////////////////////////////////////////
 static int master_scan(cascade_handle_t *cas)
 {
-    int i,r=0 ;
+    int i,r=0;
     uint16_t tmp[10];
 
     if(cas->scanAddr>CASCADE_MAX) {
@@ -861,7 +904,7 @@ static int master_scan(cascade_handle_t *cas)
     }
 
     if(!slave_find(cas, cas->scanAddr)) {
-         r = _mb_scan(cas, cas->scanAddr);
+         r = mb_scan(cas, cas->scanAddr);
         if(r>0) {
             LOGD("____ find a slave, addr: %d\n", cas->scanAddr);
             slave_add(cas, cas->scanAddr);
@@ -1557,15 +1600,11 @@ void* cascade_thread(void *arg)
     LOGD("__ cascade %s\n", (info->mode==MODBUS_MASTER)?"master":"slave");
     while(h->quit==0) {
         if(info->mode==MODBUS_MASTER) {      //主模
-            cascade_lock();
             r = master_query(cas);
-            cascade_unlock();
             sleep(1);
         }
         else {                                  //从模式,等待主设备发起数据请�?
-            cascade_lock();
             r = slave_receive(cas);
-            cascade_unlock();
         }  
     }
     

+ 18 - 1
pro/src/modbus_handle.c

@@ -244,12 +244,29 @@ int g_modbus_set_timeout(void* manger,int timeout_ms)
     int ret = 0 ;
     Modbus_Manger *modbus_manger = (Modbus_Manger *)manger;
     pthread_mutex_lock(&modbus_manger->mutex); 
-    ret = modbus_set_response_timeout(modbus_manger->mb, timeout_ms/1000, timeout_ms*1000);
+    ret = modbus_set_response_timeout(modbus_manger->mb, timeout_ms/1000, (timeout_ms%1000)*1000);
     pthread_mutex_unlock(&modbus_manger->mutex);
     return ret;
 }
 
 
+int g_modbus_get_timeout(void* manger,int *timeout_ms)
+{
+    int ret = 0 ;
+    uint32_t s,us;
+
+    Modbus_Manger *modbus_manger = (Modbus_Manger *)manger;
+    pthread_mutex_lock(&modbus_manger->mutex); 
+    ret = modbus_get_response_timeout(modbus_manger->mb, &s, &us);
+    if(ret==0 && timeout_ms) {
+        *timeout_ms = s*1000 + us/1000;
+    }
+    pthread_mutex_unlock(&modbus_manger->mutex);
+    return ret;
+}
+
+
+
 //04
 int g_modbus_read_input_reg(void* manger,int saddr,unsigned short reg,unsigned int size,unsigned short *data)
 {

+ 1 - 0
pro/src/modbus_handle.h

@@ -32,6 +32,7 @@ int g_modbus_write_x_reg(void* manger,int saddr,unsigned short reg,unsigned int
 int g_modbus_read_reg(void* manger,int saddr,unsigned short reg,unsigned short* data);
 int g_modbus_read_x_reg(void* manger,int saddr,unsigned short reg,unsigned int size,unsigned short *data);
 int g_modbus_read_x_reg_delay(void* manger,int saddr,unsigned short reg,unsigned int size,unsigned short *data);
+int g_modbus_get_timeout(void* manger,int *timeout_ms);
 int g_modbus_set_timeout(void* manger,int timeout_ms);
 void g_modbus_deinit(void* manger);