PR-765 Rework the modbus master so that it is also configured as a service
This commit is contained in:
parent
e84dcd388f
commit
4da27d3724
|
@ -54,17 +54,24 @@ binding = sized
|
|||
; ---------------------------------------------------------
|
||||
[modbusmaster]
|
||||
; Modbus master enables reading and writing located variables through the
|
||||
; modbus interface. This starts capabilties to poll one or more Modbus
|
||||
; modbus interface. This starts capabilities to poll one or more Modbus
|
||||
; servers and exchange data with the located variables.
|
||||
|
||||
enabled = true
|
||||
|
||||
; We support multiple modbus masters. Each master should specify
|
||||
; We support multiple Modbus masters. Each master should specify
|
||||
; a complete set of configuration information within this section.
|
||||
; Different masters are identified by a postfix which includes the
|
||||
; index of the master. Indices start at 0 and go up from there.
|
||||
|
||||
; A user defined name for the connection. This name appears in log messages.
|
||||
name.0 = 1
|
||||
; The protocol to use for connection. This value must be one of:
|
||||
; tcp
|
||||
; rtu
|
||||
; If you set this to any other value, then this configuration item group
|
||||
; is not created. You might use this to disable connecting to a particular
|
||||
; Modbus slave.
|
||||
protocol.0 = tcp
|
||||
slave_id.0 = 1
|
||||
ip_address.0 = 127.0.0.1
|
||||
|
@ -89,7 +96,7 @@ discrete_inputs_size.0 = 1
|
|||
[pstorage]
|
||||
; The pstorage service reads and writes persistent storage. It enables
|
||||
; the runtime to restore important variables to the previous value
|
||||
; if the runtime is restarated.
|
||||
; if the runtime is restarted.
|
||||
enabled = false
|
||||
|
||||
; How long should we wait between write cycle. The persistent storage
|
||||
|
@ -155,12 +162,12 @@ enable_unsolicited = true
|
|||
; max control commands for a single APDU
|
||||
; max_controls_per_request = 16
|
||||
|
||||
; maximum fragment size the outstation will recieve
|
||||
; maximum fragment size the outstation will receive
|
||||
; default is the max value
|
||||
; max_rx_frag_size = 2048
|
||||
|
||||
; maximum fragment size the outstation will send if
|
||||
; it needs to fragment. Default is the max falue
|
||||
; it needs to fragment. Default is the max falure
|
||||
; max_tx_frag_size = 2048
|
||||
|
||||
; size of the event buffer
|
||||
|
@ -170,7 +177,7 @@ enable_unsolicited = true
|
|||
; sol_confirm_timeout = 5000
|
||||
|
||||
; Timeout for unsolicited confirms (milliseconds)
|
||||
; unsol_conrfirm_timeout = 5000
|
||||
; unsol_confirm_timeout = 5000
|
||||
|
||||
; Timeout for unsolicited retries (milliseconds)
|
||||
; unsol_retry_timeout = 5000
|
|
@ -75,14 +75,17 @@ void updateBuffersOut_MB()
|
|||
pthread_mutex_unlock(&ioLock);
|
||||
}
|
||||
|
||||
/// Defines the protocol that is selected by ser configuration.
|
||||
enum MasterProtocol {
|
||||
ProtocolInvalid,
|
||||
ProtocolTcp,
|
||||
ProtocolRtu,
|
||||
};
|
||||
|
||||
/// How big of a buffer do we reserve for string items.
|
||||
const uint8_t MASTER_ITEM_SIZE(100);
|
||||
|
||||
/// Define the mapping for modbus addresses located variables.
|
||||
struct ModbusAddress
|
||||
{
|
||||
uint16_t start_address;
|
||||
|
@ -106,8 +109,11 @@ struct Master {
|
|||
uint8_t rtu_parity;
|
||||
uint16_t rtu_data_bit;
|
||||
uint16_t rtu_stop_bit;
|
||||
/// The context for communcating with the device.
|
||||
modbus_t* mb_ctx;
|
||||
/// Device specific timeout.
|
||||
uint16_t timeout;
|
||||
/// Is the device currently connected.
|
||||
bool is_connected;
|
||||
|
||||
struct ModbusAddress discrete_inputs;
|
||||
|
@ -124,6 +130,8 @@ struct Master {
|
|||
is_connected(false)
|
||||
{}
|
||||
|
||||
/// Create the context for the device according to the configuration
|
||||
/// parameters provided by the user.
|
||||
void create() {
|
||||
if (protocol == ProtocolTcp) {
|
||||
mb_ctx = modbus_new_tcp(ip_address, ip_port);
|
||||
|
@ -139,11 +147,15 @@ struct Master {
|
|||
}
|
||||
};
|
||||
|
||||
/// Configuration structure that is passed into the ini parsing library.
|
||||
/// This structure is populated as we process configuration items.
|
||||
struct ModbusMasterConfig {
|
||||
|
||||
chrono::milliseconds polling_period;
|
||||
vector<Master>* masters;
|
||||
|
||||
/// Get (or create) the configuration items at the specified index.
|
||||
/// This ensure that this index is addessable.
|
||||
Master* config_item(uint8_t index) {
|
||||
size_t required_size = max(masters->size(), static_cast<size_t>(index + 1));
|
||||
if (masters->size() < required_size) {
|
||||
|
@ -153,6 +165,8 @@ struct ModbusMasterConfig {
|
|||
}
|
||||
};
|
||||
|
||||
/// Callback function for the ini parser. This function is called for every
|
||||
/// configuration item.
|
||||
int modbus_master_cfg_handler(void* user_data, const char* section,
|
||||
const char* name, const char* value) {
|
||||
if (strcmp("modbusmaster", section) != 0) {
|
||||
|
@ -216,12 +230,15 @@ int modbus_master_cfg_handler(void* user_data, const char* section,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/// Arguments provided to the master polling thread.
|
||||
struct MasterArgs {
|
||||
volatile bool* run;
|
||||
chrono::milliseconds polling_period;
|
||||
vector<Master>* masters;
|
||||
};
|
||||
|
||||
/// Polls modbus slaves. This is the main function created by this modbus
|
||||
/// master.
|
||||
void* modbus_master_poll_slaves(void* args) {
|
||||
auto master_args = reinterpret_cast<MasterArgs*>(args);
|
||||
|
||||
|
@ -433,6 +450,8 @@ void* modbus_master_poll_slaves(void* args) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/// Run the modbus master. This function does not return until
|
||||
/// this service is terminated.
|
||||
void modbus_master_run(oplc::config_stream& cfg_stream,
|
||||
const char* cfg_overrides,
|
||||
const GlueVariablesBinding& bindings,
|
||||
|
@ -476,7 +495,9 @@ void modbus_master_run(oplc::config_stream& cfg_stream,
|
|||
this_thread::sleep_for(chrono::milliseconds(500));
|
||||
}
|
||||
|
||||
// Terminate the unified polling thread.
|
||||
// Terminate the unified polling thread. It is important to wait
|
||||
// here because we passed information to the modbus thread that is
|
||||
// on this stack.
|
||||
pthread_join(thread, nullptr);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue