在之前的教学中我们学习了如何新增组件和为组件新增ipmi命令,接下来我们来学习一下如何在组件中增加eeprom的读写。
为Hello_openUBMC组件新增资源对象定义
在mds/model.json中增加以下json配置,并为私有属性配置refInterface字段关联到资源协作接口
"MyEepromModel": {
"path": "/bmc/kepler/MyEepromModel/${id}",
"interfaces": {
"bmc.kepler.OpenUBMC.WriteReading": {
"properties": {
"Manufacture":
{
"baseType": "String",
"default": "Huawei"
}
}
}
},
"properties": {
"RefEepromTestChip":
{
"usage": [
"CSR"
],
"baseType": "U8[]",
"refInterface": "bmc.kepler.Chip.BlockIO"
}
}
}
在mds/service.json中增加依赖
"required": [
{
"path": "*",
"interface": "bmc.kepler.Chip.BlockIO",
"properties": {}
}
]
在mds/ipmi.json中增加eeprom读写的ipmi命令定义
"EepromReadCmd": {
"netfn": "0x00",
"cmd": "0x00",
"priority": "Default",
"role": "Administrator",
"privilege": ["UserMgmt"],
"sysLockedPolicy": "Forbidden",
"req": [
{
"data": "SubCmd",
"baseType": "U8",
"len": "1B",
"value": "0x02"
},
{
"data": "DataLen",
"baseType": "U8",
"len": "1B"
},
{
"data": "Data",
"baseType": "String",
"len": "*"
}
],
"rsp": [
{
"data": "CompletionCode",
"baseType": "U8",
"len": "1B"
},
{
"data": "ManufactureId",
"baseType": "U32",
"len": "3B",
"customizedRule": "Manufacturer"
},
{
"data": "ReadValue",
"baseType": "U8",
"len": "1B"
}
]
},
"EepromWriteCmd": {
"netfn": "0x00",
"cmd": "0x00",
"priority": "Default",
"role": "Administrator",
"privilege": ["UserMgmt"],
"sysLockedPolicy": "Forbidden",
"req": [
{
"data": "SubCmd",
"baseType": "U8",
"len": "1B",
"value": "0x03"
},
{
"data": "DataLen",
"baseType": "U8",
"len": "1B"
},
{
"data": "Data",
"baseType": "U8",
"len": "1B"
}
],
"rsp": [
{
"data": "CompletionCode",
"baseType": "U8",
"len": "1B"
},
{
"data": "ManufactureId",
"baseType": "U32",
"len": "3B",
"customizedRule": "Manufacturer"
}
]
}
在mdb_interface组件仓新增对象定义文件
新增 json/path/mdb/bmc/kepler/MyEepromModel/MyEepromModel.json 对象定义文件
{
"MyEepromModel": {
"path": "/bmc/kepler/MyEepromModel/${id}",
"interfaces": [
"bmc.kepler.OpenUBMC.WriteReading"
]
}
}
新增json/intf/mdb/bmc/kepler/OpenUBMC/WriteReading.json接口定义文件
{
"bmc.kepler.OpenUBMC.WriteReading": {
"properties": {
"Manufacture":
{
"baseType": "String",
"description": "厂商名称"
}
}
}
}
mdb_interface组件构建出包
bingo build
在Hello_openUBMC组件仓自动生成代码
bingo gen
在src/lualib/Hello_openUBMC_app.lua代码中,增加回调函数获取MyEepromModel对象信息,增加ipmi读写命令处理
local class = require 'mc.class'
local service = require 'Hello_openUBMC.service'
local logging = require 'mc.logging'
local custom_msg = require 'messages.custom'
local ipmi_cmds = require 'Hello_openUBMC.ipmi.ipmi'
local object_manage = require 'mc.mdb.object_manage'
local c_object = require 'mc.orm.object'
local context = require 'mc.context'
local mdb = require 'mc.mdb'
local mc_admin = require 'mc.mc_admin'
local client = require 'Hello_openUBMC.client'
local Hello_openUBMC = class(service)
function Hello_openUBMC:ctor()
end
-- 依赖检查
function Hello_openUBMC:check_dependencies()
logging:notice("check dependencies start")
local admin = mc_admin.new()
admin:parse_dependency(APP_WORKING_DIRECTORY .. '/mds/service.json')
admin:check_dependency(self.bus)
end
function Hello_openUBMC:init()
logging:notice("Hello_openUBMC: init start - add accessor")
self.super.init(self)
-- 依赖检查
self:check_dependencies()
self.hello_openUBMC = self:CreateHelloOpenUBMC(1, function(object)
object.ObjectName = "HelloOpenUBMC_1"
object.WelcometoOpenUBMC = "Welcome to openUBMC"
object.Health = 1
end)
-- 注册所有ipmi命令
self:register_ipmi_cmd(ipmi_cmds.FirstIpmiCmd, self.first_ipmi_cmd)
self:register_ipmi_cmd(ipmi_cmds.EepromReadCmd, function(req, ctx, ...)
return self:eeprom_read_cmd(req, ctx)
end)
self:register_ipmi_cmd(ipmi_cmds.EepromWriteCmd, function(req, ctx, ...)
return self:eeprom_write_cmd(req, ctx)
end)
-- 新增mds方法回调
self:register_mds_callback()
logging:notice("MyEepromModel run start")
logging:notice("Hello_openUBMC: init end")
end
-- ipmi读写命令处理
function Hello_openUBMC:eeprom_read_cmd(req, ctx)
logging:notice("Hello_openUBMC: ipmi eeprom_read_cmd")
-- 参数校验(按需)
local data_len = req.DataLen
local data = req.Data
-- if #data ~= data_len then
-- logging:error('eeprom_read_cmd error: invalid req length')
-- error(custom_msg.IPMIRequestLengthInvalid())
-- end
-- 业务处理
-- 构造响应体
local rsp = ipmi_cmds.EepromReadCmd.rsp.new()
rsp.CompletionCode = 0x00
rsp.ManufactureId = 0x010203
local buffer = self.eeprommodel.RefEepromTestChip:Read(context.get_context_or_default(), 188, 1)
logging:notice("Hello_openUBMC: read eeprom type: %s", type(buffer))
rsp.ReadValue = string.byte(buffer, 1)
logging:notice("Hello_openUBMC: ipmi eeprom_read_cmd end")
logging:operation(ctx, 'Hello_openUBMC', 'eeprom_read_cmd success, Data:%s', data)
return rsp
end
function Hello_openUBMC:eeprom_write_cmd(req, ctx)
logging:notice("Hello_openUBMC: ipmi eeprom_write_cmd")
-- 参数校验(按需)
local data_len = req.DataLen
local data = req.Data
-- if #data ~= data_len then
-- logging:error('eeprom_write_cmd error: invalid req length')
-- error(custom_msg.IPMIRequestLengthInvalid())
-- end
-- 业务处理
-- 构造响应体
local rsp = ipmi_cmds.EepromWriteCmd.rsp.new()
local table = {}
table[1] = data
self.eeprommodel.RefEepromTestChip:Write(context.get_context_or_default(), 188, table)
rsp.CompletionCode = 0x00
rsp.ManufactureId = 0x010203
logging:operation(ctx, 'Hello_openUBMC', 'eeprom_read_cmd success, Data:%s', data)
return rsp
end
-- 回调函数获取MyEepromModel对象信息
function Hello_openUBMC:register_mds_callback()
object_manage.on_add_object(self.bus, function(class_name, object, position)
if class_name =='MyEepromModel' then
self.eeprommodel = object
end
end)
object_manage.on_add_object_complete(self.bus, function(position)
end)
object_manage.on_delete_object(self.bus, function(class_name, object, position)
if self.eeprommodel == object then
self.eeprommodel = nil
end
end)
object_manage.on_delete_object_complete(self.bus, function(position)
end)
end
Hello_openUBMC组件构建出包
bingo build
在硬件拓扑中增加eeprom器件,具体可以参考
拉取vpd组件仓
git clone git@gitcode.com:openUBMC/vpd.git
打开服务机型(vendor/Huawei/Server/Kunpeng/openUBMC)的root.sr,硬件拓扑链路中声明一个eeprom器件
"ManagementTopology": {
...
"I2c_8": {
"Chip": [
"Eeprom_DemoEeprom_1"
]
}
...
}
在与ManagementTopology同级的objects下面定义eeprom器件的具体信息,并将Hello_openUBMC组件的RefEepromTestChip属性配置为动态引用对象关联到Eeprom_DemoEeprom_1
"Objects": {
...
"Eeprom_DemoEeprom_1": {
"HealthStatus": 0,
"PowerStatus": 1,
"SelfTestResult": 1,
"Address": 174,
"AddrWidth": 1,
"OffsetWidth": 2,
"WriteTmout": 100,
"ReadTmout": 100,
"RwBlockSize": 32,
"WriteInterval": 20
},
"Accessor_readTest": {
"Chip": "#/Eeprom_DemoEeprom_1",
"Mask": 255,
"Offset": 188,
"Type": 1,
"Size": 1,
"Value": 0
},
"MyEepromModel_1": {
"RefEepromTestChip": "#/Eeprom_DemoEeprom_1"
}
...
}
vpd组件构建,为了和之前版本进行区分,将service.json中的version字段进行更新
bingo build --stage=rc
整包构建,在manifest中build/subsys/rc/hardware.yml找到vpd声明位置,将版本改至对应的构建版本
构建出包
bingo build -sc qemu
启动qemu
python3 build/works/packet/qemu_shells/vemake_1711.py
ssh登录重点,查看Hello_openUBMC的资源树
busctl --user tree bmc.kepler.Hello_openUBMC
telnet登录重点查看启动日志

