User Configuration File
Key point
The customization and configuration of the protocol stack should be an easy task to control the resource usage of the software package.
In the common/include
directory, there is a file named MBx_user_sample.h
. Copy this file and rename it to MBx_user.h
, and add it to a path that can be included.
In the global compilation define
, add MBX_INCLUDE_USER_DEFINE_FILE. This way, the library will use the custom definitions from MBx_user.h
instead of the defaults.
Since the configuration file complies with CMSIS Configuration Wizard Annotations,, you can use the vscode
plugin or other methods to render the configuration in MBx_user.h
, allowing for a more intuitive configuration. The recommended method is to use the Arm CMSIS Solution
plugin for vscode
.
Once installed, open the MBx_user.h
file and click the "Open Preview" icon in the upper right corner to render the configuration file for graphical configuration.
Particulars
MBX_SLAVE_ENABLE
Default 1
Whether the slave function is open, 1 is open, 0 is cut off the slave function
MBX_MASTER_ENABLE
默认 1
Whether the master function is open, 1 is open, 0 is cut off the master function
MBX_MODULE_TCP_MASTER_ENABLE
Default 1
If you need to use the Modbus TCP master functionality, this macro should be set to 1. Otherwise, it is recommended to set it to 0, which will significantly reduce resource usage (mainly RAM).
MBX_MASTER_REQUEST_QUEUE_MAX
Default 40
The maximum number of entries in the host request queue for continuous read and write requests, stored and automatically sent for processing. This can significantly affect RAM usage.
MBX_MASTER_MULTI_REG_MAX
Default 127
The maximum number of multiple registers that the host can read and write to sets the maximum number of registers that can be specified for successive read or write instructions issued by the library, which significantly affects RAM usage.
MBX_EXTEN_REG_HANDLE_ENABLE
Default 0
Note that in the examples provided within the library, all different mapped variables require independent and as unique as possible handling functions.
If you need to handle requests from different Modbus virtual addresses in a single handling function, this macro should be set to 1. When this macro is set to 1, the mapping table entries need to be modified (each entry will have an additional parameter set), and each write callback should be rewritten in a new way, which will be detailed later.
A clear applicable scenario is when acting as a Modbus slave, but this slave is merely middleware that needs to control multiple identical module instances. Enabling this macro will greatly reduce the workload and lower maintenance difficulty. There are practical cases for such application scenarios.
The original mapping table is as follows, where these three addresses control three identical modules:
{.Addr = 0x2001, .Memory = &(Powerflag[0]), .Type = MBX_REG_TYPE_U8, .Handle = ModbusModulePower1,},
{.Addr = 0x2011, .Memory = &(Powerflag[1]), .Type = MBX_REG_TYPE_U8, .Handle = ModbusModulePower2,},
{.Addr = 0x2021, .Memory = &(Powerflag[2]), .Type = MBX_REG_TYPE_U8, .Handle = ModbusModulePower3,},
You would need to write three almost identical callbacks, similar to the following. Although macros can be used to generate functions and other means, it is still difficult to maintain uniformly.
uint32_t ModbusModulePower1(void *value)
{
uint8_t ValueGet = (*(uint8_t *)value);
if(ValueGet > 0)
{
/* Ignore some startup operations */
Powerflag[0] = 1;
}
else
{
/* Ignore some shutdown operations */
Powerflag[0] = 1;
}
return MBX_API_RETURN_DEFAULT;
}
After enabling this macro, you need to update this part of the mapping table as follows:
const _MBX_REG_HANDLE_PARA MBXPara1 = {.Para1 = 1, .Para2 = 1};
const _MBX_REG_HANDLE_PARA MBXPara2 = {.Para1 = 2, .Para2 = 2};
const _MBX_REG_HANDLE_PARA MBXPara3 = {.Para1 = 3, .Para2 = 3};
......
{.Addr = 0x2001, .Memory = &(Powerflag[0]), .Type = MBX_REG_TYPE_U8, .Handle = ModbusModulePower, .Para = &MBXPara1},
{.Addr = 0x2011, .Memory = &(Powerflag[1]), .Type = MBX_REG_TYPE_U8, .Handle = ModbusModulePower, .Para = &MBXPara2},
{.Addr = 0x2021, .Memory = &(Powerflag[2]), .Type = MBX_REG_TYPE_U8, .Handle = ModbusModulePower, .Para = &MBXPara3},
Here, three global static variables are added as parameter sets, and each mapping entry needs to include the binding of the .Para
part. This parameter set will be passed to the write handling function, allowing three identical modules to call the same function without needing to define three almost identical handling functions. Therefore, the definition of the handling function needs to be updated as follows:
uint32_t ModbusModulePower(void *value, _MBX_REG_HANDLE_PARA *para)
{
uint8_t ValueGet = (*(uint8_t *)value);
if(ValueGet > 0)
{
/* Perform startup operation for module identified by para->Para1 */
Powerflag[para->Para1 - 1] = 1;
}
else
{
/* Perform shutdown operation for module identified by para->Para1 */
Powerflag[para->Para1 - 1] = 1;
}
return MBX_API_RETURN_DEFAULT;
}
For entries that do not use this parameter, the best approach is to set .Para = &DefaultPara
, where DefaultPara
is a static variable generated when the macro is enabled, to avoid wild pointers.