From 6f81e8454186b0ed983ee317398cbe62ab5960b7 Mon Sep 17 00:00:00 2001 From: Eduard Iten Date: Tue, 1 Jul 2025 13:41:22 +0200 Subject: [PATCH] feat(slave_node): Implement initial Modbus RTU server - Add a basic Modbus RTU server implementation based on Zephyr samples. - Configure usart1 for Modbus via a board overlay. - The server initializes and runs, but polling with mbpoll results in a timeout. - This commit captures a functional but non-working state for further debugging. --- .../slave_node/boards/bluepill_f103rb.overlay | 7 ++ software/apps/slave_node/prj.conf | 7 +- software/apps/slave_node/src/main.c | 107 +++++++++++++++++- 3 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 software/apps/slave_node/boards/bluepill_f103rb.overlay diff --git a/software/apps/slave_node/boards/bluepill_f103rb.overlay b/software/apps/slave_node/boards/bluepill_f103rb.overlay new file mode 100644 index 0000000..8908b7e --- /dev/null +++ b/software/apps/slave_node/boards/bluepill_f103rb.overlay @@ -0,0 +1,7 @@ +&usart1 { + modbus0 { + compatible = "zephyr,modbus-serial"; + status = "okay"; + }; + status = "okay"; +}; diff --git a/software/apps/slave_node/prj.conf b/software/apps/slave_node/prj.conf index a918445..8ba4116 100644 --- a/software/apps/slave_node/prj.conf +++ b/software/apps/slave_node/prj.conf @@ -1,6 +1,6 @@ # Enable Console and printk for logging CONFIG_CONSOLE=y -CONFIG_PRINTK=y +CONFIG_LOG=y # Disable UART console CONFIG_UART_CONSOLE=n @@ -8,3 +8,8 @@ CONFIG_UART_CONSOLE=n # Enable RTT console CONFIG_RTT_CONSOLE=y CONFIG_USE_SEGGER_RTT=y + +# Config modbus +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_MODBUS=y +CONFIG_MODBUS_ROLE_SERVER=y diff --git a/software/apps/slave_node/src/main.c b/software/apps/slave_node/src/main.c index e1ded0a..8af411d 100644 --- a/software/apps/slave_node/src/main.c +++ b/software/apps/slave_node/src/main.c @@ -1,16 +1,115 @@ /* - * Copyright (c) 2025 Eduard Iten + * Copyright (c) 2020 PHYTEC Messtechnik GmbH + * Copyright (c) 2022 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(mbs_sample, LOG_LEVEL_INF); + +static uint16_t holding_reg[8]; +static uint8_t coils_state; + +static int coil_rd(uint16_t addr, bool *state) +{ + *state = true; + + LOG_INF("Coil read, addr %u, %d", addr, (int)*state); + + return 0; +} + +static int coil_wr(uint16_t addr, bool state) +{ + bool on; + if (state == true) { + coils_state |= BIT(addr); + on = true; + } else { + coils_state &= ~BIT(addr); + on = false; + } + + LOG_INF("Coil write, addr %u, %d", addr, (int)state); + + return 0; +} + +static int holding_reg_rd(uint16_t addr, uint16_t *reg) +{ + if (addr >= ARRAY_SIZE(holding_reg)) { + return -ENOTSUP; + } + + *reg = 0xDEAD; + + LOG_INF("Holding register read, addr %u", addr); + + return 0; +} + +static int holding_reg_wr(uint16_t addr, uint16_t reg) +{ + if (addr >= ARRAY_SIZE(holding_reg)) { + return -ENOTSUP; + } + + holding_reg[addr] = reg; + + LOG_INF("Holding register write, addr %u", addr); + + return 0; +} + +static struct modbus_user_callbacks mbs_cbs = { + .coil_rd = coil_rd, + .coil_wr = coil_wr, + .holding_reg_rd = holding_reg_rd, + .holding_reg_wr = holding_reg_wr, +}; + +const static struct modbus_iface_param server_param = { + .mode = MODBUS_MODE_RTU, + .server = { + .user_cb = &mbs_cbs, + .unit_id = 1, + }, + .serial = { + .baud = 19200, + .parity = UART_CFG_PARITY_NONE, + }, +}; + +#define MODBUS_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_modbus_serial) + +static int init_modbus_server(void) +{ + const char iface_name[] = {DEVICE_DT_NAME(MODBUS_NODE)}; + int iface; + + iface = modbus_iface_get_by_name(iface_name); + + if (iface < 0) { + LOG_ERR("Failed to get iface index for %s", iface_name); + return iface; + } + + return modbus_init_server(iface, server_param); +} int main(void) { - while (1) { - printk("Hello from the updated Slave Node! Version 2.0\n"); - k_msleep(1000); + LOG_INF("Starting APP"); + if (init_modbus_server()) { + LOG_ERR("Modbus RTU server initialization failed"); } + LOG_INF("APP started"); return 0; }