Support to NMBS_CLIENT_DISABLED and NMBS_SERVER_DISABLED defines
This commit is contained in:
parent
ee6dd565d4
commit
5358abde7b
@ -8,9 +8,10 @@ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
|
|||||||
|
|
||||||
include_directories(tests examples .)
|
include_directories(tests examples .)
|
||||||
|
|
||||||
#add_definitions(-DNMBS_DEBUG)
|
|
||||||
|
|
||||||
add_executable(nanomodbus_tests nanomodbus.c tests/nanomodbus_tests.c)
|
add_executable(nanomodbus_tests nanomodbus.c tests/nanomodbus_tests.c)
|
||||||
|
add_executable(server_disabled nanomodbus.c tests/server_disabled.c)
|
||||||
|
add_executable(client_disabled nanomodbus.c tests/client_disabled.c)
|
||||||
|
|
||||||
add_executable(client-tcp nanomodbus.c examples/client-tcp.c)
|
add_executable(client-tcp nanomodbus.c examples/client-tcp.c)
|
||||||
add_executable(server-tcp nanomodbus.c examples/server-tcp.c)
|
add_executable(server-tcp nanomodbus.c examples/server-tcp.c)
|
||||||
|
|
||||||
|
|||||||
10
README.md
10
README.md
@ -4,7 +4,9 @@ nanoMODBUS is a small C library that implements the Modbus protocol. It is espec
|
|||||||
system like microcontrollers.
|
system like microcontrollers.
|
||||||
Its main features are:
|
Its main features are:
|
||||||
|
|
||||||
- Compact size, only ~1000 lines of code
|
- Compact size
|
||||||
|
- Only ~1000 lines of code
|
||||||
|
- Client and server code can be disabled, if not needed
|
||||||
- No dynamic memory allocations
|
- No dynamic memory allocations
|
||||||
- Transports:
|
- Transports:
|
||||||
- RTU
|
- RTU
|
||||||
@ -145,6 +147,8 @@ make
|
|||||||
|
|
||||||
## Misc
|
## Misc
|
||||||
|
|
||||||
- To reduce code size, you can define `NMBS_STRERROR_DISABLED` to disable the code that converts `nmbs_error`s to
|
- To reduce code size, you can define the following `#define`s:
|
||||||
strings
|
- `NMBS_CLIENT_DISABLED` to disable all client code
|
||||||
|
- `NMBS_SERVER_DISABLED` to disable all server code
|
||||||
|
- `NMBS_STRERROR_DISABLED` to disable the code that converts `nmbs_error`s to strings
|
||||||
- Debug prints about received and sent messages can be enabled by defining `NMBS_DEBUG`
|
- Debug prints about received and sent messages can be enabled by defining `NMBS_DEBUG`
|
||||||
|
|||||||
60
nanomodbus.c
60
nanomodbus.c
@ -123,11 +123,13 @@ 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) {
|
nmbs_error nmbs_client_create(nmbs_t* nmbs, const nmbs_platform_conf* platform_conf) {
|
||||||
return nmbs_create(nmbs, 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,
|
nmbs_error nmbs_server_create(nmbs_t* nmbs, uint8_t address_rtu, const nmbs_platform_conf* platform_conf,
|
||||||
const nmbs_callbacks* callbacks) {
|
const nmbs_callbacks* callbacks) {
|
||||||
if (platform_conf->transport == NMBS_TRANSPORT_RTU && address_rtu == 0)
|
if (platform_conf->transport == NMBS_TRANSPORT_RTU && address_rtu == 0)
|
||||||
@ -142,6 +144,7 @@ nmbs_error nmbs_server_create(nmbs_t* nmbs, uint8_t address_rtu, const nmbs_plat
|
|||||||
|
|
||||||
return NMBS_ERROR_NONE;
|
return NMBS_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void nmbs_set_read_timeout(nmbs_t* nmbs, int32_t timeout_ms) {
|
void nmbs_set_read_timeout(nmbs_t* nmbs, int32_t timeout_ms) {
|
||||||
@ -314,7 +317,7 @@ static nmbs_error recv_msg_header(nmbs_t* nmbs, bool* first_byte_received) {
|
|||||||
return NMBS_ERROR_NONE;
|
return NMBS_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
static nmbs_error recv_req_header(nmbs_t* nmbs, bool* first_byte_received) {
|
static nmbs_error recv_req_header(nmbs_t* nmbs, bool* first_byte_received) {
|
||||||
nmbs_error err = recv_msg_header(nmbs, first_byte_received);
|
nmbs_error err = recv_msg_header(nmbs, first_byte_received);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
@ -332,7 +335,7 @@ static nmbs_error recv_req_header(nmbs_t* nmbs, bool* first_byte_received) {
|
|||||||
|
|
||||||
return NMBS_ERROR_NONE;
|
return NMBS_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static nmbs_error recv_res_header(nmbs_t* nmbs) {
|
static nmbs_error recv_res_header(nmbs_t* nmbs) {
|
||||||
uint16_t req_transaction_id = nmbs->msg.transaction_id;
|
uint16_t req_transaction_id = nmbs->msg.transaction_id;
|
||||||
@ -409,19 +412,23 @@ static nmbs_error send_msg_footer(nmbs_t* nmbs) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NMBS_CLIENT_DISABLED
|
||||||
static void send_req_header(nmbs_t* nmbs, uint16_t data_length) {
|
static void send_req_header(nmbs_t* nmbs, uint16_t data_length) {
|
||||||
send_msg_header(nmbs, data_length);
|
send_msg_header(nmbs, data_length);
|
||||||
DEBUG("NMBS req -> fc %d\t", nmbs->msg.fc);
|
DEBUG("NMBS req -> fc %d\t", nmbs->msg.fc);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
static void send_res_header(nmbs_t* nmbs, uint16_t data_length) {
|
static void send_res_header(nmbs_t* nmbs, uint16_t data_length) {
|
||||||
send_msg_header(nmbs, data_length);
|
send_msg_header(nmbs, data_length);
|
||||||
DEBUG("NMBS res -> fc %d\t", nmbs->msg.fc);
|
DEBUG("NMBS res -> fc %d\t", nmbs->msg.fc);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
static nmbs_error handle_exception(nmbs_t* nmbs, uint8_t exception) {
|
static nmbs_error handle_exception(nmbs_t* nmbs, uint8_t exception) {
|
||||||
nmbs->msg.fc += 0x80;
|
nmbs->msg.fc += 0x80;
|
||||||
send_msg_header(nmbs, 1);
|
send_msg_header(nmbs, 1);
|
||||||
@ -431,8 +438,10 @@ static nmbs_error handle_exception(nmbs_t* nmbs, uint8_t exception) {
|
|||||||
|
|
||||||
return send_msg_footer(nmbs);
|
return send_msg_footer(nmbs);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
static nmbs_error handle_read_discrete(nmbs_t* nmbs, nmbs_error (*callback)(uint16_t, uint16_t, nmbs_bitfield)) {
|
static nmbs_error handle_read_discrete(nmbs_t* nmbs, nmbs_error (*callback)(uint16_t, uint16_t, nmbs_bitfield)) {
|
||||||
nmbs_error err = recv(nmbs, 4);
|
nmbs_error err = recv(nmbs, 4);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
@ -490,8 +499,10 @@ static nmbs_error handle_read_discrete(nmbs_t* nmbs, nmbs_error (*callback)(uint
|
|||||||
|
|
||||||
return NMBS_ERROR_NONE;
|
return NMBS_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
static nmbs_error handle_read_registers(nmbs_t* nmbs, nmbs_error (*callback)(uint16_t, uint16_t, uint16_t*)) {
|
static nmbs_error handle_read_registers(nmbs_t* nmbs, nmbs_error (*callback)(uint16_t, uint16_t, uint16_t*)) {
|
||||||
nmbs_error err = recv(nmbs, 4);
|
nmbs_error err = recv(nmbs, 4);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
@ -549,28 +560,38 @@ static nmbs_error handle_read_registers(nmbs_t* nmbs, nmbs_error (*callback)(uin
|
|||||||
|
|
||||||
return NMBS_ERROR_NONE;
|
return NMBS_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
static nmbs_error handle_read_coils(nmbs_t* nmbs) {
|
static nmbs_error handle_read_coils(nmbs_t* nmbs) {
|
||||||
return handle_read_discrete(nmbs, nmbs->callbacks.read_coils);
|
return handle_read_discrete(nmbs, nmbs->callbacks.read_coils);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
static nmbs_error handle_read_discrete_inputs(nmbs_t* nmbs) {
|
static nmbs_error handle_read_discrete_inputs(nmbs_t* nmbs) {
|
||||||
return handle_read_discrete(nmbs, nmbs->callbacks.read_discrete_inputs);
|
return handle_read_discrete(nmbs, nmbs->callbacks.read_discrete_inputs);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
static nmbs_error handle_read_holding_registers(nmbs_t* nmbs) {
|
static nmbs_error handle_read_holding_registers(nmbs_t* nmbs) {
|
||||||
return handle_read_registers(nmbs, nmbs->callbacks.read_holding_registers);
|
return handle_read_registers(nmbs, nmbs->callbacks.read_holding_registers);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
static nmbs_error handle_read_input_registers(nmbs_t* nmbs) {
|
static nmbs_error handle_read_input_registers(nmbs_t* nmbs) {
|
||||||
return handle_read_registers(nmbs, nmbs->callbacks.read_input_registers);
|
return handle_read_registers(nmbs, nmbs->callbacks.read_input_registers);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
static nmbs_error handle_write_single_coil(nmbs_t* nmbs) {
|
static nmbs_error handle_write_single_coil(nmbs_t* nmbs) {
|
||||||
nmbs_error err = recv(nmbs, 4);
|
nmbs_error err = recv(nmbs, 4);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
@ -617,8 +638,10 @@ static nmbs_error handle_write_single_coil(nmbs_t* nmbs) {
|
|||||||
|
|
||||||
return NMBS_ERROR_NONE;
|
return NMBS_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
static nmbs_error handle_write_single_register(nmbs_t* nmbs) {
|
static nmbs_error handle_write_single_register(nmbs_t* nmbs) {
|
||||||
nmbs_error err = recv(nmbs, 4);
|
nmbs_error err = recv(nmbs, 4);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
@ -662,8 +685,10 @@ static nmbs_error handle_write_single_register(nmbs_t* nmbs) {
|
|||||||
|
|
||||||
return NMBS_ERROR_NONE;
|
return NMBS_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
static nmbs_error handle_write_multiple_coils(nmbs_t* nmbs) {
|
static nmbs_error handle_write_multiple_coils(nmbs_t* nmbs) {
|
||||||
nmbs_error err = recv(nmbs, 5);
|
nmbs_error err = recv(nmbs, 5);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
@ -730,8 +755,10 @@ static nmbs_error handle_write_multiple_coils(nmbs_t* nmbs) {
|
|||||||
|
|
||||||
return NMBS_ERROR_NONE;
|
return NMBS_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
static nmbs_error handle_write_multiple_registers(nmbs_t* nmbs) {
|
static nmbs_error handle_write_multiple_registers(nmbs_t* nmbs) {
|
||||||
nmbs_error err = recv(nmbs, 5);
|
nmbs_error err = recv(nmbs, 5);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
@ -798,8 +825,10 @@ static nmbs_error handle_write_multiple_registers(nmbs_t* nmbs) {
|
|||||||
|
|
||||||
return NMBS_ERROR_NONE;
|
return NMBS_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
static nmbs_error handle_req_fc(nmbs_t* nmbs) {
|
static nmbs_error handle_req_fc(nmbs_t* nmbs) {
|
||||||
DEBUG("fc %d\t", nmbs->msg.fc);
|
DEBUG("fc %d\t", nmbs->msg.fc);
|
||||||
|
|
||||||
@ -843,8 +872,10 @@ static nmbs_error handle_req_fc(nmbs_t* nmbs) {
|
|||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
nmbs_error nmbs_server_poll(nmbs_t* nmbs) {
|
nmbs_error nmbs_server_poll(nmbs_t* nmbs) {
|
||||||
msg_state_reset(nmbs);
|
msg_state_reset(nmbs);
|
||||||
|
|
||||||
@ -875,8 +906,10 @@ nmbs_error nmbs_server_poll(nmbs_t* nmbs) {
|
|||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_CLIENT_DISABLED
|
||||||
static nmbs_error read_discrete(nmbs_t* nmbs, uint8_t fc, uint16_t address, uint16_t quantity, nmbs_bitfield values) {
|
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)
|
if (quantity < 1 || quantity > 2000)
|
||||||
return NMBS_ERROR_INVALID_ARGUMENT;
|
return NMBS_ERROR_INVALID_ARGUMENT;
|
||||||
@ -923,18 +956,24 @@ static nmbs_error read_discrete(nmbs_t* nmbs, uint8_t fc, uint16_t address, uint
|
|||||||
|
|
||||||
return NMBS_ERROR_NONE;
|
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) {
|
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);
|
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) {
|
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);
|
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) {
|
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)
|
if (quantity < 1 || quantity > 125)
|
||||||
return NMBS_ERROR_INVALID_ARGUMENT;
|
return NMBS_ERROR_INVALID_ARGUMENT;
|
||||||
@ -984,18 +1023,24 @@ static nmbs_error read_registers(nmbs_t* nmbs, uint8_t fc, uint16_t address, uin
|
|||||||
|
|
||||||
return NMBS_ERROR_NONE;
|
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) {
|
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);
|
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) {
|
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);
|
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) {
|
nmbs_error nmbs_write_single_coil(nmbs_t* nmbs, uint16_t address, bool value) {
|
||||||
msg_state_req(nmbs, 5);
|
msg_state_req(nmbs, 5);
|
||||||
send_req_header(nmbs, 4);
|
send_req_header(nmbs, 4);
|
||||||
@ -1038,8 +1083,10 @@ nmbs_error nmbs_write_single_coil(nmbs_t* nmbs, uint16_t address, bool value) {
|
|||||||
|
|
||||||
return NMBS_ERROR_NONE;
|
return NMBS_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NMBS_CLIENT_DISABLED
|
||||||
nmbs_error nmbs_write_single_register(nmbs_t* nmbs, uint16_t address, uint16_t value) {
|
nmbs_error nmbs_write_single_register(nmbs_t* nmbs, uint16_t address, uint16_t value) {
|
||||||
msg_state_req(nmbs, 6);
|
msg_state_req(nmbs, 6);
|
||||||
send_req_header(nmbs, 4);
|
send_req_header(nmbs, 4);
|
||||||
@ -1079,8 +1126,10 @@ nmbs_error nmbs_write_single_register(nmbs_t* nmbs, uint16_t address, uint16_t v
|
|||||||
|
|
||||||
return NMBS_ERROR_NONE;
|
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) {
|
nmbs_error nmbs_write_multiple_coils(nmbs_t* nmbs, uint16_t address, uint16_t quantity, const nmbs_bitfield coils) {
|
||||||
if (quantity < 1 || quantity > 0x07B0)
|
if (quantity < 1 || quantity > 0x07B0)
|
||||||
return NMBS_ERROR_INVALID_ARGUMENT;
|
return NMBS_ERROR_INVALID_ARGUMENT;
|
||||||
@ -1134,8 +1183,10 @@ nmbs_error nmbs_write_multiple_coils(nmbs_t* nmbs, uint16_t address, uint16_t qu
|
|||||||
|
|
||||||
return NMBS_ERROR_NONE;
|
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) {
|
nmbs_error nmbs_write_multiple_registers(nmbs_t* nmbs, uint16_t address, uint16_t quantity, const uint16_t* registers) {
|
||||||
if (quantity < 1 || quantity > 0x007B)
|
if (quantity < 1 || quantity > 0x007B)
|
||||||
return NMBS_ERROR_INVALID_ARGUMENT;
|
return NMBS_ERROR_INVALID_ARGUMENT;
|
||||||
@ -1189,6 +1240,7 @@ nmbs_error nmbs_write_multiple_registers(nmbs_t* nmbs, uint16_t address, uint16_
|
|||||||
|
|
||||||
return NMBS_ERROR_NONE;
|
return NMBS_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
nmbs_error nmbs_send_raw_pdu(nmbs_t* nmbs, uint8_t fc, const void* data, uint32_t data_len) {
|
nmbs_error nmbs_send_raw_pdu(nmbs_t* nmbs, uint8_t fc, const void* data, uint32_t data_len) {
|
||||||
|
|||||||
29
nanomodbus.h
29
nanomodbus.h
@ -167,7 +167,7 @@ typedef struct nmbs_t {
|
|||||||
*/
|
*/
|
||||||
static const uint8_t NMBS_BROADCAST_ADDRESS = 0;
|
static const uint8_t NMBS_BROADCAST_ADDRESS = 0;
|
||||||
|
|
||||||
|
#ifndef NMBS_CLIENT_DISABLED
|
||||||
/** Create a new Modbus client.
|
/** Create a new Modbus client.
|
||||||
* @param nmbs pointer to the nmbs_t instance where the client will be created.
|
* @param nmbs pointer to the nmbs_t instance where the client will be created.
|
||||||
* @param platform_conf nmbs_platform_conf struct with platform configuration.
|
* @param platform_conf nmbs_platform_conf struct with platform configuration.
|
||||||
@ -175,7 +175,9 @@ static const uint8_t NMBS_BROADCAST_ADDRESS = 0;
|
|||||||
* @return NMBS_ERROR_NONE if successful, NMBS_ERROR_INVALID_ARGUMENT otherwise.
|
* @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);
|
nmbs_error nmbs_client_create(nmbs_t* nmbs, const nmbs_platform_conf* platform_conf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
/** Create a new Modbus server.
|
/** Create a new Modbus server.
|
||||||
* @param nmbs pointer to the nmbs_t instance where the client will be created.
|
* @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 address_rtu RTU address of this server. Can be 0 if transport is not RTU.
|
||||||
@ -186,6 +188,7 @@ nmbs_error nmbs_client_create(nmbs_t* nmbs, const nmbs_platform_conf* platform_c
|
|||||||
*/
|
*/
|
||||||
nmbs_error nmbs_server_create(nmbs_t* nmbs, uint8_t address_rtu, const nmbs_platform_conf* platform_conf,
|
nmbs_error nmbs_server_create(nmbs_t* nmbs, uint8_t address_rtu, const nmbs_platform_conf* platform_conf,
|
||||||
const nmbs_callbacks* callbacks);
|
const nmbs_callbacks* callbacks);
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Set the request/response timeout.
|
/** 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 server, sets the timeout of the nmbs_server_poll() function.
|
||||||
@ -213,12 +216,15 @@ void nmbs_set_byte_spacing(nmbs_t* nmbs, uint32_t spacing_ms);
|
|||||||
*/
|
*/
|
||||||
void nmbs_set_platform_arg(nmbs_t* nmbs, void* arg);
|
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.
|
/** Set the recipient server address of the next request on RTU transport.
|
||||||
* @param nmbs pointer to the nmbs_t instance
|
* @param nmbs pointer to the nmbs_t instance
|
||||||
* @param address server address
|
* @param address server address
|
||||||
*/
|
*/
|
||||||
void nmbs_set_destination_rtu_address(nmbs_t* nmbs, uint8_t address);
|
void nmbs_set_destination_rtu_address(nmbs_t* nmbs, uint8_t address);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
/** Handle incoming requests to the server.
|
/** 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
|
* 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).
|
* received request, is the value set with nmbs_set_read_timeout() (unless set to < 0).
|
||||||
@ -227,7 +233,9 @@ void nmbs_set_destination_rtu_address(nmbs_t* nmbs, uint8_t address);
|
|||||||
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
||||||
*/
|
*/
|
||||||
nmbs_error nmbs_server_poll(nmbs_t* nmbs);
|
nmbs_error nmbs_server_poll(nmbs_t* nmbs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NMBS_CLIENT_DISABLED
|
||||||
/** Send a FC 01 (0x01) Read Coils request
|
/** Send a FC 01 (0x01) Read Coils request
|
||||||
* @param nmbs pointer to the nmbs_t instance
|
* @param nmbs pointer to the nmbs_t instance
|
||||||
* @param address starting address
|
* @param address starting address
|
||||||
@ -237,7 +245,9 @@ nmbs_error nmbs_server_poll(nmbs_t* nmbs);
|
|||||||
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
* @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);
|
nmbs_error nmbs_read_coils(nmbs_t* nmbs, uint16_t address, uint16_t quantity, nmbs_bitfield coils_out);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NMBS_CLIENT_DISABLED
|
||||||
/** Send a FC 02 (0x02) Read Discrete Inputs request
|
/** Send a FC 02 (0x02) Read Discrete Inputs request
|
||||||
* @param nmbs pointer to the nmbs_t instance
|
* @param nmbs pointer to the nmbs_t instance
|
||||||
* @param address starting address
|
* @param address starting address
|
||||||
@ -247,7 +257,9 @@ nmbs_error nmbs_read_coils(nmbs_t* nmbs, uint16_t address, uint16_t quantity, nm
|
|||||||
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
* @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);
|
nmbs_error nmbs_read_discrete_inputs(nmbs_t* nmbs, uint16_t address, uint16_t quantity, nmbs_bitfield inputs_out);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NMBS_CLIENT_DISABLED
|
||||||
/** Send a FC 03 (0x03) Read Holding Registers request
|
/** Send a FC 03 (0x03) Read Holding Registers request
|
||||||
* @param nmbs pointer to the nmbs_t instance
|
* @param nmbs pointer to the nmbs_t instance
|
||||||
* @param address starting address
|
* @param address starting address
|
||||||
@ -257,7 +269,9 @@ nmbs_error nmbs_read_discrete_inputs(nmbs_t* nmbs, uint16_t address, uint16_t qu
|
|||||||
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
* @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);
|
nmbs_error nmbs_read_holding_registers(nmbs_t* nmbs, uint16_t address, uint16_t quantity, uint16_t* registers_out);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NMBS_CLIENT_DISABLED
|
||||||
/** Send a FC 04 (0x04) Read Input Registers request
|
/** Send a FC 04 (0x04) Read Input Registers request
|
||||||
* @param nmbs pointer to the nmbs_t instance
|
* @param nmbs pointer to the nmbs_t instance
|
||||||
* @param address starting address
|
* @param address starting address
|
||||||
@ -267,7 +281,9 @@ nmbs_error nmbs_read_holding_registers(nmbs_t* nmbs, uint16_t address, uint16_t
|
|||||||
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
* @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);
|
nmbs_error nmbs_read_input_registers(nmbs_t* nmbs, uint16_t address, uint16_t quantity, uint16_t* registers_out);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NMBS_CLIENT_DISABLED
|
||||||
/** Send a FC 05 (0x05) Write Single Coil request
|
/** Send a FC 05 (0x05) Write Single Coil request
|
||||||
* @param nmbs pointer to the nmbs_t instance
|
* @param nmbs pointer to the nmbs_t instance
|
||||||
* @param address coil address
|
* @param address coil address
|
||||||
@ -276,7 +292,9 @@ nmbs_error nmbs_read_input_registers(nmbs_t* nmbs, uint16_t address, uint16_t qu
|
|||||||
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
||||||
*/
|
*/
|
||||||
nmbs_error nmbs_write_single_coil(nmbs_t* nmbs, uint16_t address, bool value);
|
nmbs_error nmbs_write_single_coil(nmbs_t* nmbs, uint16_t address, bool value);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NMBS_CLIENT_DISABLED
|
||||||
/** Send a FC 06 (0x06) Write Single Register request
|
/** Send a FC 06 (0x06) Write Single Register request
|
||||||
* @param nmbs pointer to the nmbs_t instance
|
* @param nmbs pointer to the nmbs_t instance
|
||||||
* @param address register address
|
* @param address register address
|
||||||
@ -285,7 +303,9 @@ nmbs_error nmbs_write_single_coil(nmbs_t* nmbs, uint16_t address, bool value);
|
|||||||
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
||||||
*/
|
*/
|
||||||
nmbs_error nmbs_write_single_register(nmbs_t* nmbs, uint16_t address, uint16_t value);
|
nmbs_error nmbs_write_single_register(nmbs_t* nmbs, uint16_t address, uint16_t value);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NMBS_CLIENT_DISABLED
|
||||||
/** Send a FC 15 (0x0F) Write Multiple Coils
|
/** Send a FC 15 (0x0F) Write Multiple Coils
|
||||||
* @param nmbs pointer to the nmbs_t instance
|
* @param nmbs pointer to the nmbs_t instance
|
||||||
* @param address starting address
|
* @param address starting address
|
||||||
@ -295,7 +315,9 @@ nmbs_error nmbs_write_single_register(nmbs_t* nmbs, uint16_t address, uint16_t v
|
|||||||
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
* @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);
|
nmbs_error nmbs_write_multiple_coils(nmbs_t* nmbs, uint16_t address, uint16_t quantity, const nmbs_bitfield coils);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NMBS_CLIENT_DISABLED
|
||||||
/** Send a FC 16 (0x10) Write Multiple Registers
|
/** Send a FC 16 (0x10) Write Multiple Registers
|
||||||
* @param nmbs pointer to the nmbs_t instance
|
* @param nmbs pointer to the nmbs_t instance
|
||||||
* @param address starting address
|
* @param address starting address
|
||||||
@ -305,7 +327,9 @@ nmbs_error nmbs_write_multiple_coils(nmbs_t* nmbs, uint16_t address, uint16_t qu
|
|||||||
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
* @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);
|
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.
|
/** Send a raw Modbus PDU.
|
||||||
* CRC on RTU will be calculated and sent by this function.
|
* CRC on RTU will be calculated and sent by this function.
|
||||||
* @param nmbs pointer to the nmbs_t instance
|
* @param nmbs pointer to the nmbs_t instance
|
||||||
@ -316,7 +340,9 @@ nmbs_error nmbs_write_multiple_registers(nmbs_t* nmbs, uint16_t address, uint16_
|
|||||||
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
||||||
*/
|
*/
|
||||||
nmbs_error nmbs_send_raw_pdu(nmbs_t* nmbs, uint8_t fc, const void* data, uint32_t data_len);
|
nmbs_error nmbs_send_raw_pdu(nmbs_t* nmbs, uint8_t fc, const void* data, uint32_t data_len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NMBS_CLIENT_DISABLED
|
||||||
/** Receive a raw response Modbus PDU.
|
/** Receive a raw response Modbus PDU.
|
||||||
* @param nmbs pointer to the nmbs_t instance
|
* @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.
|
* @param data_out response data. It's up to the caller to convert this data to host byte order.
|
||||||
@ -325,6 +351,7 @@ nmbs_error nmbs_send_raw_pdu(nmbs_t* nmbs, uint8_t fc, const void* data, uint32_
|
|||||||
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
||||||
*/
|
*/
|
||||||
nmbs_error nmbs_receive_raw_pdu_response(nmbs_t* nmbs, void* data_out, uint32_t data_out_len);
|
nmbs_error nmbs_receive_raw_pdu_response(nmbs_t* nmbs, void* data_out, uint32_t data_out_len);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NMBS_STRERROR_DISABLED
|
#ifndef NMBS_STRERROR_DISABLED
|
||||||
/** Convert a nmbs_error to string
|
/** Convert a nmbs_error to string
|
||||||
|
|||||||
46
tests/client_disabled.c
Normal file
46
tests/client_disabled.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#define NMBS_CLIENT_DISABLED
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "nanomodbus.h"
|
||||||
|
|
||||||
|
#define UNUSED_PARAM(x) ((x) = (x))
|
||||||
|
|
||||||
|
|
||||||
|
int read_byte_empty(uint8_t* b, int32_t timeout, void* arg) {
|
||||||
|
UNUSED_PARAM(b);
|
||||||
|
UNUSED_PARAM(timeout);
|
||||||
|
UNUSED_PARAM(arg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int write_byte_empty(uint8_t b, int32_t timeout, void* arg) {
|
||||||
|
UNUSED_PARAM(b);
|
||||||
|
UNUSED_PARAM(timeout);
|
||||||
|
UNUSED_PARAM(arg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void platform_sleep(uint32_t milliseconds, void* arg) {
|
||||||
|
UNUSED_PARAM(arg);
|
||||||
|
usleep(milliseconds * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
nmbs_t nmbs;
|
||||||
|
|
||||||
|
nmbs_platform_conf platform_conf_empty = {.transport = NMBS_TRANSPORT_TCP,
|
||||||
|
.read_byte = read_byte_empty,
|
||||||
|
.write_byte = write_byte_empty,
|
||||||
|
.sleep = platform_sleep};
|
||||||
|
|
||||||
|
nmbs_callbacks callbacks_empty;
|
||||||
|
|
||||||
|
nmbs_error err = nmbs_server_create(&nmbs, 1, &platform_conf_empty, &callbacks_empty);
|
||||||
|
if(err != 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
44
tests/server_disabled.c
Normal file
44
tests/server_disabled.c
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#define NMBS_SERVER_DISABLED
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "nanomodbus.h"
|
||||||
|
|
||||||
|
#define UNUSED_PARAM(x) ((x) = (x))
|
||||||
|
|
||||||
|
|
||||||
|
int read_byte_empty(uint8_t* b, int32_t timeout, void* arg) {
|
||||||
|
UNUSED_PARAM(b);
|
||||||
|
UNUSED_PARAM(timeout);
|
||||||
|
UNUSED_PARAM(arg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int write_byte_empty(uint8_t b, int32_t timeout, void* arg) {
|
||||||
|
UNUSED_PARAM(b);
|
||||||
|
UNUSED_PARAM(timeout);
|
||||||
|
UNUSED_PARAM(arg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void platform_sleep(uint32_t milliseconds, void* arg) {
|
||||||
|
UNUSED_PARAM(arg);
|
||||||
|
usleep(milliseconds * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
nmbs_t nmbs;
|
||||||
|
|
||||||
|
nmbs_platform_conf platform_conf_empty = {.transport = NMBS_TRANSPORT_TCP,
|
||||||
|
.read_byte = read_byte_empty,
|
||||||
|
.write_byte = write_byte_empty,
|
||||||
|
.sleep = platform_sleep};
|
||||||
|
|
||||||
|
nmbs_error err = nmbs_client_create(&nmbs, &platform_conf_empty);
|
||||||
|
if(err != 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user