PR-777 Add the data exchange for modbus
This commit is contained in:
parent
9458b89d85
commit
465d9bcefc
|
@ -241,7 +241,7 @@ int write_holding_register(unsigned char* buffer, int buffer_size, IndexedStrate
|
|||
{
|
||||
int16_t start = mb_to_word(buffer[8], buffer[9]);
|
||||
|
||||
modbus_errno err = strategy->WriteHoldingRegister(start, buffer + 9, 2);
|
||||
modbus_errno err = strategy->WriteHoldingRegister(start, buffer + 9);
|
||||
if (err) {
|
||||
return modbus_error(buffer, ERR_ILLEGAL_DATA_ADDRESS);
|
||||
}
|
||||
|
@ -308,7 +308,7 @@ int write_multiple_registers(unsigned char* buffer, int buffer_size, IndexedStra
|
|||
/// @param buffer_size
|
||||
/// @param user_data The mapping strategy.
|
||||
/// @return size of the response message in bytes
|
||||
int process_modbus_message(unsigned char *buffer, int buffer_size, void* user_data)
|
||||
int modbus_process_message(unsigned char *buffer, int buffer_size, void* user_data)
|
||||
{
|
||||
auto strategy = reinterpret_cast<IndexedStrategy*>(user_data);
|
||||
int message_length = 0;
|
||||
|
@ -376,6 +376,29 @@ int process_modbus_message(unsigned char *buffer, int buffer_size, void* user_da
|
|||
return message_length;
|
||||
}
|
||||
|
||||
/// Arguments that are passed to the thread to exchange modbus data with the
|
||||
/// runtime.
|
||||
struct ModbusExchangeArgs {
|
||||
IndexedStrategy* strategy;
|
||||
volatile bool* run;
|
||||
std::chrono::milliseconds interval;
|
||||
};
|
||||
|
||||
/// The main function for the thread that is responsible for exchanging
|
||||
/// modbus data with the located variables.
|
||||
void* modbus_exchange_data(void* args) {
|
||||
auto exchange_args = reinterpret_cast<ModbusExchangeArgs*>(args);
|
||||
|
||||
while (*exchange_args->run) {
|
||||
spdlog::trace("Exchanging modbus master data");
|
||||
exchange_args->strategy->Exchange();
|
||||
this_thread::sleep_for(exchange_args->interval);
|
||||
}
|
||||
|
||||
delete exchange_args;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// Container for reading in configuration from the config.ini
|
||||
/// This is populated with values from the config file.
|
||||
|
@ -447,8 +470,24 @@ int8_t modbus_slave_run(std::unique_ptr<std::istream, std::function<void(std::is
|
|||
|
||||
IndexedStrategy strategy(bindings);
|
||||
|
||||
pthread_t exchange_data_thread;
|
||||
auto args = new ModbusExchangeArgs {
|
||||
.strategy=&strategy,
|
||||
.run=&run,
|
||||
.interval=std::chrono::milliseconds(100)
|
||||
};
|
||||
|
||||
int ret = pthread_create(&exchange_data_thread, NULL, modbus_exchange_data, args);
|
||||
if (ret == 0) {
|
||||
pthread_detach(exchange_data_thread);
|
||||
} else {
|
||||
delete args;
|
||||
}
|
||||
|
||||
spdlog::info("Starting modbus slave on port {}", config.port);
|
||||
startServer(config.port, run, &process_modbus_message, &strategy);
|
||||
startServer(config.port, run, &modbus_process_message, &strategy);
|
||||
|
||||
pthread_join(exchange_data_thread, nullptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
class GlueVariablesBinding;
|
||||
|
||||
/// @brief Process an individual modbus message.
|
||||
int process_modbus_message(unsigned char *buffer, int buffer_size,
|
||||
int modbus_process_message(unsigned char *buffer, int buffer_size,
|
||||
void* user_data);
|
||||
|
||||
/// @brief Start the modbus slave server.
|
||||
|
|
|
@ -132,8 +132,8 @@ int createSocket(uint16_t port)
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Blocking call. Wait here for the client to connect.
|
||||
/// @param socket_fd
|
||||
/// @param protocol_type
|
||||
/// @param socket_fd The socket file descriptor.
|
||||
/// @param run_server A flag to terminate this client.
|
||||
/// @return file descriptor to communicate with the client
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int waitForClient(int socket_fd, volatile bool& run_server)
|
||||
|
@ -153,6 +153,7 @@ int waitForClient(int socket_fd, volatile bool& run_server)
|
|||
SetSocketBlockingEnabled(client_fd, true);
|
||||
break;
|
||||
}
|
||||
|
||||
this_thread::sleep_for(chrono::milliseconds(100));
|
||||
}
|
||||
|
||||
|
@ -228,16 +229,14 @@ void *handleConnections(void *arguments)
|
|||
delete args;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Function to start the server.
|
||||
/// @brief Function to start a socket server.
|
||||
///
|
||||
/// It receives the port number as argument and
|
||||
/// creates an infinite loop to listen and parse the messages sent by the
|
||||
/// clients
|
||||
/// @param port
|
||||
/// @param protocol_type
|
||||
/// @see stopServer()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @param port The port to listen on.
|
||||
/// @param process_message A function to run to process socket messages.
|
||||
/// @param user_data Passed into the process_message function as client data.
|
||||
void startServer(uint16_t port, volatile bool& run_server, process_message_fn process_message, void* user_data)
|
||||
{
|
||||
int socket_fd, client_fd;
|
||||
|
|
|
@ -98,7 +98,7 @@ SCENARIO("indexed_strategy", "")
|
|||
{
|
||||
int_val = 0;
|
||||
uint8_t buffer[2] = { 0, 1 };
|
||||
REQUIRE(strategy.WriteHoldingRegister(0, buffer, 2) == 0);
|
||||
REQUIRE(strategy.WriteHoldingRegister(0, buffer) == 0);
|
||||
strategy.Exchange();
|
||||
REQUIRE(int_val == 1);
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ SCENARIO("indexed_strategy", "")
|
|||
{
|
||||
int_val = 0;
|
||||
uint8_t buffer[2] = { 0, 1 };
|
||||
REQUIRE(strategy.WriteHoldingRegister(1024, buffer, 2) == 0);
|
||||
REQUIRE(strategy.WriteHoldingRegister(1024, buffer) == 0);
|
||||
strategy.Exchange();
|
||||
REQUIRE(int_val == 1);
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ SCENARIO("slave", "")
|
|||
{
|
||||
// FS, Start, Num, CRC
|
||||
uint8_t buffer[BUF_SIZE] = { HEADER, 1, 0, 0, 0, 9, 0 };
|
||||
int size = process_modbus_message(buffer, BUF_SIZE, &strategy);
|
||||
int size = modbus_process_message(buffer, BUF_SIZE, &strategy);
|
||||
REQUIRE(buffer[7] == 0x01);
|
||||
REQUIRE(buffer[8] == 0x02);
|
||||
REQUIRE(buffer[9] == 0xCD);
|
||||
|
@ -77,7 +77,7 @@ SCENARIO("slave", "")
|
|||
{
|
||||
// FS, Start, Num, CRC
|
||||
uint8_t buffer[BUF_SIZE] = { HEADER, 1, 0, 1, 0, 8, 0 };
|
||||
int size = process_modbus_message(buffer, BUF_SIZE, &strategy);
|
||||
int size = modbus_process_message(buffer, BUF_SIZE, &strategy);
|
||||
REQUIRE(buffer[7] == 0x01);
|
||||
REQUIRE(buffer[8] == 0x01);
|
||||
REQUIRE(buffer[9] == 0xE6);
|
||||
|
@ -88,7 +88,7 @@ SCENARIO("slave", "")
|
|||
{
|
||||
// FS, Start, Num, By, Values, CRC
|
||||
uint8_t buffer[BUF_SIZE] = { HEADER, 15, 0, 0, 0, 9, 2, 0xCD, 0x01, 0 };
|
||||
int size = process_modbus_message(buffer, BUF_SIZE, &strategy);
|
||||
int size = modbus_process_message(buffer, BUF_SIZE, &strategy);
|
||||
REQUIRE(buffer[7] == 15);
|
||||
REQUIRE(buffer[8] == 0);
|
||||
REQUIRE(buffer[9] == 0);
|
||||
|
@ -135,7 +135,7 @@ SCENARIO("slave", "")
|
|||
{
|
||||
// FS, Start, Num, CRC
|
||||
uint8_t buffer[BUF_SIZE] = { HEADER, 2, 0, 0, 0, 9, 0 };
|
||||
int size = process_modbus_message(buffer, BUF_SIZE, &strategy);
|
||||
int size = modbus_process_message(buffer, BUF_SIZE, &strategy);
|
||||
REQUIRE(buffer[7] == 0x02);
|
||||
REQUIRE(buffer[8] == 0x02);
|
||||
REQUIRE(buffer[9] == 0xCD);
|
||||
|
@ -147,7 +147,7 @@ SCENARIO("slave", "")
|
|||
{
|
||||
// FS, Start, Num, CRC
|
||||
uint8_t buffer[BUF_SIZE] = { HEADER, 2, 0, 1, 0, 8, 0 };
|
||||
int size = process_modbus_message(buffer, BUF_SIZE, &strategy);
|
||||
int size = modbus_process_message(buffer, BUF_SIZE, &strategy);
|
||||
REQUIRE(buffer[7] == 0x02);
|
||||
REQUIRE(buffer[8] == 0x01);
|
||||
REQUIRE(buffer[9] == 0xE6);
|
||||
|
@ -176,7 +176,7 @@ SCENARIO("slave", "")
|
|||
{
|
||||
// FS, Start, Num, CRC
|
||||
uint8_t buffer[BUF_SIZE] = { HEADER, 3, 0, 0, 0, 1, 0 };
|
||||
int size = process_modbus_message(buffer, BUF_SIZE, &strategy);
|
||||
int size = modbus_process_message(buffer, BUF_SIZE, &strategy);
|
||||
REQUIRE(buffer[7] == 0x03);
|
||||
REQUIRE(buffer[8] == 0x02);
|
||||
REQUIRE(buffer[9] == 0x00);
|
||||
|
@ -188,7 +188,7 @@ SCENARIO("slave", "")
|
|||
{
|
||||
// FS, Start, Num, CRC
|
||||
uint8_t buffer[BUF_SIZE] = { HEADER, 3, 0x04, 0, 0, 1, 0 };
|
||||
int size = process_modbus_message(buffer, BUF_SIZE, &strategy);
|
||||
int size = modbus_process_message(buffer, BUF_SIZE, &strategy);
|
||||
REQUIRE(buffer[7] == 0x03);
|
||||
REQUIRE(buffer[8] == 0x02);
|
||||
REQUIRE(buffer[9] == 0x00);
|
||||
|
@ -200,7 +200,7 @@ SCENARIO("slave", "")
|
|||
{
|
||||
// FS, Start, Val, CRC
|
||||
uint8_t buffer[BUF_SIZE] = { HEADER, 6, 0, 0, 0, 0x03, 0 };
|
||||
int size = process_modbus_message(buffer, BUF_SIZE, &strategy);
|
||||
int size = modbus_process_message(buffer, BUF_SIZE, &strategy);
|
||||
REQUIRE(buffer[7] == 0x06);
|
||||
REQUIRE(buffer[8] == 0x00);
|
||||
REQUIRE(buffer[9] == 0x00);
|
||||
|
@ -213,7 +213,7 @@ SCENARIO("slave", "")
|
|||
{
|
||||
// FS, Start, Num, By, Val, CRC
|
||||
uint8_t buffer[BUF_SIZE] = { HEADER, 16, 0, 0, 0, 1, 2, 0, 0x02, 0 };
|
||||
int size = process_modbus_message(buffer, BUF_SIZE, &strategy);
|
||||
int size = modbus_process_message(buffer, BUF_SIZE, &strategy);
|
||||
REQUIRE(buffer[7] == 16);
|
||||
REQUIRE(buffer[8] == 0x00);
|
||||
REQUIRE(buffer[9] == 0x00);
|
||||
|
@ -240,7 +240,7 @@ SCENARIO("slave", "")
|
|||
{
|
||||
// FS, Start, Num, CRC
|
||||
uint8_t buffer[BUF_SIZE] = { HEADER, 4, 0, 0, 0, 1, 0 };
|
||||
int size = process_modbus_message(buffer, BUF_SIZE, &strategy);
|
||||
int size = modbus_process_message(buffer, BUF_SIZE, &strategy);
|
||||
REQUIRE(buffer[7] == 0x04);
|
||||
REQUIRE(buffer[8] == 0x02);
|
||||
REQUIRE(buffer[9] == 0x00);
|
||||
|
@ -270,7 +270,7 @@ SCENARIO("slave", "")
|
|||
{
|
||||
// FS, Start, Num, CRC
|
||||
uint8_t buffer[BUF_SIZE] = { HEADER, 5, 0, 0, 0xFF, 0, 0 };
|
||||
int size = process_modbus_message(buffer, BUF_SIZE, &strategy);
|
||||
int size = modbus_process_message(buffer, BUF_SIZE, &strategy);
|
||||
REQUIRE(buffer[7] == 0x05);
|
||||
REQUIRE(buffer[8] == 0x00);
|
||||
REQUIRE(buffer[9] == 0x00);
|
||||
|
|
Loading…
Reference in New Issue