AN-2608: Linux 电源系统管理程序
摘要
一款用于数字电源系统管理(PSM)设备的开源、自动配置型 Linux C/C++应用程序已在 github 上发布。该应用程序在用户空间中运行,使用/dev/i2c 进行I2C 通信。本应用笔记介绍该应用程序的代码框架、调试和基于 Web 的工具支持,并讨论两种主要解决方案。
阅读应用笔记后,读者应当能够成功下载、编译和运行该应用程序,从而将其用于定制软件设计、设备编程或电源系统调试。
具备 Linux 用户态 C 应用程序开发经验者会更容易上手。
引言
大多数电源系统管理(PSM)设计遵循“设置后不管”模式。与 LTpowerPlayTM 配合使用时,PSM 设备的设置和调试变得更加简单。此外,为了简化操作,当与批量编程解决方案结合使用时,不需要软件/固件。但是,许多大型系统需要板级管理控制器(BMC)。这就不禁让人思考:“软件或固件对 PSM 有何作用?”
PSM 软件/固件的基础是 PMBus,PMBus 是 SMBus 的基础,而 SMBus 的基石是I2C 。要构建一个能通过PSM 软件或固件实现增值功能的 BMC,程序员需对各种协议或现有类/代码具备一定的了解,以免陷入繁琐的细节。
Linux示例应用程序会处理每个协议层并提供应用程序编程接口(API),以便于编写用户空间PSM软件/固件。Linux PSM 不是 BMC 的替代品,而是一组类和一个示例应用程序,与典型 BMC 软件/固件兼容。
Linux 也可以配合 ADI 评估板使用,作为一种学习工具。工程师常常将 Linux 代码片段复制并粘贴到现有应用程序中加以使用,但也可以复用整个类的层次结构,包括:
- 设备和电源轨发现
- 命令 API
- 故障日志解码
- 系统内编程
本应用笔记介绍 Linux 代码库、PSM 编程、设置、Linux PSM 配合评估板的使用及 PSM 调试技术。有关协议和一般编程问题的详细信息,请参阅《 应用笔记 135:实现适用于 LTC3880 的稳健 PMBus 软件》及 I2C/SMBus/PMBus 的行业标准。1
Linux PSM
评估和开发硬件
Linux PSM 硬件包括 Devantech® USB 转 I2C 适配器(一款小型三线连接设备),用于连接评估板(中间板)或最终产品板的 PMBus、SMBus 或 I2C 总线。
为了获得更好的学习效果,建议从以下设备开始:DC1613A、DC1962C2 、Devantech 适配器 3和 Total Phase® BeagleTM4(I2C 嗅探器)。这些设备可用于控制器(LTC388X/µModule)和管理器(LTC297X)的编程、调试和学习。
图 1 显示了推荐的硬件,它们通过抓取夹实现连接。要将此硬件与 Linux PSM 软件配合使用,请用两根 Type A 转 Type B USB 线缆,将 Devantech 适配器和 Beagle 连接到 Linux 计算机(Type A 连接到小板,Type B 连接到计算机)。如果 Beagle 的 USB 未连接,请将 Beagle 的扁平线缆与抓取夹分开,以防干扰往返于 DC1962C的 PMBus 通信。5
Linux 兼容性
Linux PSM 代码基于一个自动配置项目,已利用以下环境进行了测试:运行 Ubuntu 24 的 VMWare 虚拟机(VM),以及通过 I/O 引脚实现 I2C 通信的树莓派。本应用笔记基于 VMWare 上运行的 Ubuntu 24 平台,并使用简单的 make 命令在 Ubuntu 24 上编译代码。
当使用 USB 线缆将 Devantech 适配器插入 PC 时,VM Linux 实例(可能需要使用其菜单将 USB 设备连接到 VM)会创建 /dev/i2c-0 文件。Linux 代码通过此文件操作I2C 。在树莓派平台上,I2C 内置于微处理器芯片中,同样会创建/dev/i2c-N,类似于 BMC 的嵌入式 Linux 创建/dev/i2c-N,其中N 是 Linux 分配的某个编号。一旦知道 N,就可以修改代码以匹配该值,或者通过命令行传入 N 值。
注:Devantech Linux 驱动程序未随 Ubuntu 24 安装,必须手动编译和安装。
/dev/i2c-N创建后,普通用户对其无写入权限。请勿以超级用户身份运行该 Linux 应用程序,而应按如下方式更改权限:
sudo chmod 666 /dev/i2c-N
其中N为实际数字。每次插入 USB 时都必须重复执行此命令,除非采取其他措施,在插入时自动更改文件权限。
安装 Devantech 驱动程序
此驱动程序以源代码形式提供,可通过以下链接获取:
groeck/devantech: Devantech USB-ISS Linux kernel driver (github.com)
用户通常会在其 Linux 系统上安装 git,然后从上方链接克隆代码。驱动程序代码附带的 README 文件包含安装信息,具体步骤如下:
$ sudo make install.- 将
i2c-devantech-iss添加到/etc/modules文件中,屏蔽 USB-ISS 驱动。 - 重新启动 Linux。
- 执行 README 文件中的所有步骤。注:如果系统不是 Ubuntu 24,则可能需要安装适当的 Linux头文件。
- 通过 USB 连接 Devantech 适配器,并确保它创建
-l /dev/i2c*. - 调整权限,使代码可以写入文件。
- 若有许多 I2设备,请通过以下命令进行测试以找到正确的 N:
sudo i2cget 0 0x30 0.
此操作使用命令 0x00 (PAGE)从地址 0x30处的设备( (N == 0) )读取字节。DC1962C 在该地址有一个 PMBus设备。为每个 N 发出此命令,直到其中一个做出响应。然后尝试地址 0x32或 0x33 ,确保它们也做出响应。
知道 N 后,它便始终不变。在虚拟机上,N 通常为 0。在 NUNC 盒子或其他嵌入式系统上,它可以是任意数字。
Linux PSM 应用程序
Linux 代码可从以下位置克隆(使用 git):
编译:
- 切换至顶层目录(cd)并发出以下命令:
./configure make
- 然后运行它,发出以下命令:
cd src ./LT_PMBusApp -i
此操作使应用程序以基于文本的界面在交互模式下运行。去除-i 可获得命令行选项列表。
注: 上述操作能否执行,取决于对/dev/i2c-N 是否有写权限。
命令行选项包括:
./LT_PMBusApp [-d dev] ( // 设备路径 [-p file] | // 使用文件进行编程 [-v address] | // 转储故障 [-x address] | // 禁用故障日志 [-e address] | // 启用故障日志 [-s address] | // 存储故障日志 [-c address] | // 清除故障日志 [-i]) // 菜单
设备路径选项可以与任何其他选项组合使用,但其他选项一次只能使用一个。当 N 不是默认值 0 时,设备路径选项用于提供 N 值。
菜单操作
要操作菜单系统,请输入菜单选择列表左侧的数字,然后按 Enter。从菜单项 1 开始,它包含“1 - Read All
Voltages”和“4 - Sequence On/Off”等选择。从“1 – Read All Voltages”开始。
应用程序会检测所有 PSM 设备并维护它们的内部结构,包括每个设备的页面数。选择一个电压后,就会逐个地址、逐页地记录整个树状结构的值。
系统内编程
系统内编程是一种编程方式,能够在不影响 PSM 设备运行的情况下,直接将设置写入 EEPROM。AN-166:Linduino 实时更新 描述了该过程,以及如何从 LTpowerPlay 导出 isphex 文件(系统内编程十六进制文件)。
使用 isphex 文件通过以下命令对设备进行编程:
./LT_PMBusApp -d N -p file
在制造环境中使用 Linux 进行测试时,这种方式非常有用,能够一次性对所有设备进行编程。
修改代码
代码有两个入口函数:main()只执行一次,而loop()会在循环中持续执行。
菜单被编码为辅助函数,loop()会调用主菜单函数。每个菜单对应一个 case 语句,每个 case 分支处理一个菜单编号。
要修改应用程序,只需使用所提供的 API 更改代码中的 case 语句。代码中发出 PMBus 命令的函数(API)来自单独的类层次结构,其命名简洁,直观地反映了所要执行的功能。
例如:
voltage = pmbus->readVout(0x30, false);
意思是使用 PMBus API 对象,读取地址0x30处的输出电压(不轮询),然后将其放入名为 voltage 的变量中。
作为练习,请进行一些简单的修改。例如,添加一个菜单项来读取并显示输出功率。完成后,尝试从菜单中调用此函数:
float readPout(uint8_t address, bool polling);
在 DC1962C 上,在地址 0x30 处的 LTC3880 上测试此函数。为验证其功能,请在 DC1962C 的通道 0 上添加阻性或电流负载,并确认其是否与代码输出结果相符。
PSM PMBus 类
PMBus 类位于 src 目录中。类层次结构采用分层设计:从 I2C 开始,然后是 SMBus,最后是 PMBus。有一个数字转换 API,用于实现 L11/L16 值(PMBus 格式)与浮点数的相互转换。此外,其中还有组命令协议支持、设备和电源轨发现、故障日志解码,甚至系统内编程。
每一层都是一个简单的 C++类。如果最终环境是 C,请勿担心!开发者既可以直接使用 C++类,以减少内存 开销,也可以移除类封装,轻松地以纯 C 形式使用。C++封装简化了应用程序代码,使非程序员更容易使用。
对于希望了解底层机制的程序员,请注意:SMBus 类采用层级结构设计,使得应用程序代码独立于 PEC 的启用和关闭,并且有助于移植,而 I2C 类则封装了对/dev/i2c-N 文件的 IO 操作。如果将代码移植到非 Linux平台,则 I2C 类会被重写以使用寄存器或预先存在的库。
使用 PMBus 类
即使不了解类,也可使用 API。只需导入几个模块并定义一些静态变量,代码即可开始运行。
其中最重要的是:
#include <LT_SMBusPec.h> #include <LT_SMBusNoPec.h> #include <<lt_pmbus.h></lt_pmbus.h>LT_PMBus.h> #include <LT_PMBusMath.h>及
static LT_PMBus *pmbus = new LT_PMBus(smbus);
调试
有多种方法可以调试 Linux PSM 应用程序或相关的固件应用程序:
- 打印
- 监听工具
- 调试器
本应用笔记不介绍调试器选项。
由于代码会被编译为命令行应用程序,因此打印语句是很好的调试工具。PSM 库使用此技术来处理常见错误,例如 NACK 和 PEC,因为命令行会打印此类错误。开发者可以复制粘贴现有的错误消息代码,并稍作修改,使其能够在代码的关键位置打印消息。
对于 PMBus 调试而言,Beagle 堪称终极监听利器。这个监听工具十分方便,能够监控总线流量,生成的追踪记录可直接与代码一并通过电子邮件发送给 ADI 现场应用工程师,以便快速获取帮助。
本应用笔记重点关注 Total Phase Data Center 应用程序与 Total Phase Beagle 通信所生成的数据。有关安装 Data Center 应用程序的信息,请访问 Total Phase 网站 (www.totalphase.com)。
最简单的入门方法是使用该应用程序来追踪总线。以菜单选择 3(读取电压)为例。
图 3 显示了该数据。让我们直接开始解读一些事务,并通过索引来标记位置。
在索引#1 (I1)和索引#6 (I6)处,有两个写入字节事务。在 SMBus 中,这被定义为写入字节协议。地址为 0x30,即 LTC3880,如代码所示。第一个字节是0x00,即 PAGE命令。
LTC3880 数据手册中的表 2 说明了 PAGE 命令。该表提供了一种快速解读 Beagle 数据的方法。请注意,Type(类型)列显示“R/W Byte”(读/写字节)。这意味着寄存器遵循读/写字节协议,因此两个方向都支持。
观察 I1 和 I6,第二个字节是 0x00 和 0x01。代码将 PAGE 寄存器设置为 0 和 1。
然后我们看到:
Write 0x8B, Read 0x9A 0x0D Write 0x20, Read 0x14
0x8B 是 READ_VOUT 命令。数据手册中的表 2 显示它是一个“R Word”(读取字)协议,采用 L16 格式。
0x20是 VOUT_MODE 命令。数据手册中的表 2 显示它是一个“R Byte”(读取字节)命令。
读取 READ_VOUT 和 VOUT_MODE 的代码是:
vout_L16 = smbus_.readWord(address, READ_VOUT);
exp = (int8_t)
(smbus_.readByte(address, VOUT_MODE) & 0x1F);
return math_.lin16_to_float(vout_L16, exp);
此代码中有
smbus_.readWord(address, READ_VOUT)
还有
smbus_.readByte(address, VOUT_MODE),
从 mode 中提取 5 位并放入 exp 变量中。然后,数学转换算法使用指数 exp 将 L16 变为浮点数。
这段通用代码用于读取电压和指数信息,进而将 L16 转换为浮点数。LTC388X 和 LTC297X 器件使用不同的指数。这就是存在两个事务的原因。
注:如果预先知道指数,就可以优化代码以提升运行速度。然而,通用代码错误更少,对应用程序开发者更友好。编写定制代码时,这是一个权衡取舍的问题。
在结束之前,让我们再看一个有趣的事务:复位。
查看图 5。注意有三个写入事务。在 S/P 列中,有两个 S 和一个 SP。这意味着 I1 是起始,I2 是重复起始,I3 是重复起始然后停止。此外,每个事务的地址都不同:0x30, 0x32 和 0x33。
这是组命令协议。所有命令均在 I3 结束(即停止)时处理。
花一些时间解读 Beagle 追踪记录,将有助于开发者更全面地了解 PSM 设备的 PMBus 命令。另一方面,如果目标只是让代码顺利运行,那么 PSM 库可以很好地胜任这些复杂的任务。
双控制器系统的解决方案
如前所述,大多数系统都是“设置后不管”,但有些系统具有 BMC。事实上,带有 BMC 的系统是“设置后不管”与固件的组合。那么为什么要让 BMC 承担全部设置任务呢?更简单的方式是将基本设置写入 PSM 设备中,然后仅使用 BMC 固件来实现增值功能。这也使得系统更加可靠,因为大多数固件只是读取遥测数据和裕量信息,并进行轻微的电压调整。像时序控制和 PWM 频率这样的关键功能始终是静态的,不需要由固件来控制。
LTpowerPlay 是设计、调试和启动 PSM 系统的通用工具,因此在调试固件时,它与物理时钟和数据线上的另一个 PMBus 控制器存在竞争关系。
在讨论两个控制器的实际影响之前,最好先看一下当 PMBus 有两个控制器时会发生什么情况。PMBus 基于SMBus,后者包含多个控制器。
时钟和数据线是开漏型。这意味着任何设备(无论控制器还是目标设备)都可以下拉时钟或数据线,但不能上拉。有一条规则:如果一个控制器没有拉低数据线,但检测到数据线为低电平,则它会认为有另一个控制器将数据线拉低,因而中止其本身的事务,让另一个控制器继续执行其事务。
这种技术有时被称为“位优先仲裁”,简单来说,就是在数据传输中,发送 0 位的控制器总是占上风。
Linux PSM 和 LTpowerPlay (DC1613)均支持仲裁,因此用户很容易认为一切运作良好。然而,仍有一个关键因素不容忽视。
PMBus 定义了一个 PAGE 命令(0x00),其作用类似于数据的地址索引。页面就像通道。例如,LTC2977 可以管理八个电源:它有八个通道,每个通道由 PAGE 寄存器/命令进行寻址。
实际上,这意味着当需要读取某个值(例如电压)的时候,需要两个事务:一个用于 PAGE,一个用于READ_VOUT。如果两个控制器同时尝试从同一目标读取遥测数据,并且一个控制器在另一个控制器的页面命令和遥测命令之间插入页面命令,那么它将读取错误的页面。
当 LTpowerPlay 启动并运行时,其主要功能是读取遥测数据,以使其状态显示与输出、故障和其他重要信息的图表保持同步。猜猜固件通常会做什么?它会读取遥测数据!
更糟糕的是,假设固件在引导启动时执行了一个电压识别(VID)函数,如果由于 LTpowerPlay 修改了 PAGE寄存器,而导致固件将电压值写入错误的页面,会发生什么情况?系统可能会发生故障,甚至造成损坏。幸运的是,VOUT_MAX 寄存器通常能够防止系统损坏。
PAGE 命令的这个基本问题是 PMBus 规范所固有的。这并不是 ADI 电源系统管理器件所独有的,需要引起注意。
有两种方法可以让 LTpowerPlay 与固件共存,避免PAGE 问题。第一种就是不要让两个控制器同时通信。第二种是在其中一个控制器上使用 PAGE PLUS 协议和其他方法,例如全局地址和 PAGE 命令。
PAGE_PLUS 不常用,我们首先来研究一下这种方法。PAGE_PLUS 可以将 PAGE 和 COMMAND 两项操作合并
为一个原子事务执行。并非所有设备都支持它,通常它仅在特殊情况下使用,因此本文不重点介绍 PAGE PLUS和其他深奥的方法。如果实在找不到解决方案,请阅读 ADI PSM LTC3887 和 LTC2977 数据手册,或致电当地的现场应用工程师寻求帮助。
然而,更常见的方法是防止 LTpowerPlay 和固件同时与目标设备通信。LTpowerPlay 可通过一种非常简单的方法来控制其行为。图 6 显示了遥测图,其工具栏上有一个红色方形按钮。
按下此按钮时,总线上的所有遥测和 LTpowerPlay 活动都会停止。然后,它会变成绿色箭头,如图 7 所示。
遗憾的是,固件并不一定内置了让总线静默的机制。ADI 建议设计一个内置静默机制的新固件,或提供一个硬件总线开关/多路复用器或跳线。
一旦总线控制器 LTpowerPlay 和固件处于静默状态,调试就简化为根据需要交替使用这些工具。
总结一下,解决方案有两种:
- 每次只允许一个主机在总线上通信。
- 在 ADI 现场应用工程师的帮助下,了解 PAGE PLUS 和其他先进技术的细节。
对于新设计,前者是更好的选择。
总结
Linux PSM 代码和 Devantech 适配器简化了 PSM 设备的编程。Linux PSM 代码具有适用于 SMBus 和 PMBus的简单 API。LTpowerPlay 仍可用于调试,同时可以连接 Total Phase Beagle 或其他监听工具来观测总线上的流量。
无论是为了移植代码,还是想要了解 PMBus 的工作原理,Linux PSM 都是理想的起点。在掌握了 PSM 编程的基础知识之后,提升技能并更加自信地使用其他工具将不再是难事!
注释
1有关标准文件,参见 www.pmbus.org。
2DC1962C 评估板 | ADI 公司
3Devantech USB 转 I2C 接口适配器 | Acroname
4 Beagle I2C/SPI 协议分析工具 - Total Phase
5Beagle 并非必要,但通过观测 DC1962C 的 PMBus 通信,有助于用户学习理解。强烈建议使用 DC1613A 来调试和恢复 DC1962C 默认配置。
6DC1962C(电源系统管理演示板(Power Stick))的地址 0x30 处有一个 LTC3880,地址 0x32 处有一个 LTC2975,地址 0x33 处有一个 LTC2977。






