RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

鴻蒙OpenHarmony開發(fā)板解析:【Rust模塊配置規(guī)則和指導】

jf_46214456 ? 來源: jf_46214456 ? 作者: jf_46214456 ? 2024-05-10 11:32 ? 次閱讀

概述

Rust是一門靜態(tài)強類型語言,具有更安全的內(nèi)存管理、更好的運行性能、原生支持多線程開發(fā)等優(yōu)勢。Rust官方也使用Cargo工具來專門為Rust代碼創(chuàng)建工程和構建編譯。 OpenHarmony為了集成C/C++代碼和提升編譯速度,使用了GN + Ninja的編譯構建系統(tǒng)。GN的構建語言簡潔易讀,Ninja的匯編級編譯規(guī)則直接高效。 為了在OpenHarmony中集成Rust代碼,并最大程度發(fā)揮Rust和OpenHarmony中原有C/C++代碼的交互性,采用GN作為統(tǒng)一構建工具,即通過GN構建Rust源碼文件(xxx.rs),并增加與C/C++互操作、編譯時lint、測試、IDL轉換、三方庫集成、IDE等功能。同時擴展gn框架,支持接口自動化轉換,最大程度簡化開發(fā)。

基本概念

術語描述
CargoCargo是Rust官方使用的構建工具,允許Rust項目聲明其各種依賴項,并確保您始終獲得可重復的構建。
cratecrate是一個獨立的可編譯單元。
LintLint是指出常見編程錯誤、錯誤、樣式錯誤和可疑結構的工具??梢詫Τ绦蜻M行更加廣泛的錯誤分析。

配置規(guī)則

OpenHarmony提供了用于Rust代碼編譯構建的各類型GN模板,可以用于編譯Rust可執(zhí)行文件,動態(tài)庫和靜態(tài)庫等。各類型模板說明如下:

GN模板功能輸出
ohos_rust_executablerust可執(zhí)行文件rust可執(zhí)行文件,不帶后綴
ohos_rust_shared_liaryrust動態(tài)庫rust dylib動態(tài)庫,默認后綴.dylib.so
ohos_rust_static_liaryrust靜態(tài)庫rust rlib靜態(tài)庫,默認后綴.rlib
ohos_rust_proc_macrorust proc_macrorust proc_macro庫, 默認后綴.so
ohos_rust_shared_ffirust FFI動態(tài)庫rust cdylib動態(tài)庫,給C/C++模塊調(diào)用,默認后綴.so
ohos_rust_static_ffirust FFI靜態(tài)庫rust staticlib庫,給C/C++模塊調(diào)用,默認后綴.a
ohos_rust_cargo_crate三方包Cargo craterust三方crate,支持rlib、dylib、bin
ohos_rust_systemtestrust系統(tǒng)測試用例rust可執(zhí)行系統(tǒng)測試用例,不帶后綴
ohos_rust_unittestrust單元測試用例rust可執(zhí)行單元測試用例,不帶后綴
ohos_rust_fuzztestrust Fuzz測試用例rust可執(zhí)行Fuzz測試用例,不帶后綴

配置指導

配置Rust模塊與C/C++模塊類似,參考[模塊配置規(guī)則]。下面是使用不同模板的示例。

開發(fā)前請熟悉鴻蒙開發(fā)指導文檔:[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md]

配置Rust靜態(tài)庫示例

該示例用于測試Rust可執(zhí)行bin文件和靜態(tài)庫rlib文件的編譯,以及可執(zhí)行文件對靜態(tài)庫的依賴,使用模板ohos_rust_executable和ohos_rust_static_library。操作步驟如下:

  1. 創(chuàng)建build/rust/tests/test_rlib_crate/src/simple_printer.rs,如下所示:
    //! simple_printer
    
    /// struct RustLogMessage
    
    pub struct RustLogMessage {
        /// i32: id
        pub id: i32,
        /// String: msg
        pub msg: String,
    }
    
    /// function rust_log_rlib
    pub fn rust_log_rlib(msg: RustLogMessage) {
        println!("id:{} message:{:?}", msg.id, msg.msg)
    }
    
  2. 創(chuàng)建build/rust/tests/test_rlib_crate/src/main.rs,如下所示:
    //! rlib_crate example for Rust.
    
    extern crate simple_printer_rlib;
    
    use simple_printer_rlib::rust_log_rlib;
    use simple_printer_rlib::RustLogMessage;
    
    fn main() {
        let msg: RustLogMessage = RustLogMessage {
            id: 0,
            msg: "string in rlib crate".to_string(),
        };
        rust_log_rlib(msg);
    }
    
  3. 配置gn腳本build/rust/tests/test_rlib_crate/BUILD.gn,如下所示:
    import("http://build/ohos.gni")
    
    ohos_rust_executable("test_rlib_crate") {
      sources = [ "src/main.rs" ]
      deps = [ ":simple_printer_rlib" ]
    }
    
    ohos_rust_static_library("simple_printer_rlib") {
      sources = [ "src/simple_printer.rs" ]
      crate_name = "simple_printer_rlib"
      crate_type = "rlib"
      features = [ "std" ]
    }
    
  4. 執(zhí)行編譯得到的可執(zhí)行文件,運行結果如下:
    test_rlib_crate

配置三方庫示例

rust三方庫的BUILD.gn文件可通過cargo2gn工具自動生成。參見:[Cargo2gn工具操作指導]

該示例用于測試包含預編譯文件build.rs的三方靜態(tài)庫rlib文件的編譯,使用了模板ohos_rust_executable和ohos_rust_cargo_crate。操作步驟如下:

  1. 創(chuàng)建build/rust/tests/test_rlib_cargo_crate/crate/src/lib.rs,如下所示:
    include!(concat!(env!("OUT_DIR"), "/generated/generated.rs"));
    
    pub fn say_hello_from_crate() {
        assert_eq!(run_some_generated_code(), 45);
        #[cfg(is_new_rustc)]
        println!("Is new rustc");
        #[cfg(is_old_rustc)]
        println!("Is old rustc");
        #[cfg(is_ohos)]
        println!("Is ohos");
        #[cfg(is_mac)]
        println!("Is darwin");
        #[cfg(has_feature_a)]
        println!("Has feature_a");
        #[cfg(not(has_feature_a))]
        panic!("Wasn't passed feature_a");
        #[cfg(not(has_feature_b))]
        #[cfg(test_a_and_b)]
        panic!("feature_b wasn't passed");
        #[cfg(has_feature_b)]
        #[cfg(not(test_a_and_b))]
        panic!("feature_b was passed");
    }
    
    #[cfg(test)]
    mod tests {
        /// Test features are passed through from BUILD.gn correctly. This test is the target configuration.
        #[test]
        #[cfg(test_a_and_b)]
        fn test_features_passed_target1() {
            #[cfg(not(has_feature_a))]
            panic!("feature a was not passed");
            #[cfg(not(has_feature_b))]
            panic!("feature b was not passed");
        }
    
        #[test]
        fn test_generated_code_works() {
            assert_eq!(crate::run_some_generated_code(), 45);
        }
    }
    
  2. 創(chuàng)建build/rust/tests/test_rlib_cargo_crate/crate/src/main.rs,如下所示:
    pub fn main() {
        test_rlib_crate::say_hello_from_crate();
    }
    
  3. 創(chuàng)建build/rust/tests/test_rlib_cargo_crate/crate/build.rs,如下所示:
    use std::env;
    use std::path::Path;
    use std::io::Write;
    use std::process::Command;
    use std::str::{self, FromStr};
    
    fn main() {
        println!("cargo:rustc-cfg=build_script_ran");
        let my_minor = match rustc_minor_version() {
            Some(my_minor) = > my_minor,
            None = > return,
        };
    
        if my_minor >= 34 {
            println!("cargo:rustc-cfg=is_new_rustc");
        } else {
            println!("cargo:rustc-cfg=is_old_rustc");
        }
    
        let target = env::var("TARGET").unwrap();
    
        if target.contains("ohos") {
            println!("cargo:rustc-cfg=is_ohos");
        }
        if target.contains("darwin") {
            println!("cargo:rustc-cfg=is_mac");
        }
    
        let feature_a = env::var_os("CARGO_FEATURE_MY_FEATURE_A").is_some();
        if feature_a {
            println!("cargo:rustc-cfg=has_feature_a");
        }
        let feature_b = env::var_os("CARGO_FEATURE_MY_FEATURE_B").is_some();
        if feature_b {
            println!("cargo:rustc-cfg=has_feature_b");
        }
    
        // Some tests as to whether we're properly emulating various cargo features.
        assert!(Path::new("build.rs").exists());
        assert!(Path::new(&env::var_os("CARGO_MANIFEST_DIR").unwrap()).join("build.rs").exists());
        assert!(Path::new(&env::var_os("OUT_DIR").unwrap()).exists());
    
        // Confirm the following env var is set
        env::var_os("CARGO_CFG_TARGET_ARCH").unwrap();
    
        generate_some_code().unwrap();
    }
    
    fn generate_some_code() - > std::io::Result< () > {
        let test_output_dir = Path::new(&env::var_os("OUT_DIR").unwrap()).join("generated");
        let _ = std::fs::create_dir_all(&test_output_dir);
        // Test that environment variables from .gn files are passed to build scripts
        let preferred_number = env::var("ENV_VAR_FOR_BUILD_SCRIPT").unwrap();
        let mut file = std::fs::File::create(test_output_dir.join("generated.rs"))?;
        write!(file, "fn run_some_generated_code() - > u32 {{ {} }}", preferred_number)?;
        Ok(())
    }
    
    fn rustc_minor_version() - > Option< u32 > {
        let rustc_bin = match env::var_os("RUSTC") {
            Some(rustc_bin) = > rustc_bin,
            None = > return None,
        };
    
        let output = match Command::new(rustc_bin).arg("--version").output() {
            Ok(output) = > output,
            Err(_) = > return None,
        };
    
        let rustc_version = match str::from_utf8(&output.stdout) {
            Ok(rustc_version) = > rustc_version,
            Err(_) = > return None,
        };
    
        let mut pieces = rustc_version.split('.');
        if pieces.next() != Some("rustc 1") {
            return None;
        }
    
        let next_var = match pieces.next() {
            Some(next_var) = > next_var,
            None = > return None,
        };
    
        u32::from_str(next_var).ok()
    }
    
  4. 配置gn腳本build/rust/tests/test_rlib_cargo_crate/BUILD.gn,如下所示:
    import("http://build/templates/rust/ohos_cargo_crate.gni")
    
    ohos_cargo_crate("target") {
      crate_name = "test_rlib_crate"
      crate_root = "crate/src/lib.rs"
      sources = [ "crate/src/lib.rs" ]
    
      #To generate the build_script binary
      build_root = "crate/build.rs"
      build_sources = [ "crate/build.rs" ]
      build_script_outputs = [ "generated/generated.rs" ]
    
      features = [
        "my-feature_a",
        "my-feature_b",
        "std",
      ]
      rustflags = [
        "--cfg",
        "test_a_and_b",
      ]
      rustenv = [ "ENV_VAR_FOR_BUILD_SCRIPT=45" ]
    }
    
    # Exists to test the case that a single crate has both a library and a binary
    ohos_cargo_crate("test_rlib_crate_associated_bin") {
      crate_root = "crate/src/main.rs"
      crate_type = "bin"
      sources = [ "crate/src/main.rs" ]
    
      #To generate the build_script binary
      build_root = "crate/build.rs"
      build_sources = [ "crate/build.rs" ]
      features = [
        "my-feature_a",
        "my-feature_b",
        "std",
      ]
      rustenv = [ "ENV_VAR_FOR_BUILD_SCRIPT=45" ]
      deps = [ ":target" ]
    }
    
  5. 執(zhí)行編譯得到的可執(zhí)行文件,運行結果如下:
    test_rlib_cargo_crate

其他源碼實例

在build/rust/tests目錄下有Rust各類型模塊的配置實例可供參考:

用例目錄測試功能
build/rust/tests/test_bin_crate用ohos_rust_executable模板在host平臺編譯可執(zhí)行文件,在target平臺上運行可執(zhí)行文件。
build/rust/tests/test_static_link測試可執(zhí)行文件對標準庫的靜態(tài)鏈接。
build/rust/tests/test_dylib_crate測試對動態(tài)庫的編譯和動態(tài)鏈接功能
build/rust/tests/test_rlib_crate測試對靜態(tài)庫的編譯和靜態(tài)鏈接功能
build/rust/tests/test_proc_macro_crate測試對Rust過程宏的編譯和鏈接功能。提供對不同類型的宏的測試用例。
build/rust/tests/test_cdylib_crate測試將Rust代碼編譯成C/C++動態(tài)庫。
build/rust/tests/test_staticlib_crate測試將Rust代碼編譯成C/C++靜態(tài)庫。
build/rust/tests/rust_test_ut測試Rust代碼單元測試模板功能(ability)。
build/rust/tests/rust_test_st測試Rust代碼系統(tǒng)測試模板功能(ability)。
build/rust/tests/test_bin_cargo_crate測試Rust三方可執(zhí)行文件的編譯和運行。三方源碼中包含build.rs。
build/rust/tests/test_rlib_cargo_crate測試Rust三方靜態(tài)庫的編譯和靜態(tài)鏈接。三方源碼中包含build.rs。
build/rust/tests/test_proc_macro_cargo_crate測試Rust三方過程宏的編譯和鏈接。三方源碼中包含build.rs。
build/rust/tests/rust_test_fuzzb測試Rust代碼Fuzz測試模板功能。

參考

特性點實例

Rust源碼依賴調(diào)用C/C++庫

OpenHarmony上C/C++模塊動態(tài)庫默認用.z.so后綴,但是Rust的編譯命令通過-l鏈接時,默認只會鏈接.so后綴的動態(tài)庫。因此如果要依賴一個C/C++動態(tài)庫編譯模塊,需要在該動態(tài)庫的GN構建文件中添加output_extension = "so"的聲明,這樣編譯得到的動態(tài)庫將會以".so"作為后綴,而不是".z.so"。 在Rust源碼中如果直接鏈接動態(tài)庫,后綴也需要使用".so",這時使用動態(tài)庫的中間名,不需要添加lib前綴。例如Rust源碼中鏈接libhilog.so:

#[link(name = "hilog")]

externs使用

某個模塊如果依賴二進制的rlib庫,可以使用externs屬性:

executable("foo") {
    sources = [ "main.rs" ]
    externs = [{                    # 編譯時會轉成`--extern bar=path/to/bar.rlib`
        crate_name = "bar"
        path = "path/to/bar.rlib"
    }]
}

Lint規(guī)則

OpenHarmony框架支持rustc lints和clippy lints兩種Lint,每種Lint劃為三個等級的標準:"openharmony"、"vendor"和"none",嚴格程度按照"openharmony" -> "vendor" -> "none"逐級遞減。 配置Rust模塊時可以通過rustc_lints和clippy_lints來指定使用Lint的等級。 模塊中沒有配置rustc_lints或者clippy_lints時會根據(jù)模塊所在路徑來匹配lints等級。不同路徑下的Rust代碼的語法規(guī)范會有不同程度地約束,因此用戶在OpenHarmony配置Rust代碼編譯模塊時還應關注模塊所在路徑。

rustc lints和clippy lints的各等級標志

lints類型模塊屬性lints等級lints等級標志lints內(nèi)容
rustc_lintsrustc_lintsopenharmonyRustOhosLints"-A deprecated", "-D missing-docs", "-D warnigngs"
rustc_lintsrustc_lintsvendorRustcVendorLints"-A deprecated", "-D warnigs"
rustc_lintsrustc_lintsnoneallowAllLints"-cap-lints allow"
clippy lintsclippy lintsopenharmonyClippyOhosLints"-A clippy::type-complexity", "-A clippy::unnecessary-wraps", "-A clippy::unusual-byte-groupings", "-A clippy::upper-case-acronyms"
clippy lintsclippy lintsvendorClippyVendorLints"-A clippy::complexity", "-A Clippy::perf", "-A clippy::style"
clippy lintsclippy lintsnoneallowAllLints"--cap-lints allow"

搜狗高速瀏覽器截圖20240326151450.png

代碼路徑與lints等級的對應關系

路徑Lints等級
thirdpartynone
prebuiltsnone
vendorvendor
devicevendor
othersopenharmony

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 開發(fā)板
    +關注

    關注

    25

    文章

    5032

    瀏覽量

    97371
  • Rust
    +關注

    關注

    1

    文章

    228

    瀏覽量

    6601
  • 鴻蒙
    +關注

    關注

    57

    文章

    2339

    瀏覽量

    42805
  • OpenHarmony
    +關注

    關注

    25

    文章

    3713

    瀏覽量

    16254
收藏 人收藏

    評論

    相關推薦

    OpenHarmony鴻蒙南向開發(fā)案例:【智能貓眼(基于Hi3518開發(fā)板)】

    基于Hi3518開發(fā)板,使用開源OpenHarmony開發(fā)的RTSP協(xié)議流媒體應用。達到將Hi3518開發(fā)板中攝像頭獲取的數(shù)據(jù)通過RTSP協(xié)議傳輸?shù)绞謾C并顯示 。
    的頭像 發(fā)表于 04-22 15:46 ?2009次閱讀
    <b class='flag-5'>OpenHarmony</b><b class='flag-5'>鴻蒙</b>南向<b class='flag-5'>開發(fā)</b>案例:【智能貓眼(基于Hi3518<b class='flag-5'>開發(fā)板</b>)】

    鴻蒙OpenHarmony開發(fā)板:【產(chǎn)品配置規(guī)則

    產(chǎn)品解決方案為基于開發(fā)板的完整產(chǎn)品,主要包含產(chǎn)品對OS的適配、部件拼裝配置、啟動配置和文件系統(tǒng)配置等。產(chǎn)品解決方案的源碼路徑規(guī)則為:**ve
    的頭像 發(fā)表于 05-09 10:32 ?1125次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>OpenHarmony</b><b class='flag-5'>開發(fā)板</b>:【產(chǎn)品<b class='flag-5'>配置</b><b class='flag-5'>規(guī)則</b>】

    鴻蒙OpenHarmony開發(fā)板解析:【 模塊配置規(guī)則

    編譯子系統(tǒng)通過模塊、部件和產(chǎn)品三層配置來實現(xiàn)編譯和打包。模塊就是編譯子系統(tǒng)的一個目標,包括(動態(tài)庫、靜態(tài)庫、配置文件、預編譯模塊等)。
    的頭像 發(fā)表于 05-10 14:39 ?1023次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>OpenHarmony</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>解析</b>:【 <b class='flag-5'>模塊</b><b class='flag-5'>配置</b><b class='flag-5'>規(guī)則</b>】

    鴻蒙OpenHarmony開發(fā)板解析:【芯片解決方案】

    芯片解決方案是指基于某款開發(fā)板的完整解決方案,包含驅(qū)動、設備側接口適配、開發(fā)板sdk等。
    的頭像 發(fā)表于 05-10 15:42 ?1228次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>OpenHarmony</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>解析</b>:【芯片解決方案】

    鴻蒙OpenHarmony南向/北向快速開發(fā)教程-迅為RK3568開發(fā)板

    大家期待已久的迅為RK3568開發(fā)板終于迎來了鴻蒙4.1系統(tǒng)的強勢支持!想知道如何實現(xiàn)快速開發(fā)學習嗎?跟著我們一起來探索吧! 迅為RK3568開發(fā)板: 想象一下,你手中的RK3568
    發(fā)表于 07-23 10:44

    TI DM388評估模塊開發(fā)板開發(fā)指導手冊

    TI DM388評估模塊開發(fā)板開發(fā)指導手冊
    發(fā)表于 11-25 18:06 ?15次下載

    openharmony開發(fā)openharmony開發(fā)板

    現(xiàn)在市面上支持OpenHarmony開發(fā)板已經(jīng)非常多了,OpenHarmony不僅僅只能在海思系列芯片上運行,比較常見的有HiSpark、小熊派系列。這些開發(fā)板都是基于海思的Hi38
    的頭像 發(fā)表于 06-24 09:03 ?3670次閱讀

    [鴻蒙]OpenHarmony4.0的Rust開發(fā)

    背景 Rust 是一門靜態(tài)強類型語言,具有更安全的內(nèi)存管理、更好的運行性能、原生支持多線程開發(fā)等優(yōu)勢。Rust 官方也使用 Cargo 工具來專門為 Rust 代碼創(chuàng)建工程和構建編譯
    的頭像 發(fā)表于 02-26 17:28 ?876次閱讀
    [<b class='flag-5'>鴻蒙</b>]<b class='flag-5'>OpenHarmony</b>4.0的<b class='flag-5'>Rust</b><b class='flag-5'>開發(fā)</b>

    OpenHarmony鴻蒙南向開發(fā)案例:【智能貓眼(基于3516開發(fā)板)】

    基于Hi3516開發(fā)板,使用開源OpenHarmony開發(fā)的RTSP協(xié)議流媒體應用。達到將Hi3516開發(fā)板中攝像頭獲取的數(shù)據(jù)通過RTSP協(xié)議傳輸?shù)绞謾C并顯示 。
    的頭像 發(fā)表于 04-19 22:01 ?599次閱讀
    <b class='flag-5'>OpenHarmony</b><b class='flag-5'>鴻蒙</b>南向<b class='flag-5'>開發(fā)</b>案例:【智能貓眼(基于3516<b class='flag-5'>開發(fā)板</b>)】

    鴻蒙OpenHarmony開發(fā)板解析:【系統(tǒng)能力配置規(guī)則

    SysCap(SystemCapability,系統(tǒng)能力)是部件向開發(fā)者提供的接口的集合。
    的頭像 發(fā)表于 05-11 10:10 ?529次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>OpenHarmony</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>解析</b>:【系統(tǒng)能力<b class='flag-5'>配置</b><b class='flag-5'>規(guī)則</b>】

    瑞芯微RK3566鴻蒙開發(fā)板OpenHarmony標準系統(tǒng)應用兼容性測試指導

    本文OpenHarmony標準系統(tǒng)應用兼容性測試指導,適用鴻蒙系統(tǒng)軟件開發(fā)測試的新手入門學習課程,設備為觸覺智能的瑞芯微RK3566開發(fā)板
    的頭像 發(fā)表于 09-10 11:56 ?373次閱讀
    瑞芯微RK3566<b class='flag-5'>鴻蒙</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>OpenHarmony</b>標準系統(tǒng)應用兼容性測試<b class='flag-5'>指導</b>

    觸覺智能Purple Pi OH鴻蒙開發(fā)板成功適配OpenHarmony5.0 Release,開啟新征程

    觸覺智能Purple Pi OH鴻蒙開發(fā)板,成功適配OpenHarmony5.0 Release版本!為大家?guī)?b class='flag-5'>OpenHarmony5.0特性講解!關注觸覺智能,為大家?guī)砀?/div>
    的頭像 發(fā)表于 10-25 10:51 ?382次閱讀
    觸覺智能Purple Pi OH<b class='flag-5'>鴻蒙</b><b class='flag-5'>開發(fā)板</b>成功適配<b class='flag-5'>OpenHarmony</b>5.0 Release,開啟新征程

    如何在開源鴻蒙OpenHarmony開啟SELinux模式?RK3566鴻蒙開發(fā)板演示

    本文介紹開源鴻蒙OpenHarmony系統(tǒng)下,開啟/關閉SELinux權限的方法,觸覺智能Purple Pi OH鴻蒙開發(fā)板演示,已適配全新Open
    的頭像 發(fā)表于 11-18 19:03 ?310次閱讀
    如何在開源<b class='flag-5'>鴻蒙</b><b class='flag-5'>OpenHarmony</b>開啟SELinux模式?RK3566<b class='flag-5'>鴻蒙</b><b class='flag-5'>開發(fā)板</b>演示

    OpenHarmony屬性信息怎么修改?觸覺智能RK3566鴻蒙開發(fā)板來演示

    本文介紹開源鴻蒙OpenHarmony系統(tǒng)下,修改產(chǎn)品屬性信息的方法,觸覺智能Purple Pi OH鴻蒙開發(fā)板演示,已適配全新OpenHarmon
    的頭像 發(fā)表于 11-27 09:31 ?144次閱讀
    <b class='flag-5'>OpenHarmony</b>屬性信息怎么修改?觸覺智能RK3566<b class='flag-5'>鴻蒙</b><b class='flag-5'>開發(fā)板</b>來演示

    OpenHarmony默認30秒熄屏太麻煩?觸覺智能鴻蒙開發(fā)板教你輕松取消

    OpenHarmony系統(tǒng)開機后 30 秒會自動息屏,教大家兩招輕松取消自動息屏,觸覺智能Purple Pi OH鴻蒙開發(fā)板演示,已適配全新OpenHarmony5.0 Release
    的頭像 發(fā)表于 12-09 11:45 ?199次閱讀
    <b class='flag-5'>OpenHarmony</b>默認30秒熄屏太麻煩?觸覺智能<b class='flag-5'>鴻蒙</b><b class='flag-5'>開發(fā)板</b>教你輕松取消
    RM新时代网站-首页