硬件代理插件使用指南
更新时间:2025/10/15
在Gitcode上查看源码硬件代理插件使用指南
1. 概述
硬件代理插件(hwproxy插件)提供了一种直接访问硬件的机制。通过该机制,各业务组件可以将自己的硬件访问逻辑封装为插件,在保证系统稳定性的前提下实现对硬件的直接控制。
其核心特点包括:
- 独占式总线访问:插件执行期间锁定总线资源,确保操作完整性
- 自定义协议处理:开发者可自由实现数据解析和协议转换逻辑
- 灵活控制:通过插件机制,开发者可以灵活控制硬件访问的粒度和时序
2. 系统架构与执行流程
2.1 访问流程图
2.2 执行流程说明
- 请求初始化:业务组件构建包含超时配置的上下文对象
- 插件加载:hwproxy从
/opt/bmc/lualib/hwproxy目录动态加载Lua插件 - 命令校验:通过插件的
has_cmd方法验证命令存在性 - 通道传递:将封装硬件操作能力的
chip对象作为首个参数传递 - 自定义执行:插件通过
run_cmd接口实现具体操作逻辑 - 结果返回:将处理结果以二进制数组形式返回给调用方
3. 核心接口详解
3.1 PluginRequest接口规范
3.1.1 函数签名
lua
-- 调用示例:result = chip:PluginRequest(ctx, plugin_name, cmd, args)
function PluginRequest(
ctx: Context, -- 上下文对象(可设置超时时间)
plugin_name: string, -- 插件名称(需与目录文件名一致)
cmd: string, -- 命令名称(插件中定义的函数)
args: string -- 参数(通过skynet.pack打包)
): string -- 返回值(通过skynet.unpack解析)3.1.2 参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| ctx | Context | 上下文对象,可通过ctx.timeout = N设置超时时间(默认120秒) |
| plugin_name | string | 插件文件名(需与/opt/bmc/lualib/hwproxy/目录下的Lua文件名一致) |
| cmd | string | 插件中定义的命令函数名(需通过has_cmd方法验证存在) |
| args | string | 参数序列化字符串(使用skynet.pack或skynet.packstring打包) |
3.1.3 返回值
- 类型:字符串(需通过
skynet.unpack解析为原始数据类型) - 内容:插件执行结果(如读取的二进制数据、错误码等)
4. 插件开发规范
每个有效插件必须包含以下结构: 每个有效插件必须包含以下结构:
lua
-- 基础插件模板
local plugin_class = class()
-- 命令存在性校验
function plugin_class:has_cmd(cmd_name)
return self.commands[cmd_name] ~= nil
end
-- 命令执行入口
function plugin_class:run_cmd(chip, cmd, ...)
return self.commands[cmd](chip, ...)
end
-- 命令实现集合
plugin_class.commands = {
read_data = function(chip, offset, length)
-- 具体操作逻辑
end,
write_data = function(chip, data)
-- 具体操作逻辑
end
}
return plugin_class注意事项:
- 上述
chip为hwproxy组件的chip.lua的内存实例对象,在具体操作逻辑中,只允许调用read和write函数 - 单个操作逻辑,原则上不允许连续执行1秒以上
5. 典型应用场景
5.1 长数据读取案例
lua
-- 插件实现:分块读取硬件日志
function read_log_by_mcu(chip, total_size)
local buffer = ""
local input = object_pool.new('input_args', OFFSET, DEFAULT_MASK, BLOCK_ACCESS_TYPE, READ_LEN, nil)
while total_size > 0 do
local chunk = math.min(total_size, MAX_CHUNK_SIZE)
local ok, result = pcall(chip.read, chip, input)
buffer = buffer .. result
total_size = total_size - chunk
end
return buffer
end
-- 调用示例:日志导出
local function export_log_file(file_path)
local ctx = context.new{ timeout=600 }
local log_data = chip:PluginRequest(ctx, "logger", "read_log_by_mcu", 1024*1024)
file:write(skynet.unpack(log_data))
end6. 关键注意事项
6.1 代码结构要求
- 插件必须继承基类并实现
has_cmd和run_cmd方法 - 命令函数需以
commands.[命令名]形式定义
6.2 性能与资源
警告:插件执行期间独占总线,可能导致其他硬件访问超时
6.3 参数传递限制
- 单次参数总长度有限制,超限需改用文件路径传递
6.4 超时配置
- 默认超时时间为120秒(2分钟),长任务需显式设置
ctx.timeout = N