【教学培训篇】读写eeprom

在之前的教学中我们学习了如何新增组件和为组件新增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登录重点查看启动日志

2 个赞

请问下代码中的EEPROM的Write函数会自动先关闭写保护,写完后会在开启写保护么?