摘要:本文介紹下移植開發板時如何適配系統屬性部件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
- HarmonyOS Device > 文件 > 指南 > 基礎能力: syspara系統屬性部件
- 輕量帶屏解決方案之恆玄晶片移植案例