天天看點

openEuler Embedded SIG | 分布式軟總線openEuler Embedded SIG | 分布式軟總線

openEuler Embedded SIG | 分布式軟總線

特性介紹

背景

openEuler秉承着打造“數字化基礎設施作業系統”的願景,為促進與OpenHarmony生态的合作與互通,實作端邊領域的互通和協同,首次在嵌入式領域引入分布式軟總線技術。

分布式軟總線是OpenHarmony社群開源的分布式裝置通信基座,為裝置之間的互通互聯提供統一的分布式協同能力,實作裝置無感發現和高效傳輸。

OpenHarmony主要面向強互動等需求的智能終端、物聯網終端和工業終端。openEuler主要面向有高可靠、高性能等需求的伺服器、邊緣計算、雲和嵌入式裝置,二者各有側重。通過以分布式軟總線為代表的技術進行生态互通,以期實作“1+1>2”的效果,支撐社群使用者開拓更廣闊的行業空間。

架構

軟總線的主要架構如下:

openEuler Embedded SIG | 分布式軟總線openEuler Embedded SIG | 分布式軟總線

軟總線主體功能分為發現、組網、連接配接和傳輸四個基本子產品,實作:

  • 即插即用:快速便捷發現周邊裝置。
  • 自由流轉:各裝置間自組網,任意建立業務連接配接,實作自由通信。
  • 高效傳輸:通過WIFI、藍牙裝置下軟硬體協同最大化發揮硬體傳輸性能。

軟總線南向支援标準以太網通信,同時後續可持續拓展WIFI、藍牙等多種通信方式。并為北向的分布式應用提供統一的API接口,屏蔽底層通信機制。

軟總線依賴于裝置認證、IPC、日志和系統參數(SN号)等周邊子產品,嵌入式系統中将這些依賴子產品進行了樣闆性質的替換,以實作軟總線基本功能。實際的周邊子產品功能實作,還需要使用者根據實際業務場景進行豐富和替換,以拓展軟總線能力。

應用指南

部署示意

軟總線支援區域網路内多裝置部署,裝置間通過以太網通信。單裝置上分為server和client,二者通過IPC子產品進行互動。

openEuler Embedded SIG | 分布式軟總線openEuler Embedded SIG | 分布式軟總線

注意:

目前IPC子產品和SN号等系統參數,嵌入式版本提供的僅為參考模闆,還無法支援多節點和多client部署。使用者可根據實際業務場景進行IPC子產品和SN号系統參數進行功能豐富,以拓展軟總線部署能力。

服務端啟動

服務端主程式為

softbus_server_main

,執行該主程式既可拉起軟總線服務端。

openeuler ~ # softbus_server_main >log.file &
           

當服務端被拉起時,會主動通過名為ethX的網絡裝置進行coap廣播,若探測到對端裝置存在則會啟動自組網。

用戶端API

頭檔案在sdk和initrd中均存放在

/usr/include/dsoftbus/

下,其中:

  1. discovery_service.h:發現子產品頭檔案,支援應用主動探測和釋出的API如下:
    API 功能
    PublishService 釋出特定服務能力
    UnPublishService 取消釋出特定服務能力
    StartDiscovery 訂閱/探測特定服務能力
    StopDiscovery 取消訂閱特性服務能力
    其中服務能力通過

    g\_capabilityMap

    數組定義,使用者若新增能力需要自定義修改該數組,并重新編譯軟總線服務端和用戶端程式來生效。
  2. softbus_bus_center.h:組網子產品頭檔案,支援擷取組網内裝置資訊API如下:
    API 功能
    GetAllNodeDeviceInfo 擷取目前組網内所有節點資訊
  3. session.h:連接配接/傳輸子產品頭檔案,支援建立session和資料傳輸API如下:
    API 功能
    CreateSessionServer 建立session服務端
    RemoveSessionServer 移除session服務端
    OpenSession 建立到對端的傳輸連接配接(同時依賴于本端和對端提前建立的SessionServer)
    CloseSession 斷開傳輸連接配接
    SendBytes 根據建好的連接配接ID,進行資料傳輸。

各API參數詳見頭檔案描述。

應用示例

使用QEMU部署分布式軟總線,編寫用戶端程式,使其能夠列出所有發現的裝置資訊。

  1. 編寫用戶端程式

    編寫用戶端程式依托于Embedded版本釋出的SDK,按如下步驟進行SDK環境使用準備。

    1. 安裝SDK

      執行SDK自解壓安裝腳本

      sh openeuler-glibc-x86_64-openeuler-image-aarch64-qemu-aarch64-toolchain-22.03.sh
                 
      根據提示輸入工具鍊的安裝路徑,預設路徑是

      /opt/openeuler/<openeuler version>/

      ;若不設定,則按預設路徑安裝;也可以配置相對路徑或絕對路徑。

      舉例如下:

      sh ./openeuler-glibc-x86_64-openeuler-image-armv7a-qemu-arm-toolchain-22.03.sh``
      openEuler embedded(openEuler Embedded Reference Distro) SDK installer version 22.03
      ================================================================
      Enter target directory for SDK (default: /opt/openeuler/22.03): sdk
      You are about to install the SDK to "/usr1/openeuler/sdk". Proceed [Y/n]? y
      Extracting SDK...............................................done
      Setting it up...SDK has been successfully set up and is ready to be used.
      Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
      . /usr1/openeuler/sdk/environment-setup-armv7a-openeuler-linux-gnueabi
                 
    2. 設定SDK環境變量

      前一步執行結束最後已列印source指令,運作即可。

      . /usr1/openeuler/myfiles/sdk/environment-setup-armv7a-openeuler-linux-gnueabi
                 
    3. 檢視是否安裝成功

      運作如下指令,檢視是否安裝成功、環境設定成功。

      arm-openeuler-linux-gnueabi-gcc -v
                 

    接下來編寫用戶端程式。

    建立一個

    main.c

    檔案,源碼如下:
    #include "dsoftbus/softbus_bus_center.h"
    #include <stdio.h>
    #include <stdlib.h>
    int main(void)
    {
        int32_t infoNum = 10;
        NodeBasicInfo **testInfo = malloc(sizeof(NodeBasicInfo *) * infoNum);
        int ret = GetAllNodeDeviceInfo("testClient", testInfo, &infoNum);
        if (ret != 0) {
            printf("Get node device info fail.\n");
            return 0;
        }
        printf("Get node num: %d\n", infoNum);
        for (int i = 0; i < infoNum; i++) {
            printf("\t networkId: %s, deviceName: %s, deviceTypeId: %d\n",
            testInfo[i]->networkId,
            testInfo[i]->deviceName,
            testInfo[i]->deviceTypeId);
        }
        for (int i = 0; i < infoNum; i++) {
            FreeNodeInfo(testInfo[i]);
        }
        free(testInfo);
        testInfo = NULL;
    
        return 0;
    }
               
    建立一個

    CMakeLists.txt

    檔案,源碼如下:
    project(dsoftbus_hello C)
    add_executable(dsoftbus_hello main.c)
    target_link_libraries(dsoftbus_hello dsoftbus_bus_center_service_sdk.z)
               
    編譯用戶端
    mkdir build
    cd build
    cmake ..
    make
               
    編譯完成後會得到

    dsoftbus_hello

  2. 建構QEMU組網環境

    在host中建立網橋br0

    brctl addbr br0
               
    啟動qemu1
    qemu-system-aarch64 -M virt-4.0 -m 1G -cpu cortex-a57 -nographic -kernel zImage -initrd <openeuler-image-qemu-xxx.cpio.gz> -device virtio-net-device,netdev=tap0,mac=52:54:00:12:34:56 -netdev bridge,id=tap0
               

    注意:

    首次運作如果出現如下錯誤提示:

    failed to parse default acl file `/usr/local/libexec/../etc/qemu/bridge.conf'
    qemu-system-aarch64: bridge helper failed
               
    則需要向訓示的檔案添加“allow br0”
    echo "allow br0" > /usr/local/libexec/../etc/qemu/bridge.conf
               
    啟動qemu2
    qemu-system-aarch64 -M virt-4.0 -m 1G -cpu cortex-a57 -nographic -kernel zImage -initrd openeuler-image-qemu-aarch64-20220331025547.rootfs.cpio.gz  -device virtio-net-device,netdev=tap1,mac=52:54:00:12:34:78 -netdev bridge,id=tap1
               

    注意:

    qemu1與qemu2的mac位址需要配置為不同的值。

    配置IP

    配置host的網橋位址

    ifconfig br0 192.168.10.1 up
               
    配置qemu1的網絡位址
    ifconfig eth0 192.168.10.2
               
    配置qemu2的網絡位址
    ifconfig eth0 192.168.10.3
               
    分别在host、qemu1、qemu2使用ping進行測試,確定qemu1可以ping通qemu2。
  3. 啟動分布式軟總線

    在qemu1和qemu2中啟動分布式軟總線的服務端

    softbus_server_main >log.file &
               
    将編譯好的用戶端分發到qemu1和qemu2的根目錄中
    scp dsoftbus_hello [email protected]:/
    scp dsoftbus_hello [email protected]:/
               
    分别在qemu1和qemu2的根目錄下運作

    dsoftbus_hello

    ,将得到如下輸出:

    qemu1

    [LNN]NodeStateCbCount is 10
    [LNN]BusCenterClientInit init OK!
    [DISC]Init success
    [TRAN]init tcp direct channel success.
    [TRAN]init succ
    [COMM]softbus server register service success!
    
    [COMM]softbus sdk frame init success.
    Get node num: 1
            networkId: 714373d691265f9a736442c01459ba39236642c743a71750bb63eb73cde24f5f, deviceName: UNKNOWN, deviceTypeId: 0
    
               
    qemu2
    [LNN]NodeStateCbCount is 10
    [LNN]BusCenterClientInit init OK!
    [DISC]Init success
    [TRAN]init tcp direct channel success.
    [TRAN]init succ
    [COMM]softbus server register service success!
    
    [COMM]softbus sdk frame init success.
    Get node num: 1
            networkId: eaf591f64bab3c20304ed3d3ff4fe1d878a0fd60bf8c85c96e8a8430d81e4076,deviceName: UNKNOWN, deviceTypeId: 0
               
    qemu1和qemu2分别輸出了發現的對方裝置的基礎資訊。

編譯指導

編譯依托于Embedded版本釋出的容器鏡像,請參考容器建構指導進行容器環境準備。

容器建構指導連結:https://docs.openeuler.org/zh/docs/22.03_LTS/docs/Embedded/容器建構指導.html

  1. 下載下傳腳本所在倉庫(例如下載下傳到

    src/yocto-meta-openeuler

    目錄下)
    git clone https://gitee.com/openeuler/yocto-meta-openeuler.git -b openEuler-22.03-LTS -v src/yocto-meta-openeuler
               
  2. 執行下載下傳腳本

    下載下傳最新軟總線代碼:

    sh src/yocto-meta-openeuler/scripts/download_code.sh dsoftbus
               
    代碼預設下載下傳到與

    yocto-meta-openeuler

    同級别的路徑,如需修改軟總線或者其依賴的子產品代碼可到對應路徑下查找

    dsoftbus/_standard

    yocto-embedded-tools

    倉庫進行對應修改。
  3. 編譯編譯腳本

    編譯最新軟總線代碼:

    sh src/yocto-meta-openeuler/scripts/compile.sh dsoftbus
               
    編譯工作目錄名為

    dsoftbus/_build

    ,編譯生成件目錄名為

    dsoftbus/_output

    ,二者均預設與

    yocto-meta-openeuler

    在同級别路徑。

限制限制

  1. 僅支援區域網路下的coap發現。WIFI/BLE等功能在後續版本中持續支援。
  2. 目前提供的IPC、SN号等軟總線的依賴子產品均為樣例,僅支援雙裝置節點部署,client-server一對一部署的能力。期待後續與社群夥伴,根據實際場景共同對這些依賴子產品進行執行個體化。

關注我們

Embedded 已經在 openEuler 社群開源。将開展一系列主題分享,如果您對 Embedded 的建構,應用感興趣,歡迎圍觀和加入。

繼續閱讀