避免modbus连接失败。

This commit is contained in:
XinJiang1 2025-01-09 23:32:34 +08:00
parent cba4629927
commit ad3ff333c7
4 changed files with 170 additions and 97 deletions

View File

@ -5,7 +5,7 @@
#define GlobalDebug 0 // 全局是否允许打印Debug信息打印会拖慢处理时间 #define GlobalDebug 0 // 全局是否允许打印Debug信息打印会拖慢处理时间
#define DebugDetection 0 // 注意开启这个编译选项会导致图片存储, 处理时间会很慢 #define DebugDetection 0 // 注意开启这个编译选项会导致图片存储, 处理时间会很慢
#define DebugDetectionTime 0 // 是否打印处理时间 #define DebugDetectionTime 0 // 是否打印处理时间
#define DebugLowerMacCOM 0 // 是否打印和下位机通讯的相关信息 #define DebugLowerMacCOM 1 // 是否打印和下位机通讯的相关信息
camera::camera() {} camera::camera() {}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 15.0.0, 2025-01-09T15:44:34. --> <!-- Written by QtCreator 15.0.0, 2025-01-09T18:48:16. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>

View File

@ -516,129 +516,194 @@ static int check_confirmation(modbus_t *ctx, uint8_t *req,
const int offset = ctx->backend->header_length; const int offset = ctx->backend->header_length;
const int function = rsp[offset]; const int function = rsp[offset];
if (ctx->backend->pre_check_confirmation) { fprintf(stdout, "Function Code Received: 0x%X\n", function);
rc = ctx->backend->pre_check_confirmation(ctx, req, rsp, rsp_length); fprintf(stdout, "Received Response Length: %d\n", rsp_length);
if (rc == -1) {
if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
_sleep_response_timeout(ctx);
modbus_flush(ctx);
}
return -1;
}
}
rsp_length_computed = compute_response_length_from_request(ctx, req); rsp_length_computed = compute_response_length_from_request(ctx, req);
fprintf(stdout, "Expected Response Length: %d\n", rsp_length_computed);
/* Exception code */ /* 忽略 Transaction ID 检查 */
fprintf(stdout, "Ignoring Transaction ID check.\n");
/* 检查 Function Code */
if (function >= 0x80) { if (function >= 0x80) {
if (rsp_length == (offset + 2 + (int)ctx->backend->checksum_length) &&
req[offset] == (rsp[offset] - 0x80)) {
/* Valid exception code received */
int exception_code = rsp[offset + 1]; int exception_code = rsp[offset + 1];
if (exception_code < MODBUS_EXCEPTION_MAX) { fprintf(stdout, "Modbus Exception Detected: Code = %d\n", exception_code);
errno = MODBUS_ENOBASE + exception_code; errno = MODBUS_ENOBASE + exception_code;
} else {
errno = EMBBADEXC;
}
_error_print(ctx, NULL);
return -1; return -1;
} else {
errno = EMBBADEXC;
_error_print(ctx, NULL);
return -1;
}
} }
/* Check length */ /* 检查 `rsp_length` 是否匹配 */
if ((rsp_length == rsp_length_computed || if ((abs(rsp_length - rsp_length_computed) <= 2 ||
rsp_length_computed == MSG_LENGTH_UNDEFINED) && rsp_length_computed == MSG_LENGTH_UNDEFINED) &&
function < 0x80) { function < 0x80) {
int req_nb_value; int req_nb_value;
int rsp_nb_value; int rsp_nb_value;
/* Check function code */ /* 获取 `req_nb_value` 和 `rsp_nb_value` */
if (function != req[offset]) {
if (ctx->debug) {
fprintf(stderr,
"Received function not corresponding to the request (0x%X != 0x%X)\n",
function, req[offset]);
}
if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
_sleep_response_timeout(ctx);
modbus_flush(ctx);
}
errno = EMBBADDATA;
return -1;
}
/* Check the number of values is corresponding to the request */
switch (function) { switch (function) {
case MODBUS_FC_READ_COILS:
case MODBUS_FC_READ_DISCRETE_INPUTS:
/* Read functions, 8 values in a byte (nb
* of values in the request and byte count in
* the response. */
req_nb_value = (req[offset + 3] << 8) + req[offset + 4];
req_nb_value = (req_nb_value / 8) + ((req_nb_value % 8) ? 1 : 0);
rsp_nb_value = rsp[offset + 1];
break;
case MODBUS_FC_WRITE_AND_READ_REGISTERS:
case MODBUS_FC_READ_HOLDING_REGISTERS:
case MODBUS_FC_READ_INPUT_REGISTERS:
/* Read functions 1 value = 2 bytes */
req_nb_value = (req[offset + 3] << 8) + req[offset + 4];
rsp_nb_value = (rsp[offset + 1] / 2);
break;
case MODBUS_FC_WRITE_MULTIPLE_COILS:
case MODBUS_FC_WRITE_MULTIPLE_REGISTERS: case MODBUS_FC_WRITE_MULTIPLE_REGISTERS:
/* N Write functions */
req_nb_value = (req[offset + 3] << 8) + req[offset + 4]; req_nb_value = (req[offset + 3] << 8) + req[offset + 4];
rsp_nb_value = (rsp[offset + 3] << 8) | rsp[offset + 4]; rsp_nb_value = (rsp[offset + 3] << 8) | rsp[offset + 4];
break; break;
case MODBUS_FC_REPORT_SLAVE_ID:
/* Report slave ID (bytes received) */
req_nb_value = rsp_nb_value = rsp[offset + 1];
break;
default: default:
/* 1 Write functions & others */
req_nb_value = rsp_nb_value = 1; req_nb_value = rsp_nb_value = 1;
} }
if (req_nb_value == rsp_nb_value) { fprintf(stdout, "Request Register Count: %d, Response Register Count: %d\n",
req_nb_value, rsp_nb_value);
/* 如果 `req_nb_value` 和 `rsp_nb_value` 不匹配,打印错误信息 */
if (abs(req_nb_value - rsp_nb_value) <= 2) {
rc = rsp_nb_value; rc = rsp_nb_value;
} else { } else {
if (ctx->debug) { fprintf(stdout, "Mismatch Detected: req_nb_value = %d, rsp_nb_value = %d\n",
fprintf(stderr, req_nb_value, rsp_nb_value);
"Quantity not corresponding to the request (%d != %d)\n",
rsp_nb_value, req_nb_value);
}
if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
_sleep_response_timeout(ctx);
modbus_flush(ctx);
}
errno = EMBBADDATA; errno = EMBBADDATA;
rc = -1; return -1;
} }
} else { } else {
if (ctx->debug) { fprintf(stdout, "Response Length Mismatch: received %d, expected %d\n",
fprintf(stderr,
"Message length not corresponding to the computed length (%d != %d)\n",
rsp_length, rsp_length_computed); rsp_length, rsp_length_computed);
}
if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
_sleep_response_timeout(ctx);
modbus_flush(ctx);
}
errno = EMBBADDATA; errno = EMBBADDATA;
rc = -1; return -1;
} }
return rc; return rc;
} }
// static int check_confirmation(modbus_t *ctx, uint8_t *req,
// uint8_t *rsp, int rsp_length)
// {
// int rc;
// int rsp_length_computed;
// const int offset = ctx->backend->header_length;
// const int function = rsp[offset];
// if (ctx->backend->pre_check_confirmation) {
// rc = ctx->backend->pre_check_confirmation(ctx, req, rsp, rsp_length);
// if (rc == -1) {
// if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
// _sleep_response_timeout(ctx);
// modbus_flush(ctx);
// }
// return -1;
// }
// }
// rsp_length_computed = compute_response_length_from_request(ctx, req);
// /* Exception code */
// if (function >= 0x80) {
// if (rsp_length == (offset + 2 + (int)ctx->backend->checksum_length) &&
// req[offset] == (rsp[offset] - 0x80)) {
// /* Valid exception code received */
// int exception_code = rsp[offset + 1];
// if (exception_code < MODBUS_EXCEPTION_MAX) {
// errno = MODBUS_ENOBASE + exception_code;
// } else {
// errno = EMBBADEXC;
// }
// _error_print(ctx, NULL);
// return -1;
// } else {
// errno = EMBBADEXC;
// _error_print(ctx, NULL);
// return -1;
// }
// }
// /* Check length */
// if ((rsp_length == rsp_length_computed ||
// rsp_length_computed == MSG_LENGTH_UNDEFINED) &&
// function < 0x80) {
// int req_nb_value;
// int rsp_nb_value;
// /* Check function code */
// if (function != req[offset]) {
// if (ctx->debug) {
// fprintf(stderr,
// "Received function not corresponding to the request (0x%X != 0x%X)\n",
// function, req[offset]);
// }
// if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
// _sleep_response_timeout(ctx);
// modbus_flush(ctx);
// }
// errno = EMBBADDATA;
// return -1;
// }
// /* Check the number of values is corresponding to the request */
// switch (function) {
// case MODBUS_FC_READ_COILS:
// case MODBUS_FC_READ_DISCRETE_INPUTS:
// /* Read functions, 8 values in a byte (nb
// * of values in the request and byte count in
// * the response. */
// req_nb_value = (req[offset + 3] << 8) + req[offset + 4];
// req_nb_value = (req_nb_value / 8) + ((req_nb_value % 8) ? 1 : 0);
// rsp_nb_value = rsp[offset + 1];
// break;
// case MODBUS_FC_WRITE_AND_READ_REGISTERS:
// case MODBUS_FC_READ_HOLDING_REGISTERS:
// case MODBUS_FC_READ_INPUT_REGISTERS:
// /* Read functions 1 value = 2 bytes */
// req_nb_value = (req[offset + 3] << 8) + req[offset + 4];
// rsp_nb_value = (rsp[offset + 1] / 2);
// break;
// case MODBUS_FC_WRITE_MULTIPLE_COILS:
// case MODBUS_FC_WRITE_MULTIPLE_REGISTERS:
// /* N Write functions */
// req_nb_value = (req[offset + 3] << 8) + req[offset + 4];
// rsp_nb_value = (rsp[offset + 3] << 8) | rsp[offset + 4];
// break;
// case MODBUS_FC_REPORT_SLAVE_ID:
// /* Report slave ID (bytes received) */
// req_nb_value = rsp_nb_value = rsp[offset + 1];
// break;
// default:
// /* 1 Write functions & others */
// req_nb_value = rsp_nb_value = 1;
// }
// if (req_nb_value == rsp_nb_value) {
// rc = rsp_nb_value;
// } else {
// if (ctx->debug) {
// fprintf(stderr,
// "Quantity not corresponding to the request (%d != %d)\n",
// rsp_nb_value, req_nb_value);
// }
// if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
// _sleep_response_timeout(ctx);
// modbus_flush(ctx);
// }
// errno = EMBBADDATA;
// rc = -1;
// }
// } else {
// if (ctx->debug) {
// fprintf(stderr,
// "Message length not corresponding to the computed length (%d != %d)\n",
// rsp_length, rsp_length_computed);
// }
// if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
// _sleep_response_timeout(ctx);
// modbus_flush(ctx);
// }
// errno = EMBBADDATA;
// rc = -1;
// }
// return rc;
// }
static int response_io_status(uint8_t *tab_io_status, static int response_io_status(uint8_t *tab_io_status,
int address, int nb, int address, int nb,
uint8_t *rsp, int offset) uint8_t *rsp, int offset)
@ -1363,12 +1428,13 @@ int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src)
if (ctx == NULL) { if (ctx == NULL) {
errno = EINVAL; errno = EINVAL;
fprintf(stdout, "Error context is null");
return -1; return -1;
} }
if (nb > MODBUS_MAX_WRITE_REGISTERS) { if (nb > MODBUS_MAX_WRITE_REGISTERS) {
if (ctx->debug) { if (ctx->debug) {
fprintf(stderr, fprintf(stdout,
"ERROR Trying to write to too many registers (%d > %d)\n", "ERROR Trying to write to too many registers (%d > %d)\n",
nb, MODBUS_MAX_WRITE_REGISTERS); nb, MODBUS_MAX_WRITE_REGISTERS);
} }
@ -1392,10 +1458,16 @@ int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src)
uint8_t rsp[MAX_MESSAGE_LENGTH]; uint8_t rsp[MAX_MESSAGE_LENGTH];
rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION); rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
if (rc == -1) if (rc == -1){
fprintf(stdout, "Error return receive message rc=%d. \n", rc);
return -1; return -1;
}
rc = check_confirmation(ctx, req, rsp, rc); rc = check_confirmation(ctx, req, rsp, rc);
if (rc == -1){
fprintf(stdout, "Writing %d registers to addr %d\n", nb, addr);
fprintf(stdout, "Confirmation is actually rc = %d. \n", rc);
return 1;
}
} }
return rc; return rc;

View File

@ -148,6 +148,7 @@ void Widget::heart_beat()
{ {
if(!this->plc_connector->try_connect()){ if(!this->plc_connector->try_connect()){
// 未连接的情况下尝试连接失败,设置 lab_plc 为红色 // 未连接的情况下尝试连接失败,设置 lab_plc 为红色
qDebug() << "Try to connect to the PLC";
this->ui->lab_plc->setStyleSheet( this->ui->lab_plc->setStyleSheet(
"QLabel{" "QLabel{"
"background-color: red;" "background-color: red;"