alejoseb / Modbus-STM32-HAL-FreeRTOS

Modbus TCP and RTU, Master and Slave for STM32 using Cube HAL and FreeRTOS
GNU Lesser General Public License v2.1
539 stars 183 forks source link

CRC check of received frame error #14

Closed SuriyaMeras closed 3 years ago

SuriyaMeras commented 3 years ago

I have received CRC failed error and while debugging the crc value for received frame is taken as transmitted frame crc value. because the last values in the au8Buffer were transmission frame. So the value of crc is miss interupted.

alejoseb commented 3 years ago

Can you provide more details about your environment? For example microcontroller, type of modbus operation, length, steps to reproduce the issue, etc. Thanks

SuriyaMeras commented 3 years ago

I am using STM32F429 on a custom board, It is configured as modbus master { ModbusH.uiModbusType = MASTER_RTU; ModbusH.port = &huart4; ModbusH.u8id = 0; //Master ID ModbusH.u16timeOut = 1000; ModbusH.EN_Port = RS485_EN_GPIO_Port; // RS485 Enable ModbusH.EN_Pin = RS485_EN_Pin; // RS485 Enable ModbusH.u32overTime = 0; ModbusH.au16regs = ModbusDATARX; ModbusH.u16regsize= sizeof(ModbusDATARX)/sizeof(ModbusDATARX[0]); ModbusInit(&ModbusH); ModbusStart(&ModbusH); } `void StartDefaultTask(void const argument) { / USER CODE BEGIN 5 */ modbus_t telegram; uint32_t u32NotificationValue;

telegram.u8id = 1; // slave address telegram.u8fct = 3; // function code (this one is registers read) //telegram.u16RegAdd = 0x160; // start address in slave telegram.u16RegAdd = 0x0; // start address in slave telegram.u16CoilsNo = 10; // number of elements (coils or registers) to read telegram.au16reg = ModbusDATARX; // pointer to a memory array in the Arduino

for(;;) { ModbusQuery(&ModbusH, telegram); // make a query u32NotificationValue = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // block until query finishes if(u32NotificationValue) { //handle error // while(1); } osDelay(5000); } / Infinite loop / for(;;) { osDelay(1); } / USER CODE END 5 / }`

oussemagaied commented 3 years ago

I have the same error on atmel SAMDJ17, where I write to 8 coils (sending 8 modbus write single coil frames via rs485) and then reading coils states (modbus read coil), when I receive a CRC error, the system has this unknown behaviour under FreeRTOS (the system gets a software reset from watchdog)

alejoseb commented 3 years ago

@SuriyaMeras I cannot reproduce your issue I tested exactly your same code for more than 1000 packages with zero error rate. You should check the ModbusDATARX's length, if you read 10 registers you need at least an array of 10 elements, this is not controlled by the library. Also, double check the configuration of your heap and stack in FreeRTOS. Probably, you are having a buffer overflow. Check the example for F429 for more details. @oussemagaied my answer is valid for you as well. Screenshot from 2021-04-07 16-57-37

SuriyaMeras commented 3 years ago

Do Transmission and reception use same au8Buffer buffer?

alejoseb commented 3 years ago

Yes, it is used but at different times. For RX the library uses first an independent ring buffer. This ring buffer is copied to au8Buffer when the whole frame was received. TX uses directly au8Buffer to send a frame. RX and TX occur at different times. As a master the only way to interrupt the TX process and corrupt the au8Buffer should be if you have another master running in the same bus, or having a very slow slave that responds too late to the master while the master is preparing a request.

alejoseb commented 3 years ago

I will close this issue, feel free to reopen it if you have more information about your issue.

oussemagaied commented 3 years ago

So here's the problem explicitly: 1.1 - Plug the USB RS485 interface and run a modbus server script in PC side (uModbus "python") 1.2 - Request reading coils every 3 seconds (Freemodbus) 1.3 - Close the script and re-open it on the first read retry after the timeout

So what actually happens here : Script response is shifted on the ucMasterRTURcvBuf buffer so the response is always incorrect thus read coil timeout yet the response is not shifted on the USART circular fifo buffer.

alejoseb commented 3 years ago

@oussemagaied lets clarify something.

What do you mean by Freemodbus in 1.2?

I think you have a slave running in python with uModbus and a master running this library in a SAMDJ17, right?

I will try to reproduce your issue and see if something is happening on the library.

alejoseb commented 3 years ago

I tested using the following code , without any issue I close and reopen the script as you mentioned.

`#!/usr/bin/env python3 from serial import Serial from collections import defaultdict

from umodbus.server.serial import get_server from umodbus.server.serial.rtu import RTUServer

/dev/ttyACM0

s = Serial('/dev/ttyACM0') s.timeout = 10 s.baudrate = 115200

data_store = defaultdict(int) app = get_server(RTUServer, s)

data_store[0] = 0

@app.route(slave_ids=[1], function_codes=[1, 2, 3], addresses=list(range(0, 10))) def read_data_store(slave_id, function_code, address): """" Return value of address. """ print("\nreading code:{}, addrr:{}, val:{}".format(function_code, address, data_store[address])) print(data_store) return data_store[address]

@app.route(slave_ids=[1], function_codes=[5, 6, 15], addresses=list(range(0, 10))) def write_data_store(slave_id, function_code, address, value): """" Set value for address. """ print("\nwriting code:{}, addrr:{}, val:{}".format(function_code, address, value)) print(data_store) data_store[address] = value

if name == 'main': try: app.serve_forever()

print("runinng")

finally:
    app.shutdown()`