1 一句话总结
- 一定是基于对硬件功能(或可预见未来将要具备的功能)的抽象来设计接口
2 禁忌
2.1 基于需求描述而没有进行抽象
-
议题早期描述:NPUCard接口新增属性MosNpuTemp、MosGfTemp、AiCoreDrmosTemp、BusDrmosTemp、PfmDrmosTemp、SzxPsipTemp。
-
这样设计的问题在于完全没有对新增的属性进行抽象,后续新增温度点就得新增属性
2.2 基于功能实现而忽略硬件特质
这是接口设计中最常犯的错误
1、还是上面这个例子:【已评审】新增资源协作接口属性表示NPU卡电源器件温度
-
该议题早期还有一个评审点:bmc.kepler.Systems.NPUCard新增AiCoreTemp、HBMTemp、PREDEVTemp和VRDTemp
-
这样设计的问题在于没意识到NPU卡的数据模型是卡+NPU,而新增的这些温度属性是属于NPU的,不是NPUCard的。这些属性在bmc.kepler.Systems.Processor.NPU已经有了
2、另一个例子是:【已评审】新增资源协作接口属性解决BIOS从BMC获取PCIe槽位信息超时问题
-
背景是bios组件需要获取pcie_device组件提供的PCIe建链所需信息,然后传给带内BIOS。一个设计思路是bios组件提供方法供pcie_device组件调用
-
但是这个方案最终没有往上写,因为bios对象不应该具备对外提供设置PCIe槽位信息的特质,尽管在软件层面上加个rpc方法是可行的
-
换个角度考虑,bios组件还会收集其他部件的槽位信息,如果bios对象增加一个设置PCIe槽位信息的rpc方法,那么其他部件的方法要不要加?
3、一种比较好的思路是查阅标准中是否有相关表述,如果能在标准中查到,说明xx对象具备xx属性/方法已经成为业界共识
3 常用属性设计思路
3.1 温度
1、要不要考虑负值:如果需要,则数据类型不能是无符号类型
2、要不要考虑小数:如果需要,则应当使用Double类型。北向接口、传感器配置一般不需要这么高的精度,用整型就可以
3、默认值、无效值怎么定义:
-
如果是整型,可以考虑极值。如U8是255(0不行,因为0可能是正常温度),U16是65535,S16是32767和-32768
-
-32768作为S16类型以十六进制表示为0x8000,但是代码里用0x8000去给S16类型的属性赋值会报错
-
以往U16类型为什么会有0x8000、0x4000这种取值:本质上是bit 15、bit 14置位,分别表示读取失败和未读取。在这种设计思路下,可以定义0x8000为无效值、0x4000为默认值
-
当前openUBMC已经引入了ReadingStatus的概念(见bmc.kepler.Systems.ThresholdSensor),如果要业务组件体现读取失败、未读取等状态,那么要么额外新增一个表示状态的属性,要么还是通过读数来标记状态
-
参考BIOS的IPMI接口说明和Atlas卡带外管理接口说明,通常采用通过读数来标记状态的做法
-
不同的部件可以根据业务要求分别定义不同状态(正常、失败、预失败、无效、初始)下的取值。比如温度读取失败时填0x7fff、温度未读取时填0x7ffe,这两个也可以认为就是无效值和默认值