feat(gateway): Update SDK configuration and add 485 control bridge

- Changed flash size configuration from 16MB to 4MB and updated partition table filename.
- Introduced two gateway channels with UART configurations for communication.
- Added support for gateway cache and startup services including BLE and Wi-Fi.
- Enabled SPI RAM and configured its parameters for better memory management.
- Enhanced the gateway bridge service to handle generated Modbus points more efficiently.
- Refactored the gateway Modbus component to improve point management and added new methods for point description and generation.
- Implemented a new Gateway485ControlBridge for handling 485 control communication with UART.
- Added necessary files for the 485 control bridge including configuration and implementation.

Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
Tony
2026-05-06 00:39:58 +08:00
parent 34d2d9caa0
commit 029785ff1d
13 changed files with 925 additions and 181 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
idf_component_register(
SRCS "app_main.cpp"
REQUIRES gateway_core gateway_controller gateway_network gateway_bridge gateway_cache dali_domain gateway_runtime gateway_ble gateway_usb_setup log
REQUIRES gateway_core gateway_controller gateway_network gateway_bridge gateway_cache dali_domain gateway_runtime gateway_ble gateway_usb_setup gateway_485_control log
)
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17)
+66
View File
@@ -579,6 +579,72 @@ config GATEWAY_USB_SETUP_READ_TIMEOUT_MS
range 1 1000
default 20
config GATEWAY_485_CONTROL_ENABLED
bool "Enable UART0 Lua control bridge"
default n
help
Claims UART0 for the Lua-compatible framed gateway control channel at boot.
This requires moving the ESP-IDF console away from UART0 and prevents Modbus
serial from using UART0 at runtime.
config GATEWAY_485_CONTROL_BAUDRATE
int "UART0 control baudrate"
depends on GATEWAY_485_CONTROL_ENABLED
range 1200 921600
default 9600
config GATEWAY_485_CONTROL_TX_PIN
int "UART0 control TX pin"
depends on GATEWAY_485_CONTROL_ENABLED
range -1 48
default -1
help
Leave at -1 to keep the current UART0 TX routing.
config GATEWAY_485_CONTROL_RX_PIN
int "UART0 control RX pin"
depends on GATEWAY_485_CONTROL_ENABLED
range -1 48
default -1
help
Leave at -1 to keep the current UART0 RX routing.
config GATEWAY_485_CONTROL_RX_BUFFER
int "UART0 control RX buffer bytes"
depends on GATEWAY_485_CONTROL_ENABLED
range 64 4096
default 256
config GATEWAY_485_CONTROL_TX_BUFFER
int "UART0 control TX buffer bytes"
depends on GATEWAY_485_CONTROL_ENABLED
range 64 4096
default 256
config GATEWAY_485_CONTROL_READ_TIMEOUT_MS
int "UART0 control read timeout ms"
depends on GATEWAY_485_CONTROL_ENABLED
range 1 1000
default 20
config GATEWAY_485_CONTROL_WRITE_TIMEOUT_MS
int "UART0 control write timeout ms"
depends on GATEWAY_485_CONTROL_ENABLED
range 1 1000
default 20
config GATEWAY_485_CONTROL_TASK_STACK_SIZE
int "UART0 control task stack bytes"
depends on GATEWAY_485_CONTROL_ENABLED
range 2048 16384
default 4096
config GATEWAY_485_CONTROL_TASK_PRIORITY
int "UART0 control task priority"
depends on GATEWAY_485_CONTROL_ENABLED
range 1 10
default 4
endmenu
menu "Gateway Network Services"
+96 -15
View File
@@ -6,6 +6,7 @@
#include "gateway_core.hpp"
#include "gateway_network.hpp"
#include "gateway_runtime.hpp"
#include "gateway_485_control.hpp"
#include "gateway_usb_setup.hpp"
#include "esp_log.h"
@@ -55,6 +56,42 @@
#define CONFIG_GATEWAY_USB_SETUP_READ_TIMEOUT_MS 20
#endif
#ifndef CONFIG_GATEWAY_485_CONTROL_BAUDRATE
#define CONFIG_GATEWAY_485_CONTROL_BAUDRATE 9600
#endif
#ifndef CONFIG_GATEWAY_485_CONTROL_TX_PIN
#define CONFIG_GATEWAY_485_CONTROL_TX_PIN -1
#endif
#ifndef CONFIG_GATEWAY_485_CONTROL_RX_PIN
#define CONFIG_GATEWAY_485_CONTROL_RX_PIN -1
#endif
#ifndef CONFIG_GATEWAY_485_CONTROL_RX_BUFFER
#define CONFIG_GATEWAY_485_CONTROL_RX_BUFFER 256
#endif
#ifndef CONFIG_GATEWAY_485_CONTROL_TX_BUFFER
#define CONFIG_GATEWAY_485_CONTROL_TX_BUFFER 256
#endif
#ifndef CONFIG_GATEWAY_485_CONTROL_READ_TIMEOUT_MS
#define CONFIG_GATEWAY_485_CONTROL_READ_TIMEOUT_MS 20
#endif
#ifndef CONFIG_GATEWAY_485_CONTROL_WRITE_TIMEOUT_MS
#define CONFIG_GATEWAY_485_CONTROL_WRITE_TIMEOUT_MS 20
#endif
#ifndef CONFIG_GATEWAY_485_CONTROL_TASK_STACK_SIZE
#define CONFIG_GATEWAY_485_CONTROL_TASK_STACK_SIZE 4096
#endif
#ifndef CONFIG_GATEWAY_485_CONTROL_TASK_PRIORITY
#define CONFIG_GATEWAY_485_CONTROL_TASK_PRIORITY 4
#endif
#ifndef CONFIG_GATEWAY_SMARTCONFIG_TIMEOUT_SEC
#define CONFIG_GATEWAY_SMARTCONFIG_TIMEOUT_SEC 60
#endif
@@ -257,6 +294,20 @@ constexpr bool kModbusAllowUart0 = true;
constexpr bool kModbusAllowUart0 = false;
#endif
#ifdef CONFIG_GATEWAY_485_CONTROL_ENABLED
constexpr bool k485ControlEnabled = true;
#else
constexpr bool k485ControlEnabled = false;
#endif
#if defined(CONFIG_ESP_CONSOLE_UART) && defined(CONFIG_ESP_CONSOLE_UART_NUM) && CONFIG_ESP_CONSOLE_UART_NUM == 0
constexpr bool kConsoleOnUart0 = true;
#elif defined(CONFIG_CONSOLE_UART) && defined(CONFIG_CONSOLE_UART_NUM) && CONFIG_CONSOLE_UART_NUM == 0
constexpr bool kConsoleOnUart0 = true;
#else
constexpr bool kConsoleOnUart0 = false;
#endif
#ifdef CONFIG_GATEWAY_MODBUS_SERIAL_RS485_ENABLED
constexpr bool kModbusSerialRs485Enabled = true;
#else
@@ -270,6 +321,7 @@ std::unique_ptr<gateway::GatewayController> s_controller;
std::unique_ptr<gateway::GatewayBridgeService> s_bridge;
std::unique_ptr<gateway::GatewayNetworkService> s_network;
std::unique_ptr<gateway::GatewayBleBridge> s_ble_bridge;
std::unique_ptr<gateway::Gateway485ControlBridge> s_uart0_control_bridge;
std::unique_ptr<gateway::GatewayUsbSetupBridge> s_usb_setup_bridge;
[[maybe_unused]] void LogBindError(const char* channel_name, esp_err_t err) {
@@ -289,6 +341,11 @@ struct ChannelBindingConfig {
};
bool ValidateChannelBindings() {
if (k485ControlEnabled && kConsoleOnUart0) {
ESP_LOGE(kTag, "485 control bridge requires moving the ESP-IDF console off UART0");
return false;
}
ChannelBindingConfig channels[CONFIG_GATEWAY_CHANNEL_COUNT] = {};
#if CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE
@@ -375,6 +432,10 @@ bool ValidateChannelBindings() {
if (kModbusBridgeSupported && kModbusDefaultSerialTransport) {
const int modbus_uart = CONFIG_GATEWAY_MODBUS_SERIAL_UART_PORT;
if (k485ControlEnabled && modbus_uart == 0) {
ESP_LOGE(kTag, "Modbus serial UART0 conflicts with the UART0 control bridge");
return false;
}
if (modbus_uart == 0 && !kModbusAllowUart0) {
ESP_LOGE(kTag, "Modbus serial is configured on UART0, but UART0 is reserved for console");
return false;
@@ -429,10 +490,10 @@ esp_err_t BindConfiguredChannels(gateway::DaliDomainService& dali_domain,
channel1.query_timeout_ms =
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL1_SERIAL_QUERY_TIMEOUT_MS);
channel1.name = runtime.gatewayName(channel1.gateway_id);
esp_err_t err = dali_domain.bindSerialBus(channel1);
LogBindError("channel1 serial DALI", err);
if (err != ESP_OK) {
return err;
esp_err_t err1 = dali_domain.bindSerialBus(channel1);
LogBindError("channel1 serial DALI", err1);
if (err1 != ESP_OK) {
return err1;
}
#endif
@@ -446,10 +507,10 @@ esp_err_t BindConfiguredChannels(gateway::DaliDomainService& dali_domain,
channel2.rx_pin = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_RX_PIN);
channel2.baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_BAUDRATE);
channel2.name = runtime.gatewayName(channel2.gateway_id);
esp_err_t err = dali_domain.bindHardwareBus(channel2);
LogBindError("channel2 native DALI", err);
if (err != ESP_OK) {
return err;
esp_err_t err2 = dali_domain.bindHardwareBus(channel2);
LogBindError("channel2 native DALI", err2);
if (err2 != ESP_OK) {
return err2;
}
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART1 || CONFIG_GATEWAY_CHANNEL2_PHY_UART2
gateway::DaliSerialBusConfig channel2{};
@@ -468,10 +529,10 @@ esp_err_t BindConfiguredChannels(gateway::DaliDomainService& dali_domain,
channel2.query_timeout_ms =
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL2_SERIAL_QUERY_TIMEOUT_MS);
channel2.name = runtime.gatewayName(channel2.gateway_id);
esp_err_t err = dali_domain.bindSerialBus(channel2);
LogBindError("channel2 serial DALI", err);
if (err != ESP_OK) {
return err;
esp_err_t err2 = dali_domain.bindSerialBus(channel2);
LogBindError("channel2 serial DALI", err2);
if (err2 != ESP_OK) {
return err2;
}
#endif
#endif
@@ -535,7 +596,27 @@ extern "C" void app_main(void) {
s_controller = std::make_unique<gateway::GatewayController>(*s_runtime, *s_dali_domain,
*s_cache,
controller_config);
ESP_ERROR_CHECK(s_controller->start());
if (k485ControlEnabled) {
gateway::Gateway485ControlBridgeConfig gateway485_config;
gateway485_config.enabled = true;
gateway485_config.tx_pin = CONFIG_GATEWAY_485_CONTROL_TX_PIN;
gateway485_config.rx_pin = CONFIG_GATEWAY_485_CONTROL_RX_PIN;
gateway485_config.baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_485_CONTROL_BAUDRATE);
gateway485_config.rx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_485_CONTROL_RX_BUFFER);
gateway485_config.tx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_485_CONTROL_TX_BUFFER);
gateway485_config.read_timeout_ms =
static_cast<uint32_t>(CONFIG_GATEWAY_485_CONTROL_READ_TIMEOUT_MS);
gateway485_config.write_timeout_ms =
static_cast<uint32_t>(CONFIG_GATEWAY_485_CONTROL_WRITE_TIMEOUT_MS);
gateway485_config.task_stack_size =
static_cast<uint32_t>(CONFIG_GATEWAY_485_CONTROL_TASK_STACK_SIZE);
gateway485_config.task_priority =
static_cast<UBaseType_t>(CONFIG_GATEWAY_485_CONTROL_TASK_PRIORITY);
s_uart0_control_bridge = std::make_unique<gateway::Gateway485ControlBridge>(*s_controller,
gateway485_config);
ESP_ERROR_CHECK(s_uart0_control_bridge->start());
}
ESP_ERROR_CHECK(s_controller->start());
if (kBridgeSupported) {
gateway::GatewayBridgeServiceConfig bridge_config;
@@ -552,8 +633,8 @@ extern "C" void app_main(void) {
static_cast<uint32_t>(CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE);
bridge_config.modbus_task_priority =
static_cast<UBaseType_t>(CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_PRIORITY);
bridge_config.allow_modbus_uart0 = kModbusAllowUart0;
if (!kModbusAllowUart0) {
bridge_config.allow_modbus_uart0 = kModbusAllowUart0 && !k485ControlEnabled;
if (!bridge_config.allow_modbus_uart0) {
bridge_config.reserved_uart_ports.push_back(0);
}
#if CONFIG_GATEWAY_CHANNEL1_PHY_UART1