I'm developing a modbus RTU slave device with a 32-bit MCU. The operation of the device depends on many parameters. So, the device should support modbus function codes for parameter read and write. Which specific function codes to support is up to my design.
A modbus master device reads or writes the slave device's registers at certain addresses. So, I need to map parameters to registers with addresses. I've come up with this approach: Use one or more holding registers to represent a parameter. (A holding register is a 16-bit variable with read and write access.) Use the following union to make the connection between parameters and registers: struct for parameters, and uint16_t array for registers.
typedef union{
uint16_t holding_register[PARAMETER_STRUCT_SIZE];
struct the_parameters{
float parameter1,parameter2,parameter3;
uint8_t parameter4,parameter5;
};
}modbus_union;
When a modbus master device wants to access a register at an address, it can access the element in the array at the index. The meaning of a certain register can be maintained in documentation.
Equivalently, a uint16_t pointer can be used to point at struct the_parameters. And in modbus protocol, it can just be dealt with as an array.
The problem is, my code should be MISRAC-2004 compliant to pass a safety test. The related MISRAC rules are:
Rule 18.4 (required): Unions shall not be used.
Rule 17.1 (required): Pointer arithmetic shall only be applied to pointers that address an array or array element.
How to implement modbus RTU in MISRAC-2004-complaint C?