Fixes to REGS_ADDR_MAX in server examples

This commit is contained in:
Valerio De Benedetto 2024-11-25 13:23:47 +01:00
parent 96126e5732
commit b8d247f329
2 changed files with 79 additions and 75 deletions

View File

@ -19,125 +19,129 @@
// A single nmbs_bitfield variable can keep 2000 coils // A single nmbs_bitfield variable can keep 2000 coils
nmbs_bitfield server_coils = {0}; nmbs_bitfield server_coils = {0};
uint16_t server_registers[REGS_ADDR_MAX] = {0}; uint16_t server_registers[REGS_ADDR_MAX + 1] = {0};
int32_t read_serial(uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg) { int32_t read_serial(uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg) {
Serial.setTimeout(byte_timeout_ms); Serial.setTimeout(byte_timeout_ms);
return Serial.readBytes(buf, count); return Serial.readBytes(buf, count);
} }
int32_t write_serial(const uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg) { int32_t write_serial(const uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg) {
Serial.setTimeout(byte_timeout_ms); Serial.setTimeout(byte_timeout_ms);
return Serial.write(buf, count); return Serial.write(buf, count);
} }
void onError() { void onError() {
// Set the led ON on error // Set the led ON on error
while (true) { while (true) {
digitalWrite(LED_BUILTIN, HIGH); digitalWrite(LED_BUILTIN, HIGH);
} }
} }
nmbs_error handle_read_coils(uint16_t address, uint16_t quantity, nmbs_bitfield coils_out, uint8_t unit_id, void *arg) { nmbs_error handle_read_coils(uint16_t address, uint16_t quantity, nmbs_bitfield coils_out, uint8_t unit_id, void* arg) {
if (address + quantity > COILS_ADDR_MAX + 1) if (address + quantity > COILS_ADDR_MAX + 1)
return NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS; return NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
// Read our coils values into coils_out // Read our coils values into coils_out
for (int i = 0; i < quantity; i++) { for (int i = 0; i < quantity; i++) {
bool value = nmbs_bitfield_read(server_coils, address + i); bool value = nmbs_bitfield_read(server_coils, address + i);
nmbs_bitfield_write(coils_out, i, value); nmbs_bitfield_write(coils_out, i, value);
} }
return NMBS_ERROR_NONE; return NMBS_ERROR_NONE;
} }
nmbs_error handle_write_multiple_coils(uint16_t address, uint16_t quantity, const nmbs_bitfield coils, uint8_t unit_id, void *arg) { nmbs_error handle_write_multiple_coils(uint16_t address, uint16_t quantity, const nmbs_bitfield coils, uint8_t unit_id,
if (address + quantity > COILS_ADDR_MAX + 1) void* arg) {
return NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS; if (address + quantity > COILS_ADDR_MAX + 1)
return NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
// Write coils values to our server_coils // Write coils values to our server_coils
for (int i = 0; i < quantity; i++) { for (int i = 0; i < quantity; i++) {
nmbs_bitfield_write(server_coils, address + i, nmbs_bitfield_read(coils, i)); nmbs_bitfield_write(server_coils, address + i, nmbs_bitfield_read(coils, i));
} }
return NMBS_ERROR_NONE; return NMBS_ERROR_NONE;
} }
nmbs_error handler_read_holding_registers(uint16_t address, uint16_t quantity, uint16_t* registers_out, uint8_t unit_id, void *arg) { nmbs_error handler_read_holding_registers(uint16_t address, uint16_t quantity, uint16_t* registers_out, uint8_t unit_id,
if (address + quantity > REGS_ADDR_MAX + 1) void* arg) {
return NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS; if (address + quantity > REGS_ADDR_MAX + 1)
return NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
// Read our registers values into registers_out // Read our registers values into registers_out
for (int i = 0; i < quantity; i++) for (int i = 0; i < quantity; i++)
registers_out[i] = server_registers[address + i]; registers_out[i] = server_registers[address + i];
return NMBS_ERROR_NONE; return NMBS_ERROR_NONE;
} }
nmbs_error handle_write_multiple_registers(uint16_t address, uint16_t quantity, const uint16_t* registers, uint8_t unit_id, void *arg) { nmbs_error handle_write_multiple_registers(uint16_t address, uint16_t quantity, const uint16_t* registers,
if (address + quantity > REGS_ADDR_MAX + 1) uint8_t unit_id, void* arg) {
return NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS; if (address + quantity > REGS_ADDR_MAX + 1)
return NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
// Write registers values to our server_registers // Write registers values to our server_registers
for (int i = 0; i < quantity; i++) for (int i = 0; i < quantity; i++)
server_registers[address + i] = registers[i]; server_registers[address + i] = registers[i];
return NMBS_ERROR_NONE; return NMBS_ERROR_NONE;
} }
void setup() { void setup() {
pinMode (LED_BUILTIN, OUTPUT); pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600); Serial.begin(9600);
while (!Serial); while (!Serial)
;
} }
void loop() { void loop() {
nmbs_platform_conf platform_conf; nmbs_platform_conf platform_conf;
nmbs_platform_conf_create(&platform_conf); nmbs_platform_conf_create(&platform_conf);
platform_conf.transport = NMBS_TRANSPORT_RTU; platform_conf.transport = NMBS_TRANSPORT_RTU;
platform_conf.read = read_serial; platform_conf.read = read_serial;
platform_conf.write = write_serial; platform_conf.write = write_serial;
platform_conf.arg = NULL; platform_conf.arg = NULL;
nmbs_callbacks callbacks; nmbs_callbacks callbacks;
nmbs_callbacks_create(&callbacks); nmbs_callbacks_create(&callbacks);
callbacks.read_coils = handle_read_coils; callbacks.read_coils = handle_read_coils;
callbacks.write_multiple_coils = handle_write_multiple_coils; callbacks.write_multiple_coils = handle_write_multiple_coils;
callbacks.read_holding_registers = handler_read_holding_registers; callbacks.read_holding_registers = handler_read_holding_registers;
callbacks.write_multiple_registers = handle_write_multiple_registers; callbacks.write_multiple_registers = handle_write_multiple_registers;
// Create the modbus server // Create the modbus server
nmbs_t nmbs; nmbs_t nmbs;
nmbs_error err = nmbs_server_create(&nmbs, RTU_SERVER_ADDRESS, &platform_conf, &callbacks); nmbs_error err = nmbs_server_create(&nmbs, RTU_SERVER_ADDRESS, &platform_conf, &callbacks);
if (err != NMBS_ERROR_NONE) { if (err != NMBS_ERROR_NONE) {
onError(); onError();
} }
nmbs_set_read_timeout(&nmbs, 1000); nmbs_set_read_timeout(&nmbs, 1000);
nmbs_set_byte_timeout(&nmbs, 100); nmbs_set_byte_timeout(&nmbs, 100);
bool led = false; bool led = false;
while (true) { while (true) {
err = nmbs_server_poll(&nmbs); err = nmbs_server_poll(&nmbs);
// This will probably never happen, since we don't return < 0 in our platform funcs // This will probably never happen, since we don't return < 0 in our platform funcs
if (err == NMBS_ERROR_TRANSPORT) if (err == NMBS_ERROR_TRANSPORT)
break; break;
digitalWrite(LED_BUILTIN, led); digitalWrite(LED_BUILTIN, led);
led = !led; led = !led;
} }
// No need to destroy the nmbs instance, terminate the program // No need to destroy the nmbs instance, terminate the program
exit(0); exit(0);
} }

View File

@ -21,7 +21,7 @@
// A single nmbs_bitfield variable can keep 2000 coils // A single nmbs_bitfield variable can keep 2000 coils
bool terminate = false; bool terminate = false;
nmbs_bitfield server_coils = {0}; nmbs_bitfield server_coils = {0};
uint16_t server_registers[REGS_ADDR_MAX] = {0}; uint16_t server_registers[REGS_ADDR_MAX + 1] = {0};
uint16_t server_file[FILE_SIZE_MAX]; uint16_t server_file[FILE_SIZE_MAX];