stephane / libmodbus

A Modbus library for Linux, Mac OS, FreeBSD and Windows
http://libmodbus.org
GNU Lesser General Public License v2.1
3.48k stars 1.76k forks source link

Modbus RTU t1.5 and t3.5 timer issues #400

Closed felix-hubo closed 7 years ago

felix-hubo commented 7 years ago

Hello,

I'm using libmodbus stable version v3.0.6 to play as one rtu master. I was reported the master did not follow the t1.5 timer rule on the clause 2.5.1.1 of [http://www.modbus.org/docs/Modbus_over_serial_line_V1_02.pdf]

Then I tried to investigate this. After looking at the source codes in libmodbus-3.0.6/src/modbus.c. I found this function "static int receive_msg(modbus_t ctx, uint8_t msg, msg_type_t msg_type)" from line 351 to 451 which was related to this. Here the ctx->byte_timeout is used to check the t1.5 timer out. Then my question is why on line 355 the length_to_read is set to ctx->backend->header_length + 1 but not 1. Because now you can't detect the t1.5 timer out between the 1st(address) and 2nd(function code) bytes, right? Another question is I did find where the t3.5 timer is defined and used in the source codes. Did I miss anything?

` 351 / We need to analyse the message step by step. At the first step, we want 352 to reach the function code because all packets contain this 353 information. / 354 step = _STEP_FUNCTION; 355 length_to_read = ctx->backend->header_length + 1; 356 357 if (msg_type == MSG_INDICATION) { 358 / Wait for a message, we don't know when the message will be 359 received / 360 p_tv = NULL; 361 } else { 362 tv.tv_sec = ctx->response_timeout.tv_sec; 363 tv.tv_usec = ctx->response_timeout.tv_usec; 364 p_tv = &tv; 365 } 366 367 while (length_to_read != 0) { 368 rc = ctx->backend->select(ctx, &rfds, p_tv, length_to_read); 369 if (rc == -1) { 370 _error_print(ctx, "select"); 371 if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) { 372 int saved_errno = errno; 373 374 if (errno == ETIMEDOUT) { 375 _sleep_and_flush(ctx); 376 } else if (errno == EBADF) { 377 modbus_close(ctx); 378 modbus_connect(ctx); 379 } 380 errno = saved_errno; 381 } 382 return -1; 383 } 384 385 rc = ctx->backend->recv(ctx, msg + msg_length, length_to_read); 386 if (rc == 0) { 387 errno = ECONNRESET; 388 rc = -1; 389 } 390 391 if (rc == -1) { 392 _error_print(ctx, "read"); 393 if ((ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) && 394 (errno == ECONNRESET || errno == ECONNREFUSED || 395 errno == EBADF)) { 396 int saved_errno = errno; 397 modbus_close(ctx); 398 modbus_connect(ctx); 399 / Could be removed by previous calls / 400 errno = saved_errno; 401 } 402 return -1; 403 } 404 405 / Display the hex code of each character received / 406 if (ctx->debug) { 407 int i; 408 for (i=0; i < rc; i++) 409 printf("<%.2X>", msg[msg_length + i]); 410 } 411 412 / Sums bytes received / 413 msg_length += rc; 414 / Computes remaining bytes / 415 length_to_read -= rc; 416 417 if (length_to_read == 0) { 418 switch (step) { 419 case _STEP_FUNCTION: 420 / Function code position / 421 length_to_read = compute_meta_length_after_function( 422 msg[ctx->backend->header_length], 423 msg_type); 424 if (length_to_read != 0) { 425 step = _STEP_META; 426 break; 427 } / else switches straight to the next step / 428 case _STEP_META: 429 length_to_read = compute_data_length_after_meta( 430 ctx, msg, msg_type); 431 if ((msg_length + length_to_read) > ctx->backend->max_adu_length) { 432 errno = EMBBADDATA; 433 _error_print(ctx, "too many data"); 434 return -1; 435 } 436 step = _STEP_DATA; 437 break; 438 default: 439 break; 440 } 441 } 442 443 if (length_to_read > 0 && ctx->byte_timeout.tv_sec != -1) { 444 / If there is no character in the buffer, the allowed timeout 445 interval between two consecutive bytes is defined by 446 byte_timeout */ 447 tv.tv_sec = ctx->byte_timeout.tv_sec; 448 tv.tv_usec = ctx->byte_timeout.tv_usec; 449 p_tv = &tv; 450 } 451 }

`

stephane commented 7 years ago

By design, libmodbus doesn't respect the timers defined by the protocol. Could you use the mailing to ask questions, please?