Electronic – Modbus slave firmware development

modbusslave

I'm developing a simple RS485 based MODBUS slave application on a Microchip PIC micro-controller and need to know best practices to follow on its application side.
I can guide myself to get the hardware layer working.

From my understanding, the MODBUS slave has a database of application specific registers upon which the master performs R&W operations through commands.

Now this database needs to be run-time updatable based on device operation and should also be persistent so that device status can be recovered after power reset.
Also, the master can ask for register read in contiguous manner (for e.g. read 10 registers from ID 2121).
Based on all the requirements, I'm thinking of creating two copies of the database – one on RAM and the other on flash / eeprom.
The one on RAM would simply be a set of arrays and the one on flash / eeprom would be block of memory locations.
Upon power-up, contents from the flash will be copied to the RAM locations
and all the run-time R&W operations thereon will be performed on the RAM copy itself.
Now, there could be two ways to transfer the latest data from RAM to flash:

  1. Do it instantly when any of the data changes

    • Master will be notified about operation success only when data is transferred to NV memory
    • Could invite too many flash/eeprom operations
  2. Do it periodically

    • Less transactions with the NV memory
    • There could be data loss if power goes down before transfer was complete, and worse master would think that data was successfully written to the slave

Is my understanding correct till now? If yes, which of the two ways is usually followed? Or is there a better one?

Best Answer

The choice of how to store your database is largely up to your own requirements, not really a modbus question. As for good things to do for modbus I'd recommend implementing some register that provide identification details, to allow automatic probing, and serial numbers, or other fixed numbers that can be used to verify that the device is your device. You can even provide registers to blink your led to help locate the device.

Also, don't feel limited to a single block of registers. Use them as logical blocks if you can, rather than trying to make a hard 1:1 map to your variables. This makes it easier to group and expand things down the road.

Try and avoid special casing on the register count. It's perfectly legitimate (protocol wise) that "reading 4@0x2000" gives you different data than "reading 2@0x2000 + 2@0x2002" but it's just going to confuse your users.

Try and make sure to actually be consistent with byte ordering. Try and stick to big endian like the rest of the protocol.