【串口读写求助】如何在代码里面向系统串口发送和读取数据

答案内容由AI生成,仅供参考:

如何在 openUBMC 环境下通过系统串口读取 Expander 日志数据

根据您提供的需求和环境信息(openUBMC 2512 LTS SP1),以下是对 如何通过系统串口与 Expander 通信 的完整技术指导,结合知识图谱与文档内容进行系统性说明。


:magnifying_glass_tilted_left: 问题核心分析

您的需求本质是:

  1. 配置 BMC 的 UART 接口连接到扩展板(Expander);
  2. 在 BMC 侧通过代码向该串口发送命令;
  3. 从同一串口读取返回的日志或响应数据。

这涉及到 硬件连接配置BMC 层串口管理机制 以及 应用程序层的数据收发实现 三个层面。


:white_check_mark: 系统串口是否对应 /dev/ttySX

是的,/dev/ttySX 是底层串口对应的字符设备文件,但直接操作它们存在风险,推荐使用 openUBMC 提供的管理接口。

相关事实依据:

  • UART3 被明确用于收集 OS 系统串口记录,连接至 KP920 模块,仅 RX 接入(见 KG: UART3)。
  • 系统中存在多个串口设备(UART1~UART7),可通过配置互连不同端口(见 Document Chunk 4、8)。
  • openUBMC 支持通过 UartPort 对象管理各 UART 接口,底层映射为 /dev/ttySX(如 /dev/ttyS3 对应 UART3)。

:warning: 注意:直接读写 /dev/ttySX 可能绕过系统级日志记录和权限控制,不推荐在正式功能中使用


:puzzle_piece: 一、硬件与配置层:如何配置 UART 连接到 Expander?

1. 确认物理连接路径

确保 CPU 的串口输出可通过硬件开关切换至 Expander,且此串口信号已接入 BMC 的某个 UART 接收引脚(例如 UART4 接 PORT4)。

文档线索:

“默认的Uart4和Port4是互联的,你要用这个uart的话让硬件设计串口对端连到Port4的引脚就行了”
—— 李硕来,Document Chunk #4

2. 配置 VPD 或 CSR 定义串口行为

vpd.json 或平台配置中定义 UartPort 对象,关键字段如下:

"Uart_4": {
  "Id": 4,
  "Description": "UART4 连接到 PORT4,用于读取 Expander 日志",
  "PortConnection": 4,         // 映射到 Port4
  "BaudRate": 115200,
  "DataBit": 8,
  "ParityBit": 78,             // 'N' (78 ASCII),即无校验
  "StopBit": 1,
  "SerialSwitch": "<=/Scanner_Gpio31.Value",
  "@Default": {
    "SerialSwitch": 1
  }
}

:wrench: 说明

  • PortConnection: 指定 UART4 与哪个物理端口(PORT)连接。
  • SerialSwitch: 控制物理开关切换串口方向(如切换至面板或 BMC 监听)。
  • 使用 ScannerAccessor 从 CPLD 获取动态参数(参考 UartDynamicConfig)。

:gear: 二、系统功能支持:串口录制与数据采集

openUBMC 支持 串口日志录制(circular log),适合持续采集 Expander 输出。

创建 UartCircularLog 对象(需平台配置支持)

"UartCircularLog_4": {
  "Id": 4,
  "LogDirection": 1,           // 1: 接收方向(RX)
  "RxSize": 10,                // 接收缓冲区大小,单位MB
  "TxSize": 0,
  "LogEnable": 1,
  "AutoCollect": 0,            // 是否自动触发收集
  "IsSysCom": 0                // 0: 非系统串口(BMC自身串口为1)
}

:pushpin: 作用

  • 自动将从 UART4 收到的数据循环缓存到内存。
  • 支持通过“一键收集”导出为 uart4com.dat(参考 Document Chunk #5)。

:laptop: 三、应用层开发:如何在代码中读写串口?

虽然 openUBMC 抽象了串口管理,但您仍可通过以下方式实现主动通信。

方法一:调用 Lua 脚本 + DBus 接口(推荐)

openUBMC 使用 Serial_Mgmt.lua 管理串口配置。用户应通过 DBus 接口 与系统组件交互。

示例:通过 D-Bus 查询 UART 状态(Python-like 伪代码)

import dbus

# 连接到 D-Bus 系统总线
bus = dbus.SystemBus()

# 获取 UartPort1 对象
uart_obj = bus.get_object('bmc.kepler.Managers.UartPort', '/org/openbmc/UartPort/4')
uart_iface = dbus.Interface(uart_obj, 'bmc.kepler.Managers.UartPort')

# 调用 Reset 方法初始化串口
uart_iface.Reset({"BaudRate": 115200, "DataBits": 8})

# 读取当前属性
props = uart_iface.GetAll('')
print("Current ID:", props['Id'])

示例:使用 UartData 接口导出日志

# 获取 UartData 管理器
uart_data_obj = bus.get_object('bmc.kepler.Managers.UartData', '/org/openbmc/UartData')
uart_data_iface = dbus.Interface(uart_data_obj, 'bmc.kepler.Managers.UartData')

# 导出系统串口日志
task_id = uart_data_iface.Export(Type="SYS COM", FilePath="/tmp/expander_log.tar")

:white_check_mark: 支持导出类型包括:SYS COM(系统串口)、ALL


方法二:直接操作 /dev/ttySX(实验性)

仅建议用于测试阶段。

示例:Linux shell 读写 /dev/ttyS4

# 设置串口参数
stty -F /dev/ttyS4 115200 cs8 -cstopb -parenb

# 发送命令(如 'LOG?\n')
echo -ne "LOG?\n" > /dev/ttyS4 &

# 实时读取返回数据
cat /dev/ttyS4

:warning: 注意事项:

  • 必须确保无其他进程占用该串口(如 klogdSerial_Mgmt.lua);
  • 波特率、数据位等必须与对端完全一致;
  • 推荐在隔离容器或调试模式下操作。

:pushpin: 四、关键配置建议总结

项目 建议
串口号选择 使用 UART4 或预留专用 UART,避免与 OS 系统串口(UART3)冲突
波特率 固定为 115200(除非 Expander 特殊要求)
数据格式 8 数据位,无校验,1 停止位(8N1)
配置方式 在 VPD 或 CSR 中静态配置 UartPortUartCircularLog
通信方式 使用 D-Bus 调用标准接口,避免直接操作设备节点
数据收集 启用 UartCircularLog,支持随时“一键收集”

:blue_book: 参考资料与链接


:white_check_mark: 建议下一步操作

  1. 联系硬件团队确认:Expander 串口是否已连接至某 PORT,并确认切换逻辑;
  2. 配置平台 VPD 文件:添加 Uart_4UartCircularLog_4
  3. 部署并验证配置:使用 ipmcget 或 D-Bus 工具查看对象是否存在;
  4. 编写测试脚本:通过 Lua 或 Python 调用 D-Bus 接口发送/接收数据;
  5. 测试一键收集:验证 uart4com.dat 是否包含预期数据。

如需更深入的代码示例(如完整 Lua 脚本或 C++ 调用 DBus),建议在 openUBMC 社区论坛hardwarebmc_core SIG 会议上提出讨论。