整定一版
This commit is contained in:
319
port/menu_port.c
Normal file
319
port/menu_port.c
Normal file
@ -0,0 +1,319 @@
|
||||
/**
|
||||
**********************************************************************************************************************
|
||||
* @file menu_port.c
|
||||
* @brief 菜单组件硬件端口层实现
|
||||
* @author menu_component
|
||||
* @date 2025-12-19
|
||||
**********************************************************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ----------------------------------------------------------------------------------------------------------*/
|
||||
#include "menu_port.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* 全局变量 ---------------------------------------------------------------------------------------------------------*/
|
||||
static const MenuPortDriver* sg_menu_port_driver = NULL;
|
||||
|
||||
/* 默认硬件驱动实现 -------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief 默认打印函数
|
||||
* @param fmt 格式化字符串
|
||||
* @param args 可变参数列表
|
||||
*/
|
||||
static void menu_port_default_printf(const char* fmt, va_list args)
|
||||
{
|
||||
// 默认不实现打印功能
|
||||
(void)fmt;
|
||||
(void)args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 默认获取系统时间函数
|
||||
* @return 系统时间(ms)
|
||||
*/
|
||||
static uint32_t menu_port_default_get_tick(void)
|
||||
{
|
||||
// 默认返回0,用户需要根据实际硬件实现
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 默认延迟函数
|
||||
* @param ms 延迟时间(ms)
|
||||
*/
|
||||
static void menu_port_default_delay_ms(uint32_t ms)
|
||||
{
|
||||
// 默认实现简单的延迟
|
||||
for (uint32_t i = 0; i < ms * 1000; i++) {
|
||||
__asm__ volatile ("nop");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 默认显示函数
|
||||
* @param menu_name 菜单名称
|
||||
* @param menu_id 菜单ID
|
||||
*/
|
||||
static void menu_port_default_display(const char* menu_name, uint16_t menu_id)
|
||||
{
|
||||
// 默认不实现显示功能
|
||||
(void)menu_name;
|
||||
(void)menu_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 默认按键扫描函数
|
||||
* @return 按键事件类型
|
||||
*/
|
||||
static MenuEventType menu_port_default_key_scan(void)
|
||||
{
|
||||
// 默认返回无事件
|
||||
return MENU_EVENT_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 默认中断管理函数
|
||||
* @param enable 是否启用中断
|
||||
*/
|
||||
static void menu_port_default_irq_ctrl(bool enable)
|
||||
{
|
||||
// 默认不实现中断管理
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 默认错误处理函数
|
||||
* @param err_code 错误码
|
||||
*/
|
||||
static void menu_port_default_error_handler(MenuErrCode err_code)
|
||||
{
|
||||
// 默认不实现错误处理
|
||||
(void)err_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 默认Modbus发送函数
|
||||
* @param reg_type 寄存器类型
|
||||
* @param reg_addr 寄存器地址
|
||||
* @param reg_buf 寄存器数据
|
||||
* @param buf_len 数据长度
|
||||
* @return 错误码
|
||||
*/
|
||||
static MenuErrCode menu_port_default_modbus_send(ModbusRegType reg_type, uint16_t reg_addr, const uint8_t* reg_buf, uint8_t buf_len)
|
||||
{
|
||||
// 默认不实现Modbus发送
|
||||
(void)reg_type;
|
||||
(void)reg_addr;
|
||||
(void)reg_buf;
|
||||
(void)buf_len;
|
||||
return MENU_ERR_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 默认Modbus接收函数
|
||||
* @param reg_type 寄存器类型
|
||||
* @param reg_addr 寄存器地址
|
||||
* @param reg_buf 寄存器数据
|
||||
* @param buf_len 数据长度
|
||||
* @return 错误码
|
||||
*/
|
||||
static MenuErrCode menu_port_default_modbus_receive(ModbusRegType reg_type, uint16_t reg_addr, uint8_t* reg_buf, uint8_t buf_len)
|
||||
{
|
||||
// 默认不实现Modbus接收
|
||||
(void)reg_type;
|
||||
(void)reg_addr;
|
||||
(void)reg_buf;
|
||||
(void)buf_len;
|
||||
return MENU_ERR_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 默认持久化保存函数
|
||||
* @param data 要保存的数据
|
||||
* @param size 数据大小
|
||||
* @return 错误码
|
||||
*/
|
||||
static MenuErrCode menu_port_default_persistence_save(const uint8_t* data, uint16_t size)
|
||||
{
|
||||
// 默认不实现持久化保存功能
|
||||
(void)data;
|
||||
(void)size;
|
||||
return MENU_ERR_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 默认持久化恢复函数
|
||||
* @param data 恢复数据缓冲区
|
||||
* @param size 数据大小
|
||||
* @return 错误码
|
||||
*/
|
||||
static MenuErrCode menu_port_default_persistence_restore(uint8_t* data, uint16_t* size)
|
||||
{
|
||||
// 默认不实现持久化恢复功能
|
||||
(void)data;
|
||||
(void)size;
|
||||
return MENU_ERR_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 默认硬件驱动
|
||||
*/
|
||||
static const MenuPortDriver sg_default_driver = {
|
||||
.printf = menu_port_default_printf,
|
||||
.get_tick = menu_port_default_get_tick,
|
||||
.delay_ms = menu_port_default_delay_ms,
|
||||
.display = menu_port_default_display,
|
||||
.key_scan = menu_port_default_key_scan,
|
||||
.irq_ctrl = menu_port_default_irq_ctrl,
|
||||
.error_handler = menu_port_default_error_handler,
|
||||
.modbus_send = menu_port_default_modbus_send,
|
||||
.modbus_receive = menu_port_default_modbus_receive,
|
||||
.persistence_save = menu_port_default_persistence_save,
|
||||
.persistence_restore = menu_port_default_persistence_restore,
|
||||
};
|
||||
|
||||
/* 函数实现 ---------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief 初始化硬件端口层
|
||||
* @param driver 硬件驱动结构体指针
|
||||
* @return 错误码
|
||||
*/
|
||||
MenuErrCode menu_port_init(const MenuPortDriver* driver)
|
||||
{
|
||||
if (driver != NULL) {
|
||||
sg_menu_port_driver = driver;
|
||||
} else {
|
||||
sg_menu_port_driver = &sg_default_driver;
|
||||
}
|
||||
return MENU_ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 反初始化硬件端口层
|
||||
* @return 错误码
|
||||
*/
|
||||
MenuErrCode menu_port_deinit(void)
|
||||
{
|
||||
sg_menu_port_driver = NULL;
|
||||
return MENU_ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取当前系统时间(ms)
|
||||
* @return 系统时间(ms)
|
||||
*/
|
||||
uint32_t menu_port_get_tick(void)
|
||||
{
|
||||
if (sg_menu_port_driver != NULL && sg_menu_port_driver->get_tick != NULL) {
|
||||
return sg_menu_port_driver->get_tick();
|
||||
}
|
||||
return menu_port_default_get_tick();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 硬件延迟函数
|
||||
* @param ms 延迟时间(ms)
|
||||
*/
|
||||
void menu_port_delay_ms(uint32_t ms)
|
||||
{
|
||||
if (sg_menu_port_driver != NULL && sg_menu_port_driver->delay_ms != NULL) {
|
||||
sg_menu_port_driver->delay_ms(ms);
|
||||
} else {
|
||||
menu_port_default_delay_ms(ms);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 打印函数
|
||||
* @param fmt 格式化字符串
|
||||
* @param ... 可变参数
|
||||
*/
|
||||
void menu_port_printf(const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
if (sg_menu_port_driver != NULL && sg_menu_port_driver->printf != NULL) {
|
||||
sg_menu_port_driver->printf(fmt, args);
|
||||
} else {
|
||||
menu_port_default_printf(fmt, args);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 菜单显示函数
|
||||
* @param menu_name 菜单名称
|
||||
* @param menu_id 菜单ID
|
||||
*/
|
||||
void menu_port_display(const char* menu_name, uint16_t menu_id)
|
||||
{
|
||||
if (sg_menu_port_driver != NULL && sg_menu_port_driver->display != NULL) {
|
||||
sg_menu_port_driver->display(menu_name, menu_id);
|
||||
} else {
|
||||
menu_port_default_display(menu_name, menu_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 按键扫描函数
|
||||
* @return 按键事件类型
|
||||
*/
|
||||
MenuEventType menu_port_key_scan(void)
|
||||
{
|
||||
if (sg_menu_port_driver != NULL && sg_menu_port_driver->key_scan != NULL) {
|
||||
return sg_menu_port_driver->key_scan();
|
||||
}
|
||||
return menu_port_default_key_scan();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 中断管理函数
|
||||
* @param enable 是否启用中断
|
||||
*/
|
||||
void menu_port_irq_ctrl(bool enable)
|
||||
{
|
||||
if (sg_menu_port_driver != NULL && sg_menu_port_driver->irq_ctrl != NULL) {
|
||||
sg_menu_port_driver->irq_ctrl(enable);
|
||||
} else {
|
||||
menu_port_default_irq_ctrl(enable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 错误处理函数
|
||||
* @param err_code 错误码
|
||||
*/
|
||||
void menu_port_error_handler(MenuErrCode err_code)
|
||||
{
|
||||
if (sg_menu_port_driver != NULL && sg_menu_port_driver->error_handler != NULL) {
|
||||
sg_menu_port_driver->error_handler(err_code);
|
||||
} else {
|
||||
menu_port_default_error_handler(err_code);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 断言失败处理函数
|
||||
* @param expr 断言表达式
|
||||
* @param file 文件名
|
||||
* @param line 行号
|
||||
*/
|
||||
void menu_assert_failed(const char* expr, const char* file, uint32_t line)
|
||||
{
|
||||
// 打印断言失败信息
|
||||
char buf[128] = {0};
|
||||
snprintf(buf, sizeof(buf), "Assertion failed: %s, file %s, line %lu\n", expr, file, (unsigned long)line);
|
||||
|
||||
// 直接使用printf输出,因为menu_port_printf需要va_list参数
|
||||
printf("%s", buf);
|
||||
|
||||
// 进入死循环
|
||||
while (1) {
|
||||
// 可以添加其他处理逻辑,如复位系统等
|
||||
}
|
||||
}
|
||||
111
port/menu_port.h
Normal file
111
port/menu_port.h
Normal file
@ -0,0 +1,111 @@
|
||||
/**
|
||||
**********************************************************************************************************************
|
||||
* @file menu_port.h
|
||||
* @brief 菜单组件硬件端口层定义
|
||||
* @author menu_component
|
||||
* @date 2025-12-19
|
||||
**********************************************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef MENU_PORT_H
|
||||
#define MENU_PORT_H
|
||||
|
||||
/* Includes ----------------------------------------------------------------------------------------------------------*/
|
||||
#include "../src/core/menu_config.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
/* 类型定义 ---------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Modbus寄存器类型
|
||||
*/
|
||||
typedef enum {
|
||||
MODBUS_REG_TYPE_COIL, /*!< 线圈寄存器 */
|
||||
MODBUS_REG_TYPE_DISCRETE_INPUT, /*!< 离散输入寄存器 */
|
||||
MODBUS_REG_TYPE_HOLDING_REG, /*!< 保持寄存器 */
|
||||
MODBUS_REG_TYPE_INPUT_REG, /*!< 输入寄存器 */
|
||||
} ModbusRegType;
|
||||
|
||||
/**
|
||||
* @brief 持久化操作回调函数类型定义
|
||||
*/
|
||||
typedef MenuErrCode (*MenuPersistenceSaveCallback)(const uint8_t* data, uint16_t size); ///< 保存持久化数据回调
|
||||
typedef MenuErrCode (*MenuPersistenceRestoreCallback)(uint8_t* data, uint16_t* size); ///< 恢复持久化数据回调
|
||||
|
||||
/**
|
||||
* @brief 硬件驱动结构体
|
||||
*/
|
||||
typedef struct {
|
||||
void (*printf)(const char* fmt, va_list args); ///< 硬件打印接口
|
||||
uint32_t (*get_tick)(void); ///< 获取系统滴答时间
|
||||
void (*delay_ms)(uint32_t ms); ///< 硬件延迟函数
|
||||
void (*display)(const char* menu_name, uint16_t menu_id); ///< 菜单显示接口
|
||||
MenuEventType (*key_scan)(void); ///< 按键扫描接口(可选)
|
||||
void (*irq_ctrl)(bool enable); ///< 中断管理接口(可选)
|
||||
void (*error_handler)(MenuErrCode err_code); ///< 错误处理接口(可选)
|
||||
MenuErrCode (*modbus_send)(ModbusRegType reg_type, uint16_t reg_addr, const uint8_t* reg_buf, uint8_t buf_len); ///< Modbus发送接口(可选)
|
||||
MenuErrCode (*modbus_receive)(ModbusRegType reg_type, uint16_t reg_addr, uint8_t* reg_buf, uint8_t buf_len); ///< Modbus接收接口(可选)
|
||||
MenuPersistenceSaveCallback persistence_save; ///< 持久化数据保存接口(可选)
|
||||
MenuPersistenceRestoreCallback persistence_restore; ///< 持久化数据恢复接口(可选)
|
||||
} MenuPortDriver;
|
||||
|
||||
/* 函数声明 ---------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief 初始化硬件端口层
|
||||
* @param driver 硬件驱动结构体指针
|
||||
* @return 错误码
|
||||
*/
|
||||
MenuErrCode menu_port_init(const MenuPortDriver* driver);
|
||||
|
||||
/**
|
||||
* @brief 反初始化硬件端口层
|
||||
* @return 错误码
|
||||
*/
|
||||
MenuErrCode menu_port_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief 获取当前系统时间(ms)
|
||||
* @return 系统时间(ms)
|
||||
*/
|
||||
uint32_t menu_port_get_tick(void);
|
||||
|
||||
/**
|
||||
* @brief 硬件延迟函数
|
||||
* @param ms 延迟时间(ms)
|
||||
*/
|
||||
void menu_port_delay_ms(uint32_t ms);
|
||||
|
||||
/**
|
||||
* @brief 打印函数
|
||||
* @param fmt 格式化字符串
|
||||
* @param ... 可变参数
|
||||
*/
|
||||
void menu_port_printf(const char* fmt, ...);
|
||||
|
||||
/**
|
||||
* @brief 菜单显示函数
|
||||
* @param menu_name 菜单名称
|
||||
* @param menu_id 菜单ID
|
||||
*/
|
||||
void menu_port_display(const char* menu_name, uint16_t menu_id);
|
||||
|
||||
/**
|
||||
* @brief 按键扫描函数
|
||||
* @return 按键事件类型
|
||||
*/
|
||||
MenuEventType menu_port_key_scan(void);
|
||||
|
||||
/**
|
||||
* @brief 中断管理函数
|
||||
* @param enable 是否启用中断
|
||||
*/
|
||||
void menu_port_irq_ctrl(bool enable);
|
||||
|
||||
/**
|
||||
* @brief 错误处理函数
|
||||
* @param err_code 错误码
|
||||
*/
|
||||
void menu_port_error_handler(MenuErrCode err_code);
|
||||
|
||||
#endif /* MENU_PORT_H */
|
||||
Reference in New Issue
Block a user