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

Coil, holding/input register and discrete input mapping/callback in slave mode #41

Closed khanrezwan closed 2 years ago

khanrezwan commented 2 years ago

I am trying to use this library for a modbus slave. I couldn’t find any mechanism to map u16_registers to coils/ holding reg/ input reg/ discrete input. Is there any callback mechanism?

I can see a semaphore to aceess modbus data. Should I use semaphore to access in other task?

Let's say I would like to toggle a LED(coil) in a freeRTOS task depending on modbus command, how do I do that?

Also from my current understanding, I don’t see any way to prevent write in an input register/ discrete input.

Did I miss that in example, or is my understanding is wrong?

alejoseb commented 2 years ago

There is no explicit mapping. The developer should define the ranges in the u16_registers according to the application's needs. For example, coils can be mapped from addresses 0 to 99, and holding registers from 100 to 199. However, there is no mechanism to prevent addresses 0 to 99 to be also treated as holding registers. The same apply to the whole memory space.

There is no callback mechanism. The semaphore is intended to prevent race conditions on accessing the u16_registers array. This array is either accessed by the Modbus task---when a Modbus query has arrived---or by tasks interacting (read and write) with it. For example, check the commented out example for toggling a LED here: https://github.com/alejoseb/Modbus-STM32-HAL-FreeRTOS/blob/680ca775bf3fff4b5dbbb41e3171dd35a743f0ba/Examples/ModbusF429/Core/Src/freertos.c#L143

"I don’t see any way to prevent write in an input register/ discrete input", I don't quite understand this statement, the idea is to interact (read and write) with all the Modbus data in a thread-safe way, thus the implemented semaphore.

khanrezwan commented 2 years ago

"I don’t see any way to prevent write in an input register/ discrete input", I don't quite understand this statement, the idea is to interact (read and write) with all the Modbus data in a thread-safe way, thus the implemented semaphore.

Apology for the vague question. What I meant, if there is any mechanism to prevent write from a master to slave input register/ discrete input and reply an OOPS / invalid operation.

Also if you want I may give a shot at explicit mapping for variuos types of register with callback/tasks.

alejoseb commented 2 years ago

It is up to your implementation, you can ban a particular operation commenting out the corresponding element here:

https://github.com/alejoseb/Modbus-STM32-HAL-FreeRTOS/blob/680ca775bf3fff4b5dbbb41e3171dd35a743f0ba/MODBUS-LIB/Src/Modbus.c#L179

The library will automatically respond with an invalid operation message to the master. If you need a more sophisticated method for filtering and access control, it will need further modifications beyond the Modbus specification.

The callback mechanism is not implemented. You may need to extend every Function Code methods for doing so. Another option is to create a notification mechanism from the Modbus task to a subscriber task. In any case, callbacks are not supported by this library.

IanAber commented 1 year ago

Am I correct in thinking that, assuming the STM32 is a slave and implementing 5 coils, 5 holding registers, 5 input registers and 5 discretes, the numbering for each has to be unique? i.e. Coils might be 0 to 4, holding registers 5 to 9 etc. You cannot have coil 0 AND holding register 0 at they would use the same value. Also, if you decide the holding registers are 5 to 9 there is nothing to stop the master from requesting, or writing to, holding register 0 thereby actually reading or writing a coil even though a holding register action was specified.

This does not seem to fit with what most would reasonably think the slave should do.