From 8493fc52671bd8c8b0c69e82b2527fc07ab683f1 Mon Sep 17 00:00:00 2001 From: Valerio De Benedetto Date: Wed, 15 Mar 2023 15:08:18 +0100 Subject: [PATCH] Refactoring of NMBS_*_DISABLED defines --- nanomodbus.c | 172 ++++++++++++++++++++++----------------------------- nanomodbus.h | 93 +++++++++------------------- 2 files changed, 101 insertions(+), 164 deletions(-) diff --git a/nanomodbus.c b/nanomodbus.c index 0c1f043..35bbbd3 100644 --- a/nanomodbus.c +++ b/nanomodbus.c @@ -85,6 +85,7 @@ static void msg_state_reset(nmbs_t* nmbs) { } +#ifndef NMBS_CLIENT_DISABLED static void msg_state_req(nmbs_t* nmbs, uint8_t fc) { if (nmbs->current_tid == UINT16_MAX) nmbs->current_tid = 1; @@ -98,6 +99,7 @@ static void msg_state_req(nmbs_t* nmbs, uint8_t fc) { if (nmbs->msg.unit_id == 0 && nmbs->platform.transport == NMBS_TRANSPORT_RTU) nmbs->msg.broadcast = true; } +#endif int nmbs_create(nmbs_t* nmbs, const nmbs_platform_conf* platform_conf) { @@ -124,31 +126,6 @@ int nmbs_create(nmbs_t* nmbs, const nmbs_platform_conf* platform_conf) { } -#ifndef NMBS_CLIENT_DISABLED -nmbs_error nmbs_client_create(nmbs_t* nmbs, const nmbs_platform_conf* platform_conf) { - return nmbs_create(nmbs, platform_conf); -} -#endif - - -#ifndef NMBS_SERVER_DISABLED -nmbs_error nmbs_server_create(nmbs_t* nmbs, uint8_t address_rtu, const nmbs_platform_conf* platform_conf, - const nmbs_callbacks* callbacks) { - if (platform_conf->transport == NMBS_TRANSPORT_RTU && address_rtu == 0) - return NMBS_ERROR_INVALID_ARGUMENT; - - nmbs_error ret = nmbs_create(nmbs, platform_conf); - if (ret != NMBS_ERROR_NONE) - return ret; - - nmbs->address_rtu = address_rtu; - nmbs->callbacks = *callbacks; - - return NMBS_ERROR_NONE; -} -#endif - - void nmbs_set_read_timeout(nmbs_t* nmbs, int32_t timeout_ms) { nmbs->read_timeout_ms = timeout_ms; } @@ -306,6 +283,37 @@ static nmbs_error recv_msg_header(nmbs_t* nmbs, bool* first_byte_received) { } +static void put_msg_header(nmbs_t* nmbs, uint16_t data_length) { + msg_buf_reset(nmbs); + + if (nmbs->platform.transport == NMBS_TRANSPORT_RTU) { + put_1(nmbs, nmbs->msg.unit_id); + } + else if (nmbs->platform.transport == NMBS_TRANSPORT_TCP) { + put_2(nmbs, nmbs->msg.transaction_id); + put_2(nmbs, 0); + put_2(nmbs, (uint16_t) (1 + 1 + data_length)); + put_1(nmbs, nmbs->msg.unit_id); + } + + put_1(nmbs, nmbs->msg.fc); +} + + +static nmbs_error send_msg(nmbs_t* nmbs) { + DEBUG("\n"); + + if (nmbs->platform.transport == NMBS_TRANSPORT_RTU) { + uint16_t crc = nmbs_crc_calc(nmbs->msg.buf, nmbs->msg.buf_idx); + put_2(nmbs, crc); + } + + nmbs_error err = send(nmbs, nmbs->msg.buf_idx); + + return err; +} + + #ifndef NMBS_SERVER_DISABLED static nmbs_error recv_req_header(nmbs_t* nmbs, bool* first_byte_received) { nmbs_error err = recv_msg_header(nmbs, first_byte_received); @@ -324,9 +332,27 @@ static nmbs_error recv_req_header(nmbs_t* nmbs, bool* first_byte_received) { return NMBS_ERROR_NONE; } + + +static void put_res_header(nmbs_t* nmbs, uint16_t data_length) { + put_msg_header(nmbs, data_length); + DEBUG("NMBS res -> fc %d\t", nmbs->msg.fc); +} + + +static nmbs_error send_exception_msg(nmbs_t* nmbs, uint8_t exception) { + nmbs->msg.fc += 0x80; + put_msg_header(nmbs, 1); + put_1(nmbs, exception); + + DEBUG("NMBS res -> exception %d\n", exception); + + return send_msg(nmbs); +} #endif +#ifndef NMBS_CLIENT_DISABLED static nmbs_error recv_res_header(nmbs_t* nmbs) { uint16_t req_transaction_id = nmbs->msg.transaction_id; uint8_t req_unit_id = nmbs->msg.unit_id; @@ -372,38 +398,6 @@ static nmbs_error recv_res_header(nmbs_t* nmbs) { } -static void put_msg_header(nmbs_t* nmbs, uint16_t data_length) { - msg_buf_reset(nmbs); - - if (nmbs->platform.transport == NMBS_TRANSPORT_RTU) { - put_1(nmbs, nmbs->msg.unit_id); - } - else if (nmbs->platform.transport == NMBS_TRANSPORT_TCP) { - put_2(nmbs, nmbs->msg.transaction_id); - put_2(nmbs, 0); - put_2(nmbs, (uint16_t) (1 + 1 + data_length)); - put_1(nmbs, nmbs->msg.unit_id); - } - - put_1(nmbs, nmbs->msg.fc); -} - - -static nmbs_error send_msg(nmbs_t* nmbs) { - DEBUG("\n"); - - if (nmbs->platform.transport == NMBS_TRANSPORT_RTU) { - uint16_t crc = nmbs_crc_calc(nmbs->msg.buf, nmbs->msg.buf_idx); - put_2(nmbs, crc); - } - - nmbs_error err = send(nmbs, nmbs->msg.buf_idx); - - return err; -} - - -#ifndef NMBS_CLIENT_DISABLED static void put_req_header(nmbs_t* nmbs, uint16_t data_length) { put_msg_header(nmbs, data_length); DEBUG("NMBS req -> fc %d\t", nmbs->msg.fc); @@ -412,26 +406,6 @@ static void put_req_header(nmbs_t* nmbs, uint16_t data_length) { #ifndef NMBS_SERVER_DISABLED -static void put_res_header(nmbs_t* nmbs, uint16_t data_length) { - put_msg_header(nmbs, data_length); - DEBUG("NMBS res -> fc %d\t", nmbs->msg.fc); -} -#endif - - -#ifndef NMBS_SERVER_DISABLED -static nmbs_error send_exception_msg(nmbs_t* nmbs, uint8_t exception) { - nmbs->msg.fc += 0x80; - put_msg_header(nmbs, 1); - put_1(nmbs, exception); - - DEBUG("NMBS res -> exception %d\n", exception); - - return send_msg(nmbs); -} -#endif - - #if !defined(NMBS_SERVER_READ_COILS_DISABLED) || !defined(NMBS_SERVER_READ_DISCRETE_INPUTS_DISABLED) static nmbs_error handle_read_discrete(nmbs_t* nmbs, nmbs_error (*callback)(uint16_t, uint16_t, nmbs_bitfield, void*)) { nmbs_error err = recv(nmbs, 4); @@ -819,7 +793,6 @@ static nmbs_error handle_write_multiple_registers(nmbs_t* nmbs) { #endif -#ifndef NMBS_SERVER_DISABLED static nmbs_error handle_req_fc(nmbs_t* nmbs) { DEBUG("fc %d\t", nmbs->msg.fc); @@ -879,10 +852,24 @@ static nmbs_error handle_req_fc(nmbs_t* nmbs) { return err; } -#endif -#ifndef NMBS_SERVER_DISABLED +nmbs_error nmbs_server_create(nmbs_t* nmbs, uint8_t address_rtu, const nmbs_platform_conf* platform_conf, + const nmbs_callbacks* callbacks) { + if (platform_conf->transport == NMBS_TRANSPORT_RTU && address_rtu == 0) + return NMBS_ERROR_INVALID_ARGUMENT; + + nmbs_error ret = nmbs_create(nmbs, platform_conf); + if (ret != NMBS_ERROR_NONE) + return ret; + + nmbs->address_rtu = address_rtu; + nmbs->callbacks = *callbacks; + + return NMBS_ERROR_NONE; +} + + nmbs_error nmbs_server_poll(nmbs_t* nmbs) { msg_state_reset(nmbs); @@ -917,6 +904,11 @@ nmbs_error nmbs_server_poll(nmbs_t* nmbs) { #ifndef NMBS_CLIENT_DISABLED +nmbs_error nmbs_client_create(nmbs_t* nmbs, const nmbs_platform_conf* platform_conf) { + return nmbs_create(nmbs, platform_conf); +} + + static nmbs_error read_discrete(nmbs_t* nmbs, uint8_t fc, uint16_t address, uint16_t quantity, nmbs_bitfield values) { if (quantity < 1 || quantity > 2000) return NMBS_ERROR_INVALID_ARGUMENT; @@ -963,24 +955,18 @@ static nmbs_error read_discrete(nmbs_t* nmbs, uint8_t fc, uint16_t address, uint return NMBS_ERROR_NONE; } -#endif -#ifndef NMBS_CLIENT_DISABLED nmbs_error nmbs_read_coils(nmbs_t* nmbs, uint16_t address, uint16_t quantity, nmbs_bitfield coils_out) { return read_discrete(nmbs, 1, address, quantity, coils_out); } -#endif -#ifndef NMBS_CLIENT_DISABLED nmbs_error nmbs_read_discrete_inputs(nmbs_t* nmbs, uint16_t address, uint16_t quantity, nmbs_bitfield inputs_out) { return read_discrete(nmbs, 2, address, quantity, inputs_out); } -#endif -#ifndef NMBS_CLIENT_DISABLED static nmbs_error read_registers(nmbs_t* nmbs, uint8_t fc, uint16_t address, uint16_t quantity, uint16_t* registers) { if (quantity < 1 || quantity > 125) return NMBS_ERROR_INVALID_ARGUMENT; @@ -1030,24 +1016,18 @@ static nmbs_error read_registers(nmbs_t* nmbs, uint8_t fc, uint16_t address, uin return NMBS_ERROR_NONE; } -#endif -#ifndef NMBS_CLIENT_DISABLED nmbs_error nmbs_read_holding_registers(nmbs_t* nmbs, uint16_t address, uint16_t quantity, uint16_t* registers_out) { return read_registers(nmbs, 3, address, quantity, registers_out); } -#endif -#ifndef NMBS_CLIENT_DISABLED nmbs_error nmbs_read_input_registers(nmbs_t* nmbs, uint16_t address, uint16_t quantity, uint16_t* registers_out) { return read_registers(nmbs, 4, address, quantity, registers_out); } -#endif -#ifndef NMBS_CLIENT_DISABLED nmbs_error nmbs_write_single_coil(nmbs_t* nmbs, uint16_t address, bool value) { msg_state_req(nmbs, 5); put_req_header(nmbs, 4); @@ -1090,10 +1070,8 @@ nmbs_error nmbs_write_single_coil(nmbs_t* nmbs, uint16_t address, bool value) { return NMBS_ERROR_NONE; } -#endif -#ifndef NMBS_CLIENT_DISABLED nmbs_error nmbs_write_single_register(nmbs_t* nmbs, uint16_t address, uint16_t value) { msg_state_req(nmbs, 6); put_req_header(nmbs, 4); @@ -1133,10 +1111,8 @@ nmbs_error nmbs_write_single_register(nmbs_t* nmbs, uint16_t address, uint16_t v return NMBS_ERROR_NONE; } -#endif -#ifndef NMBS_CLIENT_DISABLED nmbs_error nmbs_write_multiple_coils(nmbs_t* nmbs, uint16_t address, uint16_t quantity, const nmbs_bitfield coils) { if (quantity < 1 || quantity > 0x07B0) return NMBS_ERROR_INVALID_ARGUMENT; @@ -1190,10 +1166,8 @@ nmbs_error nmbs_write_multiple_coils(nmbs_t* nmbs, uint16_t address, uint16_t qu return NMBS_ERROR_NONE; } -#endif -#ifndef NMBS_CLIENT_DISABLED nmbs_error nmbs_write_multiple_registers(nmbs_t* nmbs, uint16_t address, uint16_t quantity, const uint16_t* registers) { if (quantity < 1 || quantity > 0x007B) return NMBS_ERROR_INVALID_ARGUMENT; @@ -1247,7 +1221,6 @@ nmbs_error nmbs_write_multiple_registers(nmbs_t* nmbs, uint16_t address, uint16_ return NMBS_ERROR_NONE; } -#endif nmbs_error nmbs_send_raw_pdu(nmbs_t* nmbs, uint8_t fc, const uint8_t* data, uint16_t data_len) { @@ -1283,6 +1256,7 @@ nmbs_error nmbs_receive_raw_pdu_response(nmbs_t* nmbs, uint8_t* data_out, uint16 return NMBS_ERROR_NONE; } +#endif #ifndef NMBS_STRERROR_DISABLED diff --git a/nanomodbus.h b/nanomodbus.h index 7c8b1e5..2adfed6 100644 --- a/nanomodbus.h +++ b/nanomodbus.h @@ -48,21 +48,6 @@ extern "C" { #endif -/** - * If NMBS_SERVER_DISABLED is set, disable all the server callbacks too. - */ - -#ifdef NMBS_SERVER_DISABLED -#define NMBS_SERVER_READ_COILS_DISABLED -#define NMBS_SERVER_READ_DISCRETE_INPUTS_DISABLED -#define NMBS_SERVER_READ_HOLDING_REGISTERS_DISABLED -#define NMBS_SERVER_READ_INPUT_REGISTERS_DISABLED -#define NMBS_SERVER_WRITE_SINGLE_COIL_DISABLED -#define NMBS_SERVER_WRITE_SINGLE_REGISTER_DISABLED -#define NMBS_SERVER_WRITE_MULTIPLE_COILS_DISABLED -#define NMBS_SERVER_WRITE_MULTIPLE_REGISTERS_DISABLED -#endif - /** * nanoMODBUS errors. * Values <= 0 are library errors, > 0 are modbus exceptions. @@ -159,6 +144,7 @@ typedef struct nmbs_platform_conf { * to nmbs_server_create together with this struct. */ typedef struct nmbs_callbacks { +#ifndef NMBS_SERVER_DISABLED #ifndef NMBS_SERVER_READ_COILS_DISABLED nmbs_error (*read_coils)(uint16_t address, uint16_t quantity, nmbs_bitfield coils_out, void* arg); #endif @@ -189,6 +175,7 @@ typedef struct nmbs_callbacks { #ifndef NMBS_SERVER_WRITE_MULTIPLE_REGISTERS_DISABLED nmbs_error (*write_multiple_registers)(uint16_t address, uint16_t quantity, const uint16_t* registers, void* arg); +#endif #endif char _nonempty; // Struct may become empty, which is undefined behavior @@ -227,29 +214,6 @@ typedef struct nmbs_t { */ static const uint8_t NMBS_BROADCAST_ADDRESS = 0; -#ifndef NMBS_CLIENT_DISABLED -/** Create a new Modbus client. - * @param nmbs pointer to the nmbs_t instance where the client will be created. - * @param platform_conf nmbs_platform_conf struct with platform configuration. It may be discarded after calling this method. - * -* @return NMBS_ERROR_NONE if successful, NMBS_ERROR_INVALID_ARGUMENT otherwise. - */ -nmbs_error nmbs_client_create(nmbs_t* nmbs, const nmbs_platform_conf* platform_conf); -#endif - -#ifndef NMBS_SERVER_DISABLED -/** Create a new Modbus server. - * @param nmbs pointer to the nmbs_t instance where the client will be created. - * @param address_rtu RTU address of this server. Can be 0 if transport is not RTU. - * @param platform_conf nmbs_platform_conf struct with platform configuration. It may be discarded after calling this method. - * @param callbacks nmbs_callbacks struct with server request callbacks. It may be discarded after calling this method. - * - * @return NMBS_ERROR_NONE if successful, NMBS_ERROR_INVALID_ARGUMENT otherwise. - */ -nmbs_error nmbs_server_create(nmbs_t* nmbs, uint8_t address_rtu, const nmbs_platform_conf* platform_conf, - const nmbs_callbacks* callbacks); -#endif - /** Set the request/response timeout. * If the target instance is a server, sets the timeout of the nmbs_server_poll() function. * If the target instance is a client, sets the response timeout after sending a request. In case of timeout, @@ -271,15 +235,18 @@ void nmbs_set_byte_timeout(nmbs_t* nmbs, int32_t timeout_ms); */ void nmbs_set_platform_arg(nmbs_t* nmbs, void* arg); -#ifndef NMBS_CLIENT_DISABLED -/** Set the recipient server address of the next request on RTU transport. - * @param nmbs pointer to the nmbs_t instance - * @param address server address - */ -void nmbs_set_destination_rtu_address(nmbs_t* nmbs, uint8_t address); -#endif - #ifndef NMBS_SERVER_DISABLED +/** Create a new Modbus server. + * @param nmbs pointer to the nmbs_t instance where the client will be created. + * @param address_rtu RTU address of this server. Can be 0 if transport is not RTU. + * @param platform_conf nmbs_platform_conf struct with platform configuration. It may be discarded after calling this method. + * @param callbacks nmbs_callbacks struct with server request callbacks. It may be discarded after calling this method. + * + * @return NMBS_ERROR_NONE if successful, NMBS_ERROR_INVALID_ARGUMENT otherwise. + */ +nmbs_error nmbs_server_create(nmbs_t* nmbs, uint8_t address_rtu, const nmbs_platform_conf* platform_conf, + const nmbs_callbacks* callbacks); + /** Handle incoming requests to the server. * This function should be called in a loop in order to serve any incoming request. Its maximum duration, in case of no * received request, is the value set with nmbs_set_read_timeout() (unless set to < 0). @@ -290,7 +257,21 @@ void nmbs_set_destination_rtu_address(nmbs_t* nmbs, uint8_t address); nmbs_error nmbs_server_poll(nmbs_t* nmbs); #endif -#ifndef NMBS_SERVER_READ_COILS_DISABLED +#ifndef NMBS_CLIENT_DISABLED +/** Create a new Modbus client. + * @param nmbs pointer to the nmbs_t instance where the client will be created. + * @param platform_conf nmbs_platform_conf struct with platform configuration. It may be discarded after calling this method. + * +* @return NMBS_ERROR_NONE if successful, NMBS_ERROR_INVALID_ARGUMENT otherwise. + */ +nmbs_error nmbs_client_create(nmbs_t* nmbs, const nmbs_platform_conf* platform_conf); + +/** Set the recipient server address of the next request on RTU transport. + * @param nmbs pointer to the nmbs_t instance + * @param address server address + */ +void nmbs_set_destination_rtu_address(nmbs_t* nmbs, uint8_t address); + /** Send a FC 01 (0x01) Read Coils request * @param nmbs pointer to the nmbs_t instance * @param address starting address @@ -300,9 +281,7 @@ nmbs_error nmbs_server_poll(nmbs_t* nmbs); * @return NMBS_ERROR_NONE if successful, other errors otherwise. */ nmbs_error nmbs_read_coils(nmbs_t* nmbs, uint16_t address, uint16_t quantity, nmbs_bitfield coils_out); -#endif -#ifndef NMBS_SERVER_READ_DISCRETE_INPUTS_DISABLED /** Send a FC 02 (0x02) Read Discrete Inputs request * @param nmbs pointer to the nmbs_t instance * @param address starting address @@ -312,9 +291,7 @@ nmbs_error nmbs_read_coils(nmbs_t* nmbs, uint16_t address, uint16_t quantity, nm * @return NMBS_ERROR_NONE if successful, other errors otherwise. */ nmbs_error nmbs_read_discrete_inputs(nmbs_t* nmbs, uint16_t address, uint16_t quantity, nmbs_bitfield inputs_out); -#endif -#ifndef NMBS_SERVER_READ_HOLDING_REGISTERS_DISABLED /** Send a FC 03 (0x03) Read Holding Registers request * @param nmbs pointer to the nmbs_t instance * @param address starting address @@ -324,9 +301,7 @@ nmbs_error nmbs_read_discrete_inputs(nmbs_t* nmbs, uint16_t address, uint16_t qu * @return NMBS_ERROR_NONE if successful, other errors otherwise. */ nmbs_error nmbs_read_holding_registers(nmbs_t* nmbs, uint16_t address, uint16_t quantity, uint16_t* registers_out); -#endif -#ifndef NMBS_SERVER_READ_INPUT_REGISTERS_DISABLED /** Send a FC 04 (0x04) Read Input Registers request * @param nmbs pointer to the nmbs_t instance * @param address starting address @@ -336,9 +311,7 @@ nmbs_error nmbs_read_holding_registers(nmbs_t* nmbs, uint16_t address, uint16_t * @return NMBS_ERROR_NONE if successful, other errors otherwise. */ nmbs_error nmbs_read_input_registers(nmbs_t* nmbs, uint16_t address, uint16_t quantity, uint16_t* registers_out); -#endif -#ifndef NMBS_SERVER_WRITE_SINGLE_COIL_DISABLED /** Send a FC 05 (0x05) Write Single Coil request * @param nmbs pointer to the nmbs_t instance * @param address coil address @@ -347,9 +320,7 @@ nmbs_error nmbs_read_input_registers(nmbs_t* nmbs, uint16_t address, uint16_t qu * @return NMBS_ERROR_NONE if successful, other errors otherwise. */ nmbs_error nmbs_write_single_coil(nmbs_t* nmbs, uint16_t address, bool value); -#endif -#ifndef NMBS_SERVER_WRITE_SINGLE_REGISTER_DISABLED /** Send a FC 06 (0x06) Write Single Register request * @param nmbs pointer to the nmbs_t instance * @param address register address @@ -358,9 +329,7 @@ nmbs_error nmbs_write_single_coil(nmbs_t* nmbs, uint16_t address, bool value); * @return NMBS_ERROR_NONE if successful, other errors otherwise. */ nmbs_error nmbs_write_single_register(nmbs_t* nmbs, uint16_t address, uint16_t value); -#endif -#ifndef NMBS_SERVER_WRITE_MULTIPLE_COILS_DISABLED /** Send a FC 15 (0x0F) Write Multiple Coils * @param nmbs pointer to the nmbs_t instance * @param address starting address @@ -370,9 +339,7 @@ nmbs_error nmbs_write_single_register(nmbs_t* nmbs, uint16_t address, uint16_t v * @return NMBS_ERROR_NONE if successful, other errors otherwise. */ nmbs_error nmbs_write_multiple_coils(nmbs_t* nmbs, uint16_t address, uint16_t quantity, const nmbs_bitfield coils); -#endif -#ifndef NMBS_SERVER_WRITE_MULTIPLE_REGISTERS_DISABLED /** Send a FC 16 (0x10) Write Multiple Registers * @param nmbs pointer to the nmbs_t instance * @param address starting address @@ -382,9 +349,7 @@ nmbs_error nmbs_write_multiple_coils(nmbs_t* nmbs, uint16_t address, uint16_t qu * @return NMBS_ERROR_NONE if successful, other errors otherwise. */ nmbs_error nmbs_write_multiple_registers(nmbs_t* nmbs, uint16_t address, uint16_t quantity, const uint16_t* registers); -#endif -#ifndef NMBS_CLIENT_DISABLED /** Send a raw Modbus PDU. * CRC on RTU will be calculated and sent by this function. * @param nmbs pointer to the nmbs_t instance @@ -395,9 +360,7 @@ nmbs_error nmbs_write_multiple_registers(nmbs_t* nmbs, uint16_t address, uint16_ * @return NMBS_ERROR_NONE if successful, other errors otherwise. */ nmbs_error nmbs_send_raw_pdu(nmbs_t* nmbs, uint8_t fc, const uint8_t* data, uint16_t data_len); -#endif -#ifndef NMBS_CLIENT_DISABLED /** Receive a raw response Modbus PDU. * @param nmbs pointer to the nmbs_t instance * @param data_out response data. It's up to the caller to convert this data to host byte order.