OpenHarmony移植案例与原理:startup子系统之syspara_lite系统属性部件

Posted 华为云开发者社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenHarmony移植案例与原理:startup子系统之syspara_lite系统属性部件相关的知识,希望对你有一定的参考价值。

摘要:本文介绍下移植开发板时如何适配系统属性部件syspara_lite,并介绍下相关的运行机制原理。

本文分享自华为云社区《openharmony移植案例与原理 - startup子系统之syspara_lite系统属性部件》,作者: zhushy 。

系统属性部件syspara_lite负责提供获取与设置操作系统相关的系统属性,包括默认系统属性、OEM厂商系统属性和自定义系统属性。为满足OpenHarmony产品兼容性规范,产品解决方案需要实现获取设备信息的接口,如:产品名、品牌名、厂家名等,同时提供设置/读取系统属性的接口。系统属性部件syspara_lite包含系统参数特性syspara_lite和token。系统属性部件syspara_lite定义在build\\lite\\components\\startup.json。源代码目录如下:

base/startup/syspara_lite/    # 系统属性部件
├── frameworks                # 系统属性部件源文件目录
├── hals                      # 系统属性部件硬件抽象层头文件目录
└── interfaces                # 系统属性部件对外接口目录

系统参数syspara适配

适配启动恢复子系统startup的syspara_lite部件的一个实例vendor\\bestechnic\\display_demo\\config.json的代码片段如下,⑴处的配置项enable_ohos_startup_syspara_lite_use_posix_file_api设置为true,下文通过分析syspara_lite部件的代码来解释。

  
  "product_name": "display_demo",
    ......
  "subsystems": [
    
    ......
    
      "subsystem": "startup",
      "components": [
        
          "component": "bootstrap_lite"
        ,
        
          "component": "syspara_lite",
          "features": [
⑴           "enable_ohos_startup_syspara_lite_use_posix_file_api = true"
          ]
        
      ]
    ,
    ......
  ],
  "vendor_adapter_dir": "",
  "product_adapter_dir": "//vendor/bestechnic/display_demo/hals",
    ......

我们知道,syspara_lite部件支持获取和设置操作系统的参数,当设置系统参数时,系统参数会最终写到文件中进行持久化保存。在轻量系统中,文件操作相关接口有POSIX接口与HalFiles接口这两套实现。POSIX文件系统接口代码位置kernel\\liteos_m\\kal\\libc\\musl\\fs.c,HalFiles文件系统接口位置为utils\\native\\lite\\file\\src\\file_impl_hal\\file.c。当对接内核的文件系统,采用POSIX相关的接口时,需要在features字段中需要增加enable_ohos_startup_syspara_lite_use_posix_file_api = true。如果对接HalFiles相关的接口,则无须修改。enable_ohos_startup_syspara_lite_use_posix_file_api默认为false,定义在文件base\\startup\\syspara_lite\\frameworks\\parameter\\config.gni。我们通过看下编译配置文件来了解下实现的原理机制,打开文件base\\startup\\syspara_lite\\frameworks\\parameter\\src\\BUILD.gn,片段如下。

⑴处解释了上文的配置参数enable_ohos_startup_syspara_lite_use_posix_file_api。⑵处依赖产品解决方案中的适配的sys_param实现代码。ohos_product_adapter_dir是产品解决方案config.json中的配置项,该配置项一遍设置为"hals"。sys_param实现代码文件的路径一遍为"hals/utils/sys_paramn/hal_sys_param.c",并且同级目录的BUILD.gn文件中的静态库名称必须为hal_sysparam。⑶处表示如果需要使用安全函数,则需要配置项enable_ohos_startup_syspara_lite_use_thirdparty_mbedtls设置为true。⑷处设置一些配置项宏,这些属于构建类别的参数。

if (ohos_kernel_type == "liteos_m") 
  static_library("sysparam") 
    include_dirs = [
      "//base/startup/syspara_lite/interfaces/kits",
      "//utils/native/lite/include",
      "//base/startup/syspara_lite/frameworks/parameter/src",
      "//base/startup/syspara_lite/hals",
      "//third_party/mbedtls/include",
    ]
    sources = [ "parameter_common.c" ]
⑴  if (enable_ohos_startup_syspara_lite_use_posix_file_api) 
      sources += [ "param_impl_posix/param_impl_posix.c" ]
     else 
      sources += [ "param_impl_hal/param_impl_hal.c" ]
    

⑵  deps = [ "$ohos_product_adapter_dir/utils/sys_param:hal_sysparam" ]
⑶  if (enable_ohos_startup_syspara_lite_use_thirdparty_mbedtls) 
      deps += [ "//third_party/mbedtls:mbedtls" ]
    

    if (enable_ohos_startup_syspara_lite_use_posix_file_api) 
      deps += [ "//third_party/bounds_checking_function:libsec_static" ]
    
    defines = [
⑷    "INCREMENTAL_VERSION=\\"$ohos_version\\"",
      "BUILD_TYPE=\\"$ohos_build_type\\"",
      "BUILD_USER=\\"$ohos_build_user\\"",
      "BUILD_TIME=\\"$ohos_build_time\\"",
      "BUILD_HOST=\\"$ohos_build_host\\"",
      "BUILD_ROOTHASH=\\"$ohos_build_roothash\\"",
      "USE_MBEDTLS",
      "DATA_PATH=\\"$config_ohos_startup_syspara_lite_data_path\\"",
    ]
  

看个产品解决方案的实际例子,vendor\\bestechnic\\display_demo\\hals\\utils\\sys_param\\BUILD.gn的代码如下,⑴处的静态库的名字是不能随意更改的,见上文解释。

⑴  static_library("hal_sysparam") 
    sources = [ "hal_sys_param.c" ]
    include_dirs = [ "//base/startup/syspara_lite/hals" ]
    defines = [
        "INCREMENTAL_VERSION=\\"$ohos_version\\"",
        "BUILD_TYPE=\\"$ohos_build_type\\"",
        "BUILD_USER=\\"$ohos_build_user\\"",
        "BUILD_TIME=\\"$ohos_build_time\\"",
        "BUILD_HOST=\\"$ohos_build_host\\"",
        "BUILD_ROOTHASH=\\"$ohos_build_roothash\\"",
    ]
    

文件vendor\\bestechnic\\display_demo\\hals\\utils\\sys_param\\hal_sys_param.c实现接口文件base\\startup\\syspara_lite\\hals\\hal_sys_param.h中声明的函数,如下所示,主要包含设备厂商信息,软件版本信息,构建信息等。

const char* HalGetDeviceType(void);
const char* HalGetManufacture(void);
const char* HalGetBrand(void);
const char* HalGetMarketName(void);
const char* HalGetProductSeries(void);
const char* HalGetProductModel(void);
const char* HalGetSoftwareModel(void);
const char* HalGetHardwareModel(void);
const char* HalGetHardwareProfile(void);
const char* HalGetSerial(void);
const char* HalGetBootloaderVersion(void);
const char* HalGetAbiList(void);
const char* HalGetDisplayVersion(void);
const char* HalGetIncrementalVersion(void);
const char* HalGetBuildType(void);
const char* HalGetBuildUser(void);
const char* HalGetBuildHost(void);
const char* HalGetBuildTime(void);
int HalGetFirstApiVersion(void);

在适配HalGetSerial接口时,开发板不像产线生产过程那样,会写入一个具体的序列号Serial Number,因而需要确定一个数据对开发板进行唯一标识。vendor\\bestechnic\\display_demo\\hals\\utils\\sys_param\\hal_sys_param.c中提供了一种方法,采用WiFi Mac地址进行适配。

const char* HalGetSerial(void)

    char macAddr[ETH_ALEN];
    // as devboard has no production serial number, we just
    // use wifi mac address as device serial number.
    if (serialNumber[0] == STR_END_FLAG) 
        extern int bwifi_get_own_mac(u8 *addr);
        bwifi_get_own_mac(macAddr);
        int j = 0;
        for (int i = 0; i < ETH_ALEN; i++) 
            u8 lowFour, highFour;
            highFour = (macAddr[i] & MAC_HIGH_MASK) >> MAC_BITS;
            serialNumber[j] = Hex2Char(highFour);
            j++;
            lowFour = macAddr[i] & MAC_LOW_MASK;
            serialNumber[j] = Hex2Char(lowFour);
            j++;
        
    
    return serialNumber;

Token令牌适配

在文件base\\startup\\syspara_lite\\hals\\hal_token.h中定义令牌相关的接口声明,包含写令牌,获取AcKey,获取产品编码和产品键值。在移植开发板时,需要实现这些接口。

在base\\startup\\syspara_lite\\frameworks\\token\\BUILD.gn文件中,查看令牌如何编译的,以LiteOS-M为例,片段为:
⑴处可以看出编译使用的源文件是"src/token_impl_hal/token.c",对于linux和liteos-a内核使用的源文件是"src/token_impl_posix/token.c"。"token.c"文件代码很简单,判断下参数然后调用产品解决方案中的适配函数,比如函数ReadToken()会调用HalReadToken()函数。

⑵处需要注意,这里依赖的就是产品解决方案适配的token实现代码。ohos_product_adapter_dir是产品解决方案config.json中的配置项,该配置项一遍设置为"hals"。token实现代码文件的路径一遍为"hals/utils/token/hal_token.c",并且同级目录的BUILD.gn文件中的静态库名称必须为hal_token_static。⑶处表示token部件由特性token_static组成。

    if (ohos_kernel_type == "liteos_m") 
    static_library("token_static") 
⑴      sources = [ "src/token_impl_hal/token.c" ]

        include_dirs = [
        "//base/startup/syspara_lite/interfaces/kits",
        "//utils/native/lite/include",
        "//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite",
        "//base/startup/syspara_lite/hals",
        ]

⑵      deps = [ "$ohos_product_adapter_dir/utils/token:hal_token_static" ]
    
    

    lite_component("token") 
    features = []
    if (ohos_kernel_type == "liteos_a" || ohos_kernel_type == "linux") 
        features += [ ":token_shared" ]
    
    if (ohos_kernel_type == "liteos_m") 
⑶      features += [ ":token_static" ]
    
    

看个产品解决方案的实际例子,vendor\\bestechnic\\display_demo\\hals\\utils\\token\\BUILD.gn的代码如下,⑴处的静态库的名字是不能随意更改的,见上文解释。

⑴  static_library("hal_token_static") 
    sources = [ "hal_token.c" ]

    include_dirs = [
        "//base/startup/syspara_lite/hals",
        "//utils/native/lite/include",
    ]
    deps = []
    

文件vendor\\bestechnic\\display_demo\\hals\\utils\\token\\hal_token.c中的令牌实现代码片段如下,当前均为空实现,没有实际使用起来。

static int OEMReadToken(char *token, unsigned int len)

    // OEM need add here, read token from device
    (void)(token);
    (void)(len);
    return EC_SUCCESS;

......
int HalReadToken(char *token, unsigned int len)

    if (token == NULL) 
        return EC_FAILURE;
    

    return OEMReadToken(token, len);

系统参数syspara_lite部件使用例子

下面是系统参数syspara_lite部件使用例子,来自https://gitee.com/openharmony/startup_syspara_lite。⑴处获取设备类型,⑵处获取厂商名称,⑶处获取品牌名称。其他系统属性接口调用的例子类似,详细的接口说明下文会提供。

⑴  char* value1 = GetDeviceType();
    printf("Device type =%s\\n", value1);
    free(value1);
⑵  char* value2 = GetManufacture();
    printf("Manufacture =%s\\n", value2);
    free(value2);
⑶  char* value3 = GetBrand();
    printf("GetBrand =%s\\n", value3);
    free(value3);

系统参数syspara_lite部件接口信息

在文件base\\startup\\syspara_lite\\interfaces\\innerkits\\native\\syspara\\include\\parameter.h中定义了系统属性的接口。系统属性接口说明如下表所示:

参考站点

点击关注,第一时间了解华为云新鲜技术~

以上是关于OpenHarmony移植案例与原理:startup子系统之syspara_lite系统属性部件的主要内容,如果未能解决你的问题,请参考以下文章

OpenHarmony移植案例与原理XTS子系统之应用兼容性测试用例开发

OpenHarmony移植案例:如何适配服务启动引导部件bootstrap_lite

OpenHarmony移植案例:如何适配服务启动引导部件bootstrap_lite

OpenHarmony移植:如何适配utils子系统之KV存储部件

OpenHarmony移植案例: build lite源码分析之hb命令__entry__.py

OpenHarmony移植:XTS子系统之应用兼容性测试套件