硬件自描述文件(CSR)
更新时间:2024/12/19
在Gitcode上查看源码

简要介绍

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部分数据:FormatVersionUnitDataVersionManagementTopologyObjectsFormatVersionDataVersion由主版本号和次版本号组成,主版本号范围1~99;次版本号范围0~99,不足两位补0,具体样式为"A.BC"的非空字符串

CSR整体结构样例

json
{
    "FormatVersion": "3.00",
    "DataVersion": "1.00",
    "Unit": {
        "Type": ,
        "Name":
    },
    "ManagementTopology": {},
    "Objects": {}
}
  1. FormatVersion

    • 定义:CSR数据格式及整体结构, 由openUBMC统一维护,可能会存在断代情况
    • 选项:必填字段
    • 格式:"主版本号.次版本号",主版本号范围1~99;次版本号范围0~99,不足两位补0
    • 注意事项:硬件自发现会校验和解析FormatVersion的值,需要配置准确
  2. DataVersion

    • 定义:跟随CSR数据内容变化而变化,即增加或修改数据时,需要变更数据版本
    • 选项:必填字段
    • 格式:"主版本号.次版本号",主版本号范围1~99;次版本号范围0~99,不足两位补0
    • 注意事项:硬件自发现会校验和解析DataVersion的值,需要配置准确
  3. Unit

    • 定义:描述CSR文件的类型和名称
    • Type:描述CSR所属的板卡类型,如EXU、BCU和IEU等
    • Name:描述CSR文件的名称,即其主要是描述哪个对象

ManagementTopology结构

ManagementTopology作为管理拓扑的关键字,解析时默认认为这下面的都是对Objects下面对象的引用,按照树结构根节点开始,以层序遍历的方式平铺列出Bus/Chip/Connector的连接关系

  • ManagementTopology只能包含AnchorBusesChipsConnectors的层级关系;Anchor是必选对象类型且它一定包含Buses属性,Buses、Chips和Connectors是可选字段,且不能包含其他对象
  • ManagementTopology主要描述CSR文件中链路逻辑关系,需要对照设计的硬件链路来配置。
  • Anchor是上一级Connector传递链路的入口,是和上级板卡连接的桥梁。
  • 传入的Buses上可以挂载Chips和Connectors对象,也可以什么都不挂载,但如果Buses挂载其他对象,则需要定义它配置的Chips和Connectors。注意:openUBMC规定传入的Buses下必须至少配置一个器件(Connector或Chip)或被传入到下一级连接器

ManagementTopology结构

json
{
    "ManagementTopology": {
        "Anchor": {
            "Buses": [

            ]
        }
    }
}

ManagementTopology样例说明

EXU的Connector对象

json
{
    "Objects":{
        "Connector_BCU": {
            "Buses": [
                "I2c_1",
                "I2c_2",
                "Hisport_0"
            ]
        }
    } 
}

BCU的Anchor

json
{
    "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对象说明:

  1. 选项:Anchor是必选对象类型

  2. Anchor是拓扑结构的入口,一定包含Buses属性

  3. Anchor中Buses属性只是一个符号,为字符串数组类型,包含0到多个元素,用于描述CSR文件采用的总线类型,它实际会被上一级Connector传递过来的Buses按顺序替代

  4. 命名规范:固定命名,即在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对象说明:

  1. 选项:Buses是可选对象类型,即如果在总线下挂载Chip或Connector,需要在ManagementTopology说明
  2. Buses类型:Jtag、 JtagOverGpio、 JtagOverLocalBus、 Gpio、 Hisport、 I2c、 Can、LocalBus、 Adc、JtagMux、I2cMux
  3. 命名规范:"Type_Name",其中Type为有效的总线类型(见第2点),Name为对象名称,不可为空,例如 "I2c_2"
  4. Buses来源:挂在ManagementTopology下的总线一定来源于Anchor或部分Chip(Pca9544、Pca9545、Pca9548、Smc、JtagSwitch、I2cMux):
    • I2cMux对象必须挂在Pca9544、Pca9545、Pca9548或Smc下
    • JtagMux对象必须挂在JtagSwitch下
    • 除了上面两个对象,其它Bus对象挂在Anchor下
  5. Buses配置:总线下可配置Chips和Connectors字段:
    • 若配置Chips字段,则该字段只能配置有效的Chip对象名称或为空
    • 若配置Connectors字段,则该字段只能配置Connector对象名称或为空。
  6. Buses总线只在BMC芯片/板卡(管理拓扑的root节点)的CSR文件描述,即在root.sr的Objects下描述具体内容,在非root节点的CSR中,Anchor中的Buses只是一种符号标记,不需要在Objects中描述具体内容

注意
同一个I2cMux或JtagMux总线不能挂在两个Chip下

Buses样例说明

  1. root.sr文件的Buses样例说明
json
{
    "ManagementTopology": {
        "Anchor": {
            "Buses": [
                "I2c_1",
            ]
        },
        "I2c_1": {
            "Connectors": [
                "Connector_EXU_1"
            ]
        }
    },
    "Objects": {
        "I2c_1": {
            "Id": 1
        }
    }
}
  1. 非root.sr文件的Buses样例说明
json
{
    "I2C_2": {
        "Chips": [
            "Pca9545_BCU"
        ]
    },
    "Pca9545_BCU": {
        "Buses": [
            "I2cMux_9545Chan1"
        ]
    }
}

Chip结构

  1. 选项:Chip是可选对象类型,如果在板卡上存在物理寄存器以及它挂载某条总线上,需要在ManagementTopology说明

  2. Chip类型:Chip、 Eeprom、 Lm75、 Pca9545、 Smc、 Pca9555、 Cpld、 JtagSwitch、CanbusChip、 Pca9544、 Vrd、 Ads78、 CpldRegister等,这些Chips都是真实的物理寄存器

  3. 命名规范:"Type_Name", 其中Type为有效的寄存器类型(见第2点),Name为对象名称,不可为空,例如"Smc_CpuBoard"

  4. 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": {}
        }
    }
  5. 特殊说明:

    • Pca9544、Pca9545、Pca9548、Smc、JtagSwitch可挂在ManagementTopology下继续配置Buses字段
    • Pca9544、Pca9545、Pca9548、Smc的Buses属性可配置多个I2cMux总线,配置的总线对象均需在Objects中定义
    • JtagSwitch的Buses属性可以配置JtagMux总线,配置的总线对象均需在Objects中定义
  6. openUBMC规定:所有Chip(Pca9544、Pca9545、Pca9548、JtagSwitch例外)至少须配置一个Accessor或Scanner,或被其它对象引用。(Accessor和Scanner的配置具体参考《板卡适配》

注意
同一个Chip在某总线的拓扑中最多只能出现一次,且不能同时存在于两个总线的拓扑配置中。

样例说明

json
{
    "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总线
Pca9555Pca9555管脚信息转化成可通过总线读取的寄存器信息,总线用来读取单板的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结构

  1. 选项:Connectors是可选对象类型,如果板卡间通过Connector连接以及它挂载在某条总线上,需要在ManagementTopology说明
  2. Connector来源:CSR定义的Connector对象必须挂在总线下,需要在ManagementTopology中声明该Connector对象在哪个总线下,且在Objects中存在定义
  3. 命名规范:"Type_Name",其中Type为Connector(固定命名),Name为对象名称,不可为空,例如"Connector_Memory"
  4. 特殊说明:不同于Buses和Chip,Connector不能在ManagementTopology下继续进行拓扑配置

注意
Connector不能同时存在于两个总线的拓扑配置中

Connector的配置样例

json
{
    "ManagementTopology": {
        "I2c_1": {
            "Connectors": [
                "Connector_Memory"
            ]
        }
    },
    "Objects": {
        "Connector_Memory": {}
    }
}

Objects结构

Objects结构

json
{
    "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的通用结构,更多详细信息见下面

  1. Objects:本组件/部件内需要描述的业务对象,如Smc、Scanner、NetworkAdapter等,以近似平铺方式列出所有待管理的对象,每个对象都由对象名及其属性表组成

  2. 对象的命名规范:类名_名称/序号

    • 类名来源于各个组件(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组件

  3. 对象的属性及其属性值的具体配置需要和硬件对齐

  4. 对象定义可以使用多种语法,包括变量、同步、默认值、引用、层级、表达式等语法

  5. 配置CSR文件时,不强求配置Objects对象所有的属性,若某个属性不配置时,硬件自发现时会优先使用对象对应类的model.json的属性默认值,若在model.json不配置属性默认值,则就会使用该属性值类型的默认值,例如,属性值类型是int时,则默认是0。

Objects对象的属性及其属性值

硬件自发现组件在加载和解析CSR文件时,会对对象的属性进行参数校验,因此,在配置CSR时需要确保对象的属性及其属性值的类型和取值范围正确。

  1. 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"
        }
    }
  2. 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属性值的类型

  3. 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()在同步和引用语法的基础,增加数学表达式或字符串处理方式数学表达式、字符串处理等

静态引用语法--${}

  1. 位置: 静态引用存在于CSR对象的属性配置中

  2. 格式:${ctx},其中${}为固定语法,前后可拼接字符串,例如:"CpuBoard_${Slot}"、"CpuBoard ${Slot} BCU"

  3. ${}语法:仅支持字符串格式配置,当配置的变量数据类型,与对应属性类型相同,会自动进行数据类型转换

  4. 类型:

    • ${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}"
        }
    }

    解析说明:

    1. 当加载EXU.sr文件时,root.sr的"Connector_EXU_1"对象中"SystemId"、"ManagerId"、"GroupId"和"GroupPosition"属性值会一次性传递下来并替代EXU.sr的${SystemId}${ManagerId}${GroupId}${GroupPosition}
    2. 样例中,root.sr配置"Connector_EXU_1"对象的"SystemId"和"ManagerId"属性,没有配置"GroupId"和"GroupPosition"值,它们的值将会采用在MDS配置默认值
  5. ${}传递的值是一次性替换,后续不再变化

动态引用语法--#/

  1. 类别:动态引用语法分为引用对象语法引用属性语法
  2. 位置: 动态引用存在CSR对象的属性配置中
  3. 格式:#/xxx,其中#/为固定语法, 如果xxx是定义在Objects中的对象,则是引用对象语法#/object_name,如果xxx是定义在Objects中对象的某个属性,则是引用属性语法#/object_name.property_name
  4. 若配置为对象的动态引用#/object_name,则object_name不可为该对象本身,若配置为对属性的动态引用#object_name.property_name,则object_name可为其他对象,也可为该对象本身
  5. 引用对象:引用对象能够直接访问被引用对象所有接口或指定接口的属性
  6. 引用属性:引用属性能够直接访问被引用对象中特定属性
  7. 引用对象和引用属性的区别:
    • 引用属性可以引用自身对象的其他属性,但引用对象只能引用其他对象
    • 某些属性可以采用引用属性语法,但在特殊场景只能采用引用对象:如Scanner和Accessor对象,它们是对对象进行读写操作,而不是对某个属性进行读写操作
    • 在MDS中定义"refInterface"字段,只能配置为引用对象

引用对象语法

  1. 类别:引用对象分为引用同一个sr文件的对象和引用其他sr文件的对象(引用其他sr文件对象也称为全局引用对象)

  2. 引用同一个sr文件的对象:引用对象和被引用对象,可以归属同一个业务组件,也可以分属不同的业务组件。语法关键字:"#/",格式为"#/object_name

    引用同一个sr文件的对象配置样例

    json
    {
        "Objects": {
            "Chip_MCU": {},
            "RiserCard_1": {
                "RefMCUChip": "#/Chip_MCU"
            }
        }
    }

    解析说明:"RiserCard_1"对象的"RefMCUChip"属性直接访问同个sr文件的"Chip_MCU"寄存器,调用"Chip_MCU"寄存器的对象接口

  3. 引用其他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"对象

  4. 支持调用对象接口: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接口属性

    shell
    NAME                        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"接口的属性,在具体业务中能够直接调用这个接口

  5. 如果某个属性引用了对象,则该属性在MDS中需要被定义为私有属性,且配置了正确的refInterface字段。特殊场景:

    • Accessor和Scanner引用Chip对象不需要在MDS配置refInterface
    • 同一组件的对象引用本组件对象不需要在MDS配置refInterface

Scanner引用对象场景的配置样例

Scanner的MDS配置

json
{
    "Scanner": {
        "properties": {
            "Chip": {
                "usage": [
                    "CSR"
                ],
                "baseType": "String"
            }
        }
    }
}

CSR文件中的Scanner的属性

json
{
    "Scanner_Riser12V0Event": {
        "Chip": "#/Pca9555_IO"
    }
}

同一组件的对象引用本组件对象的配置样例

DftPca9555的MDS配置

json
{
    "Pca9555": {},
    "DftPca9555": {
        "properties": {
            "RefChip": {
                "baseType": "String",
                "usage": [
                    "CSR"
                ]
            }
        }
    }
}

CSR文件中的DftPca9555属性

json
{
    "DftPca9555_1": {
        "RefChip": "#/Pca9555_IEU"
    }
}

引用属性语法

  1. 类别:引用属性分为引用同一个sr文件中对象的属性和引用其他sr文件中对象的属性(引用其他sr文件中对象的属性也称为全局引用属性)

  2. 属性要求:被引用的属性值必须为被引用对象对应的类在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"
        }
    }

    解析说明: 引用属性可以引用自身对象的其他属性

  3. 引用全局对象属性:仅支持同步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"属性值

同步对象属性语法

  1. 同步语法:仅支持同步对象的属性
  2. 同步属性语法:支持在对象初始化,或被同步对象属性发生变化时,自动将属性值同步给当前对象指定属性
  3. 位置: 数据同步存在于CSR对象的属性配置
  4. 格式:<=/object_name.property_name,其中<=/为固定语法,object_name为定义在Objects中的对象,property_name为object_name对象对应的类在MDS中管理的资源协作接口下的任意属性,例如,<=/PCIeDevice.Value

注意
同步的object_name不能是该对象本身,只能是其他对象,属性property_name不能为object_name对象的私有属性,只能是挂载在资源协作接口的属性

同步同一个sr文件的对象属性的配置样例

Fru的MDS配置

json
{
    "Fru": {
        "interfaces": {
            "bmc.kepler.Systems.Fru": {
                    "properties": {
                    "FruId": {}
                }
            }
        }
    }
}

IEU.sr文件

json
{
    "Fru_IEU": {
        "FruId": 1
    },
    "RiserCard_1": {
        "FruID": "<=/Fru_IEU.FruId"
    }
}

解析说明:IEU.sr中的"RiserCard_1"对象的"FruID"数值同步Fru_IEU对象的FruId属性值时,需要确保Fru_IEU对象的FruId是挂载资源协作接口的属性

  1. 同步全局对象属性仅支持同步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值

  2. 同步对象属性配置默认值

    • 如果同步对象属性配置默认值,当对象初始化未获取到被同步对象属性时,将设置属性值为配置的默认值,语法关键字:@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

  1. 表示对象之间有上下级关系,并非继承关系
  2. 格式:"@Parent": "object_name"
  3. CSR对象中若存在@Parent属性,则该属性值一定为同一个CSR文件的其他Objects对象,这两对象对应的类在MDS中的定义也存在Parent关系。
  4. 作用:确定该对象在资源协作接口中挂载哪个对象下面的

层级关系语法配置样例

NetworkAdapter的MDS配置

json
{
    "NetworkAdapter":{
        "path": "/bmc/kepler/Systems/:SystemID/NetworkAdapters/:ID"
    },
    "NetworkPort": {
        "parent": "NetworkAdapter",
        "path": ":parent/Ports/:ID"
    }
}

PCIeCard.sr文件

json
{
    "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

  1. @Default表示此对象使用了同步语法的属性的默认值,即当同步源不存在时或首次同步失败时,使用该属性的默认取值
  2. CSR对象中若存在属性配置了同步语法,或配置的表达式中包含同步语法,则该属性可在该CSR对象的@Default字段的同名属性下配置默认值,默认值的类型需和该属性定义类型一致,默认值的取值范围为该属性所约束的取值范围,默认值不可配置为动态引用、静态引用和数据同步语法。(具体样例说明见同步对象属性语法

表达式语法

  1. 表达式语法:在同步语法(<=/)和引用语法(#/)的基础上,增加表达式语法,支持字符串处理和数学计算
  2. 范围:允许对多个同步对象属性单个引用对象属性进行表达式计算,并将最终计算结果赋值给对应属性
  • 支持多个同步对象属性的原因:属性同步(<=/)是一种弱依赖,可以通过分号扩展成多个同步源

    多个同步对象属性的配置样例

    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. 组成:由入参和管道(|>)组成
    • 入参:使用$1,$2…表示从管道连接符左侧传递过来的入参,以及表达式语句中的占位符,入参个数最多10个
    • 管道:使用管道连接符(|>)表示同步值/引用值作为后续表达式的输入,管道连接符支持多级,每一级表达式的结果是下一级的入参,但管道层级最多只能支持10层
  2. 类型:数学计算和字符串处理
  3. 字符串处理string.*():字符串相关操作,当前支持的方法有formatsubgsubupperlower等。
  • 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{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