|
@@ -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;
|
|
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(r==0) {
|
|
|
- if(type>0) {
|
|
|
|
|
|
|
+ if(mode==MODBUS_SLAVE) {
|
|
|
LOGD("___ set slave addr: %d\n", addr);
|
|
LOGD("___ set slave addr: %d\n", addr);
|
|
|
cas->addr = addr;
|
|
cas->addr = addr;
|
|
|
g_modbus_set_slave(&cas->m, addr);
|
|
g_modbus_set_slave(&cas->m, addr);
|
|
@@ -466,9 +466,7 @@ static int _mb_scan(cascade_handle_t *cas, int addr)
|
|
|
int r;
|
|
int r;
|
|
|
uint16_t tmp;
|
|
uint16_t tmp;
|
|
|
|
|
|
|
|
- //g_modbus_set_timeout(&cas->m, 100);
|
|
|
|
|
r = g_modbus_read_x_reg(&cas->m, addr, CASCADE_REG_SCAN, 1, &tmp);
|
|
r = g_modbus_read_x_reg(&cas->m, addr, CASCADE_REG_SCAN, 1, &tmp);
|
|
|
- //g_modbus_set_timeout(&cas->m, 1500);
|
|
|
|
|
|
|
|
|
|
return r;
|
|
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);
|
|
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)
|
|
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;
|
|
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)
|
|
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];
|
|
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) {
|
|
while(1) {
|
|
|
if(rlen+oncelen>d->dlen) {
|
|
if(rlen+oncelen>d->dlen) {
|
|
|
xlen = d->dlen-rlen;
|
|
xlen = d->dlen-rlen;
|
|
@@ -600,17 +633,17 @@ static int mb_read(cascade_handle_t *cas, int addr, data_t *d)
|
|
|
}
|
|
}
|
|
|
xlen += xlen%2;
|
|
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;
|
|
r = -1; break;
|
|
|
}
|
|
}
|
|
|
- if(rlen+r*2>=d->dlen) {
|
|
|
|
|
|
|
+ if(rlen+rl*2>=d->dlen) {
|
|
|
xlen = d->dlen-rlen;
|
|
xlen = d->dlen-rlen;
|
|
|
finish = 1;
|
|
finish = 1;
|
|
|
}
|
|
}
|
|
|
else {
|
|
else {
|
|
|
- xlen = r*2;
|
|
|
|
|
|
|
+ xlen = rl*2;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
memcpy((char*)d->data+rlen, buff, xlen);
|
|
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;
|
|
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;
|
|
return r;
|
|
|
}
|
|
}
|
|
|
static int mb_write(cascade_handle_t *cas, int addr, data_t *d)
|
|
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];
|
|
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) {
|
|
while(1) {
|
|
|
if(wlen+oncelen>d->dlen) {
|
|
if(wlen+oncelen>d->dlen) {
|
|
|
xlen = d->dlen-wlen;
|
|
xlen = d->dlen-wlen;
|
|
@@ -646,24 +687,25 @@ static int mb_write(cascade_handle_t *cas, int addr, data_t *d)
|
|
|
xlen += xlen%2;
|
|
xlen += xlen%2;
|
|
|
|
|
|
|
|
memcpy(buff, d->data+wlen, xlen);
|
|
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;
|
|
r = -1; break;
|
|
|
}
|
|
}
|
|
|
- if(wlen+r*2>=d->dlen) {
|
|
|
|
|
|
|
+ if(wlen+wl*2>=d->dlen) {
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
else {
|
|
else {
|
|
|
- xlen = r*2;
|
|
|
|
|
|
|
+ xlen = wl*2;
|
|
|
}
|
|
}
|
|
|
wlen += xlen;
|
|
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;
|
|
return r;
|
|
|
}
|
|
}
|
|
@@ -694,13 +736,14 @@ static int mb_receive(cascade_handle_t *cas)
|
|
|
|
|
|
|
|
#if 1
|
|
#if 1
|
|
|
//do not know why slave can receive all address data
|
|
//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) {
|
|
if(h.addr>0 && h.addr!=cas->addr) {
|
|
|
return -1;
|
|
return -1;
|
|
|
}
|
|
}
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
- switch(h.reg) {
|
|
|
|
|
|
|
+ //LOGD("____mb_receive, reg: %d, rc: %d\n", h.reg, rc);
|
|
|
|
|
+ switch(h.reg) {
|
|
|
case CASCADE_REG_SCAN:
|
|
case CASCADE_REG_SCAN:
|
|
|
{
|
|
{
|
|
|
r = _mb_reply(cas, buff, rc, cas->map);
|
|
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)
|
|
static int master_scan(cascade_handle_t *cas)
|
|
|
{
|
|
{
|
|
|
- int i,r=0 ;
|
|
|
|
|
|
|
+ int i,r=0;
|
|
|
uint16_t tmp[10];
|
|
uint16_t tmp[10];
|
|
|
|
|
|
|
|
if(cas->scanAddr>CASCADE_MAX) {
|
|
if(cas->scanAddr>CASCADE_MAX) {
|
|
@@ -861,7 +904,7 @@ static int master_scan(cascade_handle_t *cas)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if(!slave_find(cas, cas->scanAddr)) {
|
|
if(!slave_find(cas, cas->scanAddr)) {
|
|
|
- r = _mb_scan(cas, cas->scanAddr);
|
|
|
|
|
|
|
+ r = mb_scan(cas, cas->scanAddr);
|
|
|
if(r>0) {
|
|
if(r>0) {
|
|
|
LOGD("____ find a slave, addr: %d\n", cas->scanAddr);
|
|
LOGD("____ find a slave, addr: %d\n", cas->scanAddr);
|
|
|
slave_add(cas, 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");
|
|
LOGD("__ cascade %s\n", (info->mode==MODBUS_MASTER)?"master":"slave");
|
|
|
while(h->quit==0) {
|
|
while(h->quit==0) {
|
|
|
if(info->mode==MODBUS_MASTER) { //主模
|
|
if(info->mode==MODBUS_MASTER) { //主模
|
|
|
- cascade_lock();
|
|
|
|
|
r = master_query(cas);
|
|
r = master_query(cas);
|
|
|
- cascade_unlock();
|
|
|
|
|
sleep(1);
|
|
sleep(1);
|
|
|
}
|
|
}
|
|
|
else { //从模式,等待主设备发起数据请�?
|
|
else { //从模式,等待主设备发起数据请�?
|
|
|
- cascade_lock();
|
|
|
|
|
r = slave_receive(cas);
|
|
r = slave_receive(cas);
|
|
|
- cascade_unlock();
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|