简要介绍
SR分为PSR和CSR,其定义如下:
PSR:Product Self-description Record,站在软件的角度来定义整机硬件“是什么,有什么,能做什么”,其体现的主要是整机视角看到的硬件组成结构,配置合法性检查规则等
CSR:Component Self-description Record,站在软件的角度来定义硬件的,使用软件的语言描述硬件“是什么,有什么,能做什么”,其体现的主要是硬件内部的器件信息、器件互联关系、器件的能力等
在openUBMC中,CSR设计的初衷是用于描述硬件信息,方便加载各种硬件时,能够自动读取对应的数据信息。在这里,推荐开发者使用BMC Studio来配置CSR:BMC Studio方便理解,上手快速,具体参考《BMC Studio用户指南》。
CSR结构
基本结构
CSR数据为json格式,完整的CSR结构包含4部分数据:FormatVersion
、Unit
、DataVersion
、ManagementTopology
和Objects
: FormatVersion
和DataVersion
由主版本号和次版本号组成,主版本号范围1~99;次版本号范围0~99,不足两位补0,具体样式为"A.BC"
的非空字符串
CSR整体结构样例
{
"FormatVersion": "3.00",
"DataVersion": "1.00",
"Unit": {
"Type": ,
"Name":
},
"ManagementTopology": {},
"Objects": {}
}
FormatVersion
- 定义:CSR数据格式及整体结构,
由openUBMC统一维护,可能会存在断代情况
- 选项:必填字段
- 格式:
"主版本号.次版本号"
,主版本号范围1~99;次版本号范围0~99,不足两位补0 - 注意事项:硬件自发现会校验和解析FormatVersion的值,需要配置准确
- 定义:CSR数据格式及整体结构,
DataVersion
- 定义:跟随CSR数据内容变化而变化,即增加或修改数据时,需要变更数据版本
- 选项:必填字段
- 格式:
"主版本号.次版本号"
,主版本号范围1~99;次版本号范围0~99,不足两位补0 - 注意事项:硬件自发现会校验和解析DataVersion的值,需要配置准确
Unit
- 定义:描述CSR文件的类型和名称
- Type:描述CSR所属的板卡类型,如EXU、BCU和IEU等
- Name:描述CSR文件的名称,即其主要是描述哪个对象
ManagementTopology结构
ManagementTopology
作为管理拓扑的关键字,解析时默认认为这下面的都是对Objects下面对象的引用,按照树结构根节点开始,以层序遍历的方式平铺列出Bus/Chip/Connector的连接关系
- ManagementTopology只能包含
Anchor
、Buses
、Chips
、Connectors
的层级关系;Anchor是必选对象类型且它一定包含Buses属性
,Buses、Chips和Connectors是可选字段,且不能包含其他对象 - ManagementTopology主要描述CSR文件中链路逻辑关系,需要对照设计的硬件链路来配置。
- Anchor是上一级Connector传递链路的入口,是和上级板卡连接的桥梁。
- 传入的Buses上可以挂载Chips和Connectors对象,也可以什么都不挂载,但如果Buses挂载其他对象,则需要定义它配置的Chips和Connectors。注意:openUBMC规定传入的Buses下必须至少配置一个器件(Connector或Chip)或被传入到下一级连接器
ManagementTopology结构
{
"ManagementTopology": {
"Anchor": {
"Buses": [
]
}
}
}
ManagementTopology样例说明
EXU的Connector对象
{
"Objects":{
"Connector_BCU": {
"Buses": [
"I2c_1",
"I2c_2",
"Hisport_0"
]
}
}
}
BCU的Anchor
{
"Anchor": {
"Buses": [
"I2c_1",
"I2c_2",
"Hisport_0"
]
},
"I2c_1": {
"Chips": [
"Smc_CpuBrdSMC",
"Eeprom_BCU",
],
"Connectors": [
"Connector_Memory"
]
},
"I2C_2": {
"Chips": [
"Pca9545_BCU"
]
},
"Hisport_0": {
"Connectors": [
"Connector_A1a"
]
},
"Pca9545_BCU": {
"Buses": [
"I2cMux_9545Chan1",
"I2cMux_9545Chan2",
"I2cMux_9545Chan3"
]
},
"I2cMux_9545Chan1": {
"Connectors": [
"Connector_PCIe_1"
]
},
"I2cMux_9545Chan2": {
"Connectors": [
"Connector_PCIe_2"
]
},
"I2cMux_9545Chan3": {
"Connectors": [
"Connector_PCIe_3"
]
}
}
解析说明:以图1为例,讲解BCU的硬件管理拓扑关系:
1. EXU的Connector与下一级板卡BCU相连接,EXU的Connector传递下来的Buses总线会按顺序替代BCU管理拓扑Anchor下的Buses,即它传递下来的"I2c_1","I2c_2"和"Hisport_0"会按顺序取代Anchor下的"I2c_1","I2c_2"和"Hisport_0",因为Anchor下的Buses属性只是符号.
2. "I2c_1"总线挂载Chip("Smc_CpuBrdSMC"和"Eeprom_BCU")和Connectors("Connector_Memory")
3. "I2c_2"总线挂载Chip("Pca9545_BCU"),"Pca9545_BCU"是多路复用器,它下面最多可以连接四条总线;其连接的总线需要在ManagementTopology下描述;再者,"Pca9545_BCU"下的总线还可以挂载多个Chip或者Connectors
4. "Hisport_0"总线挂载Connectors("Connector_A1a")
Anchor结构
Anchor对象说明:
选项:Anchor是必选对象类型
Anchor是拓扑结构的入口,
一定包含Buses属性
Anchor中Buses属性只是一个符号,为字符串数组类型,包含0到多个元素,用于描述CSR文件采用的总线类型,它实际会被上一级Connector传递过来的Buses按顺序替代
命名规范:
固定命名
,即在CSR文件中,只能写Anchor
,不能写Anchor_1、Anchor_BCU等Anchor样例说明
EXU的Connector对象
json{ "Objects": { "Connector_BCU": { "Buses": [ "I2c_1", "I2c_2" ] } } }
BCU的Anchor
json{ "Anchor": { "Buses": [ "I2c_1", "I2c_2" ] } }
解析说明:以BCU的Anchor举例,它的上一级是EXU,即EXU -> BCU,它们是通过Connector来连接的,上一级EXU的Connector传递下来的Buses会按顺序替代BCU的Anchor中的Buses属性
Buses结构
Buses对象说明:
- 选项:Buses是可选对象类型,即如果在总线下挂载Chip或Connector,需要在ManagementTopology说明
- Buses类型:Jtag、 JtagOverGpio、 JtagOverLocalBus、 Gpio、 Hisport、 I2c、 Can、LocalBus、 Adc、JtagMux、I2cMux
- 命名规范:
"Type_Name"
,其中Type为有效的总线类型(见第2点),Name为对象名称,不可为空
,例如 "I2c_2" - Buses来源:挂在ManagementTopology下的总线一定来源于Anchor或部分Chip(Pca9544、Pca9545、Pca9548、Smc、JtagSwitch、I2cMux):
- I2cMux对象必须挂在Pca9544、Pca9545、Pca9548或Smc下
- JtagMux对象必须挂在JtagSwitch下
- 除了上面两个对象,其它Bus对象挂在Anchor下
- Buses配置:总线下可配置Chips和Connectors字段:
- 若配置Chips字段,则该字段只能配置有效的Chip对象名称或为空
- 若配置Connectors字段,则该字段只能配置Connector对象名称或为空。
- Buses总线只在BMC芯片/板卡(管理拓扑的root节点)的CSR文件描述,即在root.sr的Objects下描述具体内容,在非root节点的CSR中,Anchor中的Buses只是一种符号标记,不需要在Objects中描述具体内容
注意
同一个I2cMux或JtagMux总线不能挂在两个Chip下
Buses样例说明
- root.sr文件的Buses样例说明
{
"ManagementTopology": {
"Anchor": {
"Buses": [
"I2c_1",
]
},
"I2c_1": {
"Connectors": [
"Connector_EXU_1"
]
}
},
"Objects": {
"I2c_1": {
"Id": 1
}
}
}
- 非root.sr文件的Buses样例说明
{
"I2C_2": {
"Chips": [
"Pca9545_BCU"
]
},
"Pca9545_BCU": {
"Buses": [
"I2cMux_9545Chan1"
]
}
}
Chip结构
选项:Chip是可选对象类型,如果在板卡上存在物理寄存器以及它挂载某条总线上,需要在ManagementTopology说明
Chip类型:Chip、 Eeprom、 Lm75、 Pca9545、 Smc、 Pca9555、 Cpld、 JtagSwitch、CanbusChip、 Pca9544、 Vrd、 Ads78、 CpldRegister等,
这些Chips都是真实的物理寄存器
命名规范:
"Type_Name"
, 其中Type为有效的寄存器类型(见第2点),Name为对象名称,不可为空
,例如"Smc_CpuBoard"Chip来源:CSR定义的Chip对象必须挂在总线下,需要在ManagementTopology中声明该Chip对象挂载在哪个总线下,且在Objects中存在定义
Chip的配置样例
json{ "ManagementTopology": { "I2c_1": { "Chips": [ "Smc_CpuBrdSMC", ] }, "I2C_2": { "Chips": [ "Pca9545_BCU" ] }, "Pca9545_BCU": { "Buses": [ "I2cMux_9545Chan1", ] }, "I2cMux_9545Chan1": { "Connectors": [ "Connector_PCIe_1" ] } }, "Objects": { "Smc_CpuBrdSMC": {}, "Pca9545_BCU": {}, "Connector_PCIe_1": {} } }
特殊说明:
- Pca9544、Pca9545、Pca9548、Smc、JtagSwitch可挂在ManagementTopology下继续配置Buses字段
- Pca9544、Pca9545、Pca9548、Smc的Buses属性可配置多个I2cMux总线,配置的总线对象均需在Objects中定义
- JtagSwitch的Buses属性可以配置JtagMux总线,配置的总线对象均需在Objects中定义
openUBMC规定:所有Chip(Pca9544、Pca9545、Pca9548、JtagSwitch例外)至少须配置一个Accessor或Scanner,或被其它对象引用。(Accessor和Scanner的配置具体参考《板卡适配》)
注意
同一个Chip在某总线的拓扑中最多只能出现一次,且不能同时存在于两个总线的拓扑配置中。
样例说明
{
"ManagementTopology": {
"Anchor": {
"Buses": [
"I2c_1"
]
},
"I2c_1": {
"Chips": [
"Eeprom_BCU"
]
}
},
"Objects": {
"Eeprom_BCU": {},
"SRUpgrade_1": {
"StorageChip": "#/Eeprom_BCU"
}
}
}
Chip类型 | 用途 | 与总线的关联 |
---|---|---|
Eeprom | 用来保存数据,如天池组件CSR信息、网卡MAC地址、FRU信息等 | 只能挂载在I2c和Hisport总线 |
Pca9555 | Pca9555管脚信息转化成可通过总线读取的寄存器信息,总线用来读取单板的Boardid,Pcbid等信息 | 只能挂载在I2c和Hisport总线 |
Pca9545 | 线路拓展器,将1路信号拓展为4路信号 | 只能挂载在I2c和Hisport总线 |
Pca9548 | 线路拓展器,将1路信号拓展为8路信号 | 只能挂载在I2c和Hisport总线 |
Lm75 | 温度传感器 | 可以挂载在I2c和I2cMux等总线 |
Cpld | 可编程逻辑阵列 | - |
Chip_Gpio | - | 只能挂载在Gpio总线 |
更多Chip和Buses相关内容请参考《BMC Studio用户指南》。
Connectors结构
- 选项:Connectors是可选对象类型,如果板卡间通过Connector连接以及它挂载在某条总线上,需要在ManagementTopology说明
- Connector来源:CSR定义的Connector对象必须挂在总线下,需要在ManagementTopology中声明该Connector对象在哪个总线下,且在Objects中存在定义
- 命名规范:
"Type_Name"
,其中Type为Connector(固定命名)
,Name为对象名称,不可为空
,例如"Connector_Memory" - 特殊说明:不同于Buses和Chip,Connector不能在ManagementTopology下继续进行拓扑配置
注意
Connector不能同时存在于两个总线的拓扑配置中
Connector的配置样例
{
"ManagementTopology": {
"I2c_1": {
"Connectors": [
"Connector_Memory"
]
}
},
"Objects": {
"Connector_Memory": {}
}
}
Objects结构
Objects结构
{
"Objects": {
"class1_1": {
"Property1": "ABC",
"Property2": 1,
"Porperty3": 1,
"Porperty4": 96
},
"class2_1": {
"Property1": "#/Class1_1",
"Property2": "Abc${Slot}",
"Porperty3": 2,
"Porperty4": null,
"Property5": "#/Class1_1.Property2"
},
"Class3_1": {
"@Parent": "Class2_1",
"Property1": "<=/Class2_1.Property4",
"Property2": 1,
"Property3": "Xyz${SystemId}",
"Property4": "BMC${ManagerId}",
"Property5": "${ChassisId}",
"Property6": 174,
"@Default": {
"Property1": 20,
}
}
}
}
解析说明:这里举例objects的通用结构,更多详细信息见下面
Objects
:本组件/部件内需要描述的业务对象,如Smc、Scanner、NetworkAdapter等,以近似平铺方式列出所有待管理的对象,每个对象都由对象名及其属性表组成对象的命名规范:
类名_名称/序号
:类名
来源于各个组件(APP)的MDS中定义的数据模型,必须是全局唯一
;硬件自发现组件分发对象时,会根据类名来将其分发到对应的组件名称/序号
无实际含义,只为了确保一个对象在同一个CSR文件下的命名是全局唯一
Objects结构的配置样例
json{ "Objects": { "Smc_CpuBrdSMC": { "Address": 96, "AddrWidth": 1, "OffsetWidth": 1, "WriteTmout": 0, "ReadTmout": 0 } } }
解析说明:当某个对象命名为
Smc_CpuBrdSMC
时:它的类名是Smc,名称是CpuBrdSMC,硬件自发现分发Smc_CpuBrdSMC时,会将其分发到hwproxy组件对象的属性及其属性值的具体配置需要和硬件对齐
对象定义可以使用多种语法,包括变量、同步、默认值、引用、层级、表达式等语法
配置CSR文件时,不强求配置Objects对象所有的属性,若某个属性不配置时,硬件自发现时会优先使用对象对应类的model.json的属性默认值,若在model.json不配置属性默认值,则就会使用该属性值类型的默认值,例如,属性值类型是int时,则默认是0。
Objects对象的属性及其属性值
硬件自发现组件在加载和解析CSR文件时,会对对象的属性进行参数校验,因此,在配置CSR时需要确保对象的属性及其属性值的类型和取值范围正确。
Objects对象下配置的属性(@Default和@Parent除外),均需在对象对应类管理的资源协作接口属性或私有属性中定义,且usage字段要被设置为“CSR”。
Objects对象的属性的配置样例
PCIeCard的MDS配置
json{ "PCIeCard": { "interfaces": { "bmc.kepler.Systems.PCIeDevices.PCIeCard": { "properties": { "Name": { "usage": ["CSR"] } } } }, "properties": { "Protocol": { "usage": ["CSR"], "baseType": "String" } } } }
PCIeCard的CSR文件
json{ "PCIeCard_1": { "Name": "SP670", "Protocol": "SmBus" } }
Objects对象下配置的属性(@Default和@Parent除外)的值类型须和所匹配资源协作接口属性或MDS私有属性类型一致,若属性配置了引用或同步关系,则需追溯判断,允许类型提升。
Objects对象的属性值类型的配置样例
PCIeCard的MDS配置
json{ "PCIeCard": { "properties": { "PcbID": { "usage": ["CSR"], "baseType": "U8" } } } }
Accessor的MDS配置
json{ "Accessor": { "interfaces": { "bmc.kepler.Accessor": { "properties": { "Value": { "usage": [ "CSR" ], "baseType": "U64" } } } } } }
PCIeCard的CSR文件
json{ "Accessor_PcbID": { "Value": 0 }, "PCIeCard_1": { "PcbID": "#/Accessor_PcbID.Value" } }
解析说明:PCIeCard_1对象的PcbID属性引用Accessor_PcbID对象的Value值,所以需要追溯判断Accessor_PcbID对象配置的Value值是不是满足Accessor在MDS配置的Valuse属性值的类型
Objects中定义的对象,其下所配置属性(@Default和@Parent除外)的值范围须和所匹配资源协作接口属性或MDS私有属性定义的一致,若属性配置了引用或同步关系,则需追溯判断,允许类型提升。
Objects对象的属性值范围的配置样例
CoolingConfig的MDS配置
json{ "CoolingConfig": { "properties": { "InitLevelInStartup": { "usage": ["CSR", "PoweroffPer"], "baseType": "U8", "minimum": 0, "maximum": 100, "default": 100, "notAllowNull": true } } } }
CLU的CSR文件
json{ "CoolingConfig_1": { "InitLevelInStartup": 100 } }
解析说明:CoolingConfig_1对象的InitLevelInStartup属性值的配置要满足CoolingConfig的范围[0, 100]
语法
对象定义可以使用多种语法,包括同步、引用、层级和表达式等语法。
名称 | 符号 | 描述 | 类别 |
---|---|---|---|
静态引用语法 | ${} | 加载时直接一次性引用对象属性值,后续不再变化 | ${Slot} 、${SystemId} 、${ManagerId} 、${Container} 、${GroupId} 、${ChassisId} 、${GroupPosition} 、${SilkText} 、${FormatVersion} 和${DataVersion} |
动态引用语法 | #/ | 主动访问其他对象或其属性值,后续被引用对象或其属性值发生变化时,需要引用对象主动去获取 | 分为引用对象和引用对象属性 |
同步引用语法 | <=/ | 同步其他对象的属性值,后续被同步对象属性值发生变化时,会自动将属性值同步给当前对象指定的属性值 | 只有同步对象属性 |
层级关系语法 | @ | - | 分为@Parent和@Default |
表达式语法 | expr() | 在同步和引用语法的基础,增加数学表达式或字符串处理方式 | 数学表达式、字符串处理等 |
静态引用语法--${}
位置: 静态引用存在于CSR对象的属性配置中
格式:
${ctx}
,其中${}
为固定语法,前后可拼接字符串,例如:"CpuBoard_${Slot}"、"CpuBoard ${Slot} BCU"${}
语法:仅支持字符串格式配置,当配置的变量数据类型,与对应属性类型相同,会自动进行数据类型转换类型:
${Slot}
、${SystemId}
、${ManagerId}
、${Container}
、${GroupId}
、${ChassisId}
、${GroupPosition}
、${SilkText}
都支持将上级Connector对象的属性值作为参数,替换下级加载组件的CSR中对象的变量${FormatVersion}
和${DataVersion}
使用保留字段FormatVersion和DataVersion的内容填充
变量语法配置样例
root.sr连接EXU的Connector对象
json{ "Connector_EXU_1": { "SystemId": 1, "ManagerId": "1", } }
EXU.sr的对象
json{ "Connector_BCU_1": { "SystemId": "${SystemId}", "ManagerId": "${ManagerId}", }, "DftCD_1": { "Slot": "${GroupId}" }, "PcieAddrInfo_NIC_5": { "GroupPosition": "PcieAddrInfo_NIC_5_${GroupPosition}" } }
解析说明:
- 当加载EXU.sr文件时,root.sr的"Connector_EXU_1"对象中"SystemId"、"ManagerId"、"GroupId"和"GroupPosition"属性值会一次性传递下来并替代EXU.sr的
${SystemId}
、${ManagerId}
、${GroupId}
和${GroupPosition}
; - 样例中,root.sr配置"Connector_EXU_1"对象的"SystemId"和"ManagerId"属性,没有配置"GroupId"和"GroupPosition"值,它们的值将会采用在MDS配置默认值
${}传递的值是一次性替换,后续不再变化
动态引用语法--#/
- 类别:动态引用语法分为
引用对象语法
和引用属性语法
- 位置: 动态引用存在CSR对象的属性配置中
- 格式:
#/xxx
,其中#/
为固定语法, 如果xxx是定义在Objects中的对象,则是引用对象语法#/object_name
,如果xxx是定义在Objects中对象的某个属性,则是引用属性语法#/object_name.property_name
。 - 若配置为对象的动态引用#/object_name,则object_name不可为该对象本身,若配置为对属性的动态引用#object_name.property_name,则object_name可为其他对象,也可为该对象本身。
- 引用对象:引用对象能够直接访问被引用对象所有接口或指定接口的属性
- 引用属性:引用属性能够直接访问被引用对象中特定属性
- 引用对象和引用属性的区别:
- 引用属性可以引用自身对象的其他属性,但引用对象只能引用其他对象
- 某些属性可以采用引用属性语法,但在特殊场景只能采用引用对象:如Scanner和Accessor对象,它们是对对象进行读写操作,而不是对某个属性进行读写操作
- 在MDS中定义"refInterface"字段,只能配置为引用对象
引用对象语法
类别:引用对象分为引用同一个sr文件的对象和引用其他sr文件的对象(引用其他sr文件对象也称为全局引用对象)
引用同一个sr文件的对象:引用对象和被引用对象,可以归属同一个业务组件,也可以分属不同的业务组件。语法关键字:"
#/
",格式为"#/
object_name引用同一个sr文件的对象配置样例
json{ "Objects": { "Chip_MCU": {}, "RiserCard_1": { "RefMCUChip": "#/Chip_MCU" } } }
解析说明:"RiserCard_1"对象的"RefMCUChip"属性直接访问同个sr文件的"Chip_MCU"寄存器,调用"Chip_MCU"寄存器的对象接口
引用其他sr文件的对象(全局引用对象):仅支持引用root.sr及platform.sr的全局对象,格式为"
#/::
object_name"。引用其他sr文件的对象的配置样例 root.sr文件
json{ "Objects": { "CanbusChip_0": {} } }
EXU.sr文件
json{ "Objects": { "PsuSlot_5": { "PsuChip": "#/::CanbusChip_0" } } }
解析说明:EXU.sr的"PsuSlot_5"对象的"PsuChip"属性直接访问root.sr文件的"CanbusChip_0"对象
支持调用对象接口:CSR对象中的某属性,若其被定义为MDS中的私有属性,且配置了refInterface字段,则在CSR中该属性须配置为动态引用对象,被动态引用的对象对应的类需管理实现了refInterface关联接口的资源协作接口的对象。
支持调用对象接口的配置样例
RiserCard的MDS的私有属性的资源管理
json{ "RiserCard": { "properties": { "RefMCUChip": { "refInterface":"bmc.kepler.Chip.BlockIO" } } } }
RiserCard中该私有属性的配置
json{ "RiserCard_1": { "RefMCUChip": "#/Chip_MCU_2e6" } }
refInterface的bmc.kepler.Chip.BlockIO接口属性
shellNAME TYPE SIGNATURE RESULT/VALUE FLAGS bmc.kepler.Chip.BlockIO interface - - - .BatchWrite method a{ss}a(uay) - - .ComboWriteRead method a{ss}uayuu ay - .PluginRequest method a{ss}ssay ay - .Read method a{ss}uu ay - .Write method a{ss}uay - - .WriteRead method a{ss}ayu - -
具体业务代码
lua-- 由框架解析出来的obj local read_method = obj['RefMCUChip'].read
解析说明:RiserCard_1直接访问Chip_MCU_2e6对象的"bmc.kepler.Chip.BlockIO"接口的属性,在具体业务中能够直接调用这个接口
如果某个属性引用了对象,则该属性在MDS中需要被定义为私有属性,且配置了正确的refInterface字段。特殊场景:
- Accessor和Scanner引用Chip对象不需要在MDS配置refInterface
- 同一组件的对象引用本组件对象不需要在MDS配置refInterface
Scanner引用对象场景的配置样例
Scanner的MDS配置
{
"Scanner": {
"properties": {
"Chip": {
"usage": [
"CSR"
],
"baseType": "String"
}
}
}
}
CSR文件中的Scanner的属性
{
"Scanner_Riser12V0Event": {
"Chip": "#/Pca9555_IO"
}
}
同一组件的对象引用本组件对象的配置样例
DftPca9555的MDS配置
{
"Pca9555": {},
"DftPca9555": {
"properties": {
"RefChip": {
"baseType": "String",
"usage": [
"CSR"
]
}
}
}
}
CSR文件中的DftPca9555属性
{
"DftPca9555_1": {
"RefChip": "#/Pca9555_IEU"
}
}
引用属性语法
类别:引用属性分为引用同一个sr文件中对象的属性和引用其他sr文件中对象的属性(引用其他sr文件中对象的属性也称为全局引用属性)
属性要求:被引用的属性值必须为被引用对象对应的类在MDS中管理的资源协作接口的对象所实现接口的任意属性,若被引用对象为该对象本身,则被引用的属性值还可为该对象所在类管理的私有属性
引用其他对象的属性的配置样例
Accessor的MDS配置
json{ "Accessor": { "interfaces": { "bmc.kepler.Accessor": { "properties": { "Value": {} } } } } }
RiserCard引用Accessor_PcbI的值
json{ "Objects": { "Accessor_PcbID": { "Value": 0 }, "RiserCard_1": { "PcbID": "#/Accessor_PcbID.Value" } } }
解析说明:若引用其他对象的属性,只能引用其他对象挂载在资源协作接口的属性
引用自身对象的其他属性的配置样例 BCU.sr文件
json{ "CPU_2": { "Name": "${Slot} |> expr($1 * 2) |> string.format('CPU%s', $1)", "AssetName": "#/CPU_2.Name" } }
解析说明: 引用属性可以引用自身对象的其他属性
引用全局对象属性:仅支持同步root.sr及platform.sr的全局对象属性,格式为"
#/::
object_name.property_name"。引用全局对象属性的配置样例
root.sr文件
json{ "Objects":{ "CanbusChip_0": { "Address": 5 } } }
EXU.sr文件
json{ "Objects": { "PsuSlot_5": { "SlotI2cAddr": "#/::CanbusChip_0.Address" } } }
解析说明:EXU.sr中的"PsuSlot_5"对象的"SlotI2cAddr"属性直接引用root.sr中的"CanbusChip_0"对象的"Address"属性值
同步对象属性语法
- 同步语法:仅支持同步对象的属性
- 同步属性语法:支持在对象初始化,或被同步对象属性发生变化时,自动将属性值同步给当前对象指定属性
- 位置: 数据同步存在于CSR对象的属性配置
- 格式:
<=/object_name.property_name
,其中<=/
为固定语法,object_name为定义在Objects中的对象,property_name为object_name对象对应的类在MDS中管理的资源协作接口下的任意属性,例如,<=/PCIeDevice.Value
注意
同步的object_name不能是该对象本身,只能是其他对象,属性property_name不能为object_name对象的私有属性,只能是挂载在资源协作接口的属性
同步同一个sr文件的对象属性的配置样例
Fru的MDS配置
{
"Fru": {
"interfaces": {
"bmc.kepler.Systems.Fru": {
"properties": {
"FruId": {}
}
}
}
}
}
IEU.sr文件
{
"Fru_IEU": {
"FruId": 1
},
"RiserCard_1": {
"FruID": "<=/Fru_IEU.FruId"
}
}
解析说明:IEU.sr中的"RiserCard_1"对象的"FruID"数值同步Fru_IEU对象的FruId属性值时,需要确保Fru_IEU对象的FruId是挂载资源协作接口的属性
同步全局对象属性:仅支持同步root.sr及platform.sr的全局对象属性,格式为"
<=/::
object_name.property_name"。同步全局对象属性的配置样例
FruCtrl的MDS配置
json{ "FruCtrl": { "bmc.kepler.Systems.FruCtrl": { "properties": { "PowerState": {} } } } }
platform.sr文件
json{ "FruCtrl_1_0": { "PowerState": 0, } }
IEU.sr文件
json{ "Scanner_Riser3V3Event": { "ScanEnabled": "<=/::FruCtrl_1_0.PowerState" } }
解析说明:IEU.sr的"Scanner_Riser3V3Event"对象的"ScanEnabled"属性值同步platform.sr文件的FruCtrl_1_0对象的PowerState值
同步对象属性配置默认值
- 如果同步对象属性配置默认值,当对象初始化未获取到被同步对象属性时,将设置属性值为配置的默认值,语法关键字:
@Default
,格式为"@Default": {}
,可以在列表中配置多个同步对象属性的默认值。(@Default具体语法参考层级关系语法--@Default部分) - 对象初始属性值根据MDS定义,优先级由高到低依次为
对象持久化属性值、对象定义属性默认值(仅同步对象属性场景有效)、对象定义属性值、类定义属性默认值、数据类型默认值
。
同步对象属性配置默认值的配置样例
- "@Default"配置单个同步对象属性的默认值
json{ "NetworkAdapter_1": { "PCBVersion": "<=/PCIeCard_1.PcbVersion", "@Default": { "PCBVersion": ".A" } } }
解析说明:当"NetworkAdapter_1"对象初始化时,未能从NetworkAdapter_1的持久化中获取的"PCBVersion"属性值,且未能获取到同步对象PCIeCard_1的PcbVersion属性值,那它将会使用的CSR文件配置的"@Default"的"PCBVersion"属性值。
- "@Default"配置多个同步对象属性的默认值
json{ "ThresholdSensor_STBY5V0": { "Reading": "<=/Scanner_ECUSys5V2.Value |> expr($1 / 27.3) |> expr(($1 > 255 || $1 == 0) ? 100 : $1)", "ReadingStatus": "<=/Scanner_ECUSys5V2.Status", "@Default": { "Reading": 100, "ReadingStatus": 2 } } }
- 如果同步对象属性配置默认值,当对象初始化未获取到被同步对象属性时,将设置属性值为配置的默认值,语法关键字:
层级关系语法--@
类别:层级关系语法分为@Parent、@Default
@Parent
- 表示对象之间有上下级关系,并非继承关系
- 格式:
"@Parent": "
object_name"
- CSR对象中若存在@Parent属性,则该属性值一定为同一个CSR文件的其他Objects对象,这两对象对应的类在MDS中的定义也存在Parent关系。
- 作用:确定该对象在资源协作接口中挂载哪个对象下面的
层级关系语法配置样例
NetworkAdapter的MDS配置
{
"NetworkAdapter":{
"path": "/bmc/kepler/Systems/:SystemID/NetworkAdapters/:ID"
},
"NetworkPort": {
"parent": "NetworkAdapter",
"path": ":parent/Ports/:ID"
}
}
PCIeCard.sr文件
{
"NetworkAdapter_1":{},
"NetworkPort_0": {
"@Parent": "NetworkAdapter_1",
},
"NetworkAdapter_2":{},
"NetworkPort_1": {
"@Parent": "NetworkAdapter_2",
}
}
资源协作接口的显示
/bmc/kepler/Systems/1/NetworkAdapters
│ ├─/bmc/kepler/Systems/1/NetworkAdapters/NetworkAdapter_1_010106
│ │ └─/bmc/kepler/Systems/1/NetworkAdapters/NetworkAdapter_1_010106/Ports
│ │ ├─/bmc/kepler/Systems/1/NetworkAdapters/NetworkAdapter_1_010106/Ports/NetworkPort_0_010106
│ ├─/bmc/kepler/Systems/1/NetworkAdapters/NetworkAdapter_2_010106
│ │ └─/bmc/kepler/Systems/1/NetworkAdapters/NetworkAdapter_2_010106/Ports
│ │ ├─/bmc/kepler/Systems/1/NetworkAdapters/NetworkAdapter_2_010106/Ports/NetworkPort_1_010106
解析说明:在PCIeCard.sr中配置"NetworkPort_0"和"NetworkAdapter_1"存在Parent关系,则在它们对应的MDS中也定义Parent关系,这就意味着NetworkPort_0是挂在NetworkAdapter_1对象下面的。以此类推,NetworkPort_1是挂在NetworkAdapter_2对象下面的等
@Default
- @Default表示此对象使用了同步语法的属性的默认值,即当同步源不存在时或首次同步失败时,使用该属性的默认取值
- CSR对象中若存在属性配置了同步语法,或配置的表达式中包含同步语法,则该属性可在该CSR对象的@Default字段的同名属性下配置默认值,默认值的类型需和该属性定义类型一致,默认值的取值范围为该属性所约束的取值范围,默认值不可配置为动态引用、静态引用和数据同步语法。(具体样例说明见同步对象属性语法)
表达式语法
- 表达式语法:在
同步语法(<=/)和引用语法(#/)的基础上,增加表达式语法
,支持字符串处理和数学计算 - 范围:允许对多个同步对象属性或单个引用对象属性进行表达式计算,并将最终计算结果赋值给对应属性
支持多个同步对象属性的原因:属性同步(
<=/
)是一种弱依赖,可以通过分号扩展成多个同步源多个同步对象属性的配置样例
json{ "Scanner_12v2": { "Status": 0, "Value": 0 }, "Scanner_PowerGood": { "Value": 0 }, "ThresholdSensor_Bcu12v2": { "ReadingStatus": "<=/Scanner_12v2.Status;<=/Scanner_12v2.Value;<=/Scanner_PowerGood.Value |> expr((($1 == 0) && (($2 / 12) > 255 || $2 == 0) && ($3 == 1)) ? 2 : $1)" } }
解析说明:
a. 首先同步Scanner_12v2对象的"Status"属性值0和"Value"属性值0,和同步Scanner_PowerGood对象的"Value"属性值0,并将它们分别赋予$1, $2和$3值,即$1=0, $2=0和$3=0
b. 层层剖析表达式:令x = (($1 == 0) && (($2 / 12) > 255 || $2 == 0) && ($3 == 1)), 然后进行三目运算x ? 2: 0
c. 判断x是True还是False:因为$2 = 0,所以($2 / 12) > 255 || $2 == 0)返回是True;因为$3 = 0,所以($3 == 1)返回是False,最终(($2 / 12) > 255 || $2 == 0) && ($3 == 1))返回是False;因为$1 = 0,所以($1 == 0)返回True,最终x返回False
d. "ReadingStatus"的值是0
支持单个引用对象属性的原因:属性引用(#/)是一种强依赖,不支持指定多个引用源
单个引用对象属性的配置样例
json{ "Scanner_3v1": { "Value": 0 }, "Event_CpuBoard3V1_LowerVoltage": { "DescArg1": "#/Scanner_3v1.Value |> expr($1 == 32767 ? 3.3 : (($1 / 20) * 3.3 * 1.5 * 20 / 4096)) |> string.format('%0.3f', $1)" } }
解析说明:
a. 引用Scanner_3v1对象的Value值,将其传递到第一个管道的表达式($1 == 32767 ? 3.3 : (($1 / 20) * 3.3 * 1.5 * 20 / 4096))中的$1,即$1 = 0
b. 进行表达式运算:$1 != 32767,所以($1 == 32767 ? 3.3 : (($1 / 20) * 3.3 * 1.5 * 20 / 4096))取(($1 / 20) * 3.3 * 1.5 * 20 / 4096)的结果0
c. 将第一个管道的值0赋值给第二个管道的字符串string.format('%0.3f', $1)的$1,即$1 = 0,所以string.format('%0.3f', $1)输出结果是"0.000"
同步对象属性的个数约束:多个同步源仅限于有表达式处理的场景,且最多10个,且只能被第一个表达式接收,后续的表达式接收的入参只能是上一个表达式的结果
- 组成:由入参和管道
(|>)
组成- 入参:使用$1,$2…表示从管道连接符左侧传递过来的入参,以及表达式语句中的占位符,入参个数最多10个
- 管道:使用管道连接符(|>)表示同步值/引用值作为后续表达式的输入,管道连接符支持多级,每一级表达式的结果是下一级的入参,但管道层级最多只能支持10层
- 类型:数学计算和字符串处理
- 字符串处理
string.*()
:字符串相关操作,当前支持的方法有format
、sub
、gsub
、upper
、lower
等。
string.format(格式化) string.format的配置样例 EXU.sr
json{ "Connector_BCU_1": { "Slot": 1 } }
BCU.sr
json{ "CPU_1": { "DeviceLocator": "${Slot} |> expr($1 * 2 - 1) |> string.format('CPU%s', $1)" } }
解析说明:
a. BCU.sr使用上一级Connector_BCU_1连接器对象传递下来的Slot属性值替换
{Slot} = 1; b. ${Slot} = 1替代在第一个管道|>的右侧表达式expr($1 * 2 - 1)中的$1,然后进行表达式运算:1*2-1 = 1
c. 第一个表达式计算的结果1是第二个管道|>的入参,即结果1替代第二个管道右侧表达式string.format('CPU%s', $1)中的$1,然后进行字符串格式化处理,输出"CPU1"
string.upper(转大写)
string.lower(转小写)
string.gsub(取子串、去除空格等)
string.sub(取子串)
string.sub的配置样例
json{ "RiserCard_1":{ "MCUVersion": "1.00" }, "Chip_MCU1": { "DrvWriteDelay": "<=/RiserCard_1.MCUVersion |> string.sub($1, 1, 4) |> expr($1 >= '1.12' ? 0 : 1)" } }
解析说明:
a. 首先将同步的RiserCard_1对象的MCUVersion属性值"1.00",将其传递到第一个管道string.sub($1, 1, 4)中的$1,然后对$1="1.00"进行取第1字符到第4字符的子串,也就是"1.00"
b. 将第一个表达式取子串"1.00"的结果传递到第二个管道的表达式expr($1 >= '1.12' ? 0 : 1)中的$1,然后进行三目表达式判断:因为"1.00" < "1.12",所以最终输出1,即"DrvWriteDelay"是1