polarimeter_software/User/app/mb_hmi/hmi_server.c

156 lines
4.6 KiB
C
Raw Normal View History

2025-09-30 02:37:23 +00:00
#include "hmi_server.h"
#include "et_log.h"
#include "etk_utils.h"
#include "mb_command.h"
#include "mb_interface.h"
nmbs_t nmbs;
static rt_uint8_t mb_hmi_stack[HMI_THREAD_STACK_SIZE];
struct rt_thread mb_hmi_thread;
static nmbs_error server_read_input_registers(uint16_t address, uint16_t quantity, uint16_t *registers_out,
uint8_t unit_id, void *arg);
static nmbs_error server_read_holding_registers(uint16_t address, uint16_t quantity, uint16_t *registers_out,
uint8_t unit_id, void *arg);
static nmbs_error server_write_single_register(uint16_t address, uint16_t value, uint8_t unit_id, void *arg);
static nmbs_error server_write_multiple_registers(uint16_t address, uint16_t quantity, const uint16_t *registers,
uint8_t unit_id, void *arg);
static nmbs_error nmbs_server_init(nmbs_t *nmbs)
{
nmbs_platform_conf conf;
nmbs_callbacks cb;
nmbs_platform_conf_create(&conf);
conf.transport = NMBS_TRANSPORT_RTU;
conf.read = pm_hmi_uart_read;
conf.write = pm_hmi_uart_write;
nmbs_callbacks_create(&cb);
cb.read_coils = NULL;
cb.read_holding_registers = server_read_holding_registers;
cb.write_single_coil = NULL;
cb.write_multiple_coils = NULL;
cb.write_single_register = server_write_single_register;
cb.write_multiple_registers = server_write_multiple_registers;
cb.read_input_registers = server_read_input_registers;
nmbs_error status = nmbs_server_create(nmbs, MB_SLAVE_ID, &conf, &cb);
if (status != NMBS_ERROR_NONE)
{
return status;
}
nmbs_set_byte_timeout(nmbs, 100);
nmbs_set_read_timeout(nmbs, 1000);
return NMBS_ERROR_NONE;
}
static nmbs_error server_read_input_registers(uint16_t address, uint16_t quantity, uint16_t *registers_out,
uint8_t unit_id, void *arg)
{
ETK_UNUSED(unit_id);
ETK_UNUSED(arg);
return mb_handle_read_input_registers(address, quantity, registers_out);
}
static nmbs_error server_read_holding_registers(uint16_t address, uint16_t quantity, uint16_t *registers_out,
uint8_t unit_id, void *arg)
{
ETK_UNUSED(unit_id);
ETK_UNUSED(arg);
// 直接从底层寄存器区读取
if (address + quantity > REG_BUF_SIZE)
{
ET_ERR("Read holding registers out of range: addr=%u, qty=%u", address, quantity);
return NMBS_ERROR_INVALID_REQUEST;
}
mb_command_t *cmd = get_command_instance();
if (cmd == RT_NULL)
{
ET_ERR("Failed to get command instance");
return NMBS_ERROR_INVALID_ARGUMENT;
}
mb_command_t *get_command_instance(void);
for (uint16_t i = 0; i < quantity; ++i)
{
registers_out[i] = cmd->regs[address + i];
ET_DBG("Read holding register[%u] = 0x%04X", address + i, registers_out[i]);
}
return NMBS_ERROR_NONE;
}
// function: 0x06 Write Single Register
static nmbs_error server_write_single_register(uint16_t address, uint16_t value, uint8_t unit_id, void *arg)
{
ETK_UNUSED(unit_id);
ETK_UNUSED(arg);
uint16_t reg = value;
return server_write_multiple_registers(address, 1, &reg, unit_id, arg);
}
static nmbs_error server_write_multiple_registers(uint16_t address, uint16_t quantity, const uint16_t *registers,
uint8_t unit_id, void *arg)
{
ETK_UNUSED(unit_id);
ETK_UNUSED(arg);
return mb_handle_write_holding_registers(address, quantity, registers);
}
static void mb_hmi_thread_entry(void *parameter)
{
RT_UNUSED(parameter);
while (1)
{
nmbs_server_poll(&nmbs);
rt_thread_mdelay(20);
}
}
int hmi_server_start(void)
{
rt_err_t result;
result = rt_thread_init(&mb_hmi_thread, "HMI", mb_hmi_thread_entry, RT_NULL, mb_hmi_stack, sizeof(mb_hmi_stack),
HMI_THREAD_PRIORITY, 50);
if (result == RT_EOK)
{
ET_INFO("servo thread init success.");
rt_thread_startup(&mb_hmi_thread);
}
else
{
ET_ERR("servo thread init failed.%d", result);
return -1;
}
return 0;
}
int hmi_server_handler_register(hmi_server_t *hmi, mb_cmd_handler_t *handler)
{
hmi->cmd.handler = handler;
return 0;
}
int hmi_server_init(hmi_server_t *hmi)
{
if (pm_mb_hmi_init() != 0)
{
ET_ERR("Failed to initialize Modbus HMI");
return -1;
}
mb_command_init(&hmi->cmd);
mb_interface_init();
nmbs_server_init(&nmbs);
return 0;
}