国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

AndroidAutomotive模塊介紹(四)VehicleHal介紹

這篇具有很好參考價(jià)值的文章主要介紹了AndroidAutomotive模塊介紹(四)VehicleHal介紹。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

前言

前面的文章中,描述了 Android Automotive 的框架中應(yīng)用、Framework 層服務(wù)等知識(shí),本篇文章將會(huì)繼續(xù)按照 Android Automotive 框架介紹 Vehicle Hal 層服務(wù)的內(nèi)容。

上一篇:AndroidAutomotive模塊介紹(三)CarService服務(wù)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-849772.html

正文

1、VehicleHal 介紹

本篇文檔將對(duì) Andorid Automotive 框架中 VehicleHal 層展開(kāi)介紹。VehicleHal 即為車輛硬件抽象層的定義。可以理解為 Android Automotive OS 中的硬件抽象層接口,包括車輛屬性和方法;各廠商制造商會(huì)根據(jù)定義的 Hal 接口,實(shí)現(xiàn)定制化的模塊服務(wù)。

VehicleHal 是鏈接 Android Automotive Car Services 與制造商實(shí)現(xiàn)車輛控制服務(wù)進(jìn)程的橋梁,通過(guò)標(biāo)準(zhǔn)化接口對(duì)上層提供服務(wù),對(duì)于服務(wù)的實(shí)現(xiàn)依賴廠商的定制化,可以忽略汽車制造商的具體實(shí)現(xiàn),也就是說(shuō) CarService 調(diào)用 VehicleHal 定義的標(biāo)準(zhǔn)接口,廠商實(shí)現(xiàn)這些接口。

2、VehicleHal 模塊功能

2.1 rc 文件

VehicleHal 的代碼路徑為:android/hardware/interfaces/automotive/vehicle/2.0/default。路徑下有 android.hardware.automotive.vehicle@2.0-service.rc 文件,在開(kāi)機(jī)階段通過(guò)此 rc 文件,將 VehicleHal 進(jìn)程啟動(dòng),下面來(lái)看下 android.hardware.automotive.vehicle@2.0-service.rc 文件的定義

service vendor.vehicle-hal-2.0 /vendor/bin/hw/android.hardware.automotive.vehicle@2.0-service
    class hal
    user vehicle_network
    group system inet

2.2 編譯

對(duì)于 VehicleHal 的編譯,可以對(duì)以下兩個(gè) Android.bp 文件介紹。

  • Hidl 接口編譯
  • VehicleHal 服務(wù)編譯

VehicleHal 定義的 Hal 接口編譯介紹,Android.bp 文件路徑為:android/hardware/interfaces/automotive/vehicle/2.0,目錄結(jié)構(gòu)如下:

ubuntu:android/hardware/interfaces/automotive/vehicle/2.0$ ls -l
total 132
-rw-r--r-- 1   users    375 Nov  9  2022 Android.bp
drwxrwxr-x 5   users   4096 Mar 22 13:55 default
-rw-r--r-- 1   users   2336 Nov  9  2022 IVehicleCallback.hal
-rw-r--r-- 1   users   3665 Nov  9  2022 IVehicle.hal
-rw-r--r-- 1   users 115184 Nov  9  2022 types.hal

下面是 Android.bp 文件的定義:

// This file is autogenerated by hidl-gen -Landroidbp.

hidl_interface {
    name: "android.hardware.automotive.vehicle@2.0",
    root: "android.hardware",
    vndk: {
        enabled: true,
    },
    srcs: [
        "types.hal",
        "IVehicle.hal",
        "IVehicleCallback.hal",
    ],
    interfaces: [
        "android.hidl.base@1.0",
    ],
    gen_java: true,
}

編譯文件中定義了 android.hardware.automotive.vehicle@2.0 HIDL 接口編譯,包含三個(gè)文件 types.hal、IVehicle.hal、IVehicleCallback.hal 文件。

VehicleHal 服務(wù)編譯介紹,Android.bp 文件路徑為:android/hardware/interfaces/automotive/vehicle/2.0/default,目錄結(jié)構(gòu)如下:

ubuntu16:android/hardware/interfaces/automotive/vehicle/2.0/default$ ls -l
total 28
-rw-r--r-- 1   users 4705 Nov  9  2022 Android.bp
-rw-r--r-- 1   users  155 Nov  9  2022 android.hardware.automotive.vehicle@2.0-service.rc
drwxrwxr-x 4   users 4096 Jun  7  2022 common
drwxrwxr-x 3   users 4096 Jun  7  2022 impl
drwxrwxr-x 2   users 4096 Nov  9  2022 tests
-rw-r--r-- 1   users 1953 Nov  9  2022 VehicleService.cpp

Android.bp 文件定義如下:

// Vehicle reference implementation lib
cc_library {
    name: "android.hardware.automotive.vehicle@2.0-manager-lib",
    vendor: true,
    defaults: ["vhal_v2_0_defaults"],
    srcs: [
        "common/src/Obd2SensorStore.cpp",
        "common/src/SubscriptionManager.cpp",
        "common/src/VehicleHalManager.cpp",
        "common/src/VehicleObjectPool.cpp",
        "common/src/VehiclePropertyStore.cpp",
        "common/src/VehicleUtils.cpp",
        "common/src/VmsUtils.cpp",
    ],
    local_include_dirs: ["common/include/vhal_v2_0"],
    export_include_dirs: ["common/include"],
}

// Vehicle default VehicleHAL implementation
cc_library_static {
    name: "android.hardware.automotive.vehicle@2.0-default-impl-lib",
    vendor: true,
    cflags: ["-Wno-unused-parameter", "-Wno-sign-compare"],
    defaults: ["vhal_v2_0_defaults"],
    srcs: [
        "impl/vhal_v2_0/CommConn.cpp",
        "impl/vhal_v2_0/EmulatedVehicleHal.cpp",
        "impl/vhal_v2_0/VehicleEmulator.cpp",
        "impl/vhal_v2_0/PipeComm.cpp",
        "impl/vhal_v2_0/SocketComm.cpp",
        "impl/vhal_v2_0/LinearFakeValueGenerator.cpp",
        "impl/vhal_v2_0/JsonFakeValueGenerator.cpp",
    ],
    local_include_dirs: ["common/include/vhal_v2_0"],
    export_include_dirs: ["impl"],
    whole_static_libs: ["android.hardware.automotive.vehicle@2.0-manager-lib"],
    shared_libs: [
        "libbase",
        "libprotobuf-cpp-lite",
    ],
    static_libs: [
        "libjsoncpp",
        "libqemu_pipe",
        "android.hardware.automotive.vehicle@2.0-libproto-native",
    ],
}

cc_binary {
    name: "android.hardware.automotive.vehicle@2.0-service",
    defaults: ["vhal_v2_0_defaults"],
    init_rc: ["android.hardware.automotive.vehicle@2.0-service.rc"],
    vendor: true,
    relative_install_path: "hw",
    srcs: ["VehicleService.cpp"],
    shared_libs: [
        "libbase",
        "libprotobuf-cpp-lite",
    ],
    static_libs: [
        "android.hardware.automotive.vehicle@2.0-manager-lib",
        "android.hardware.automotive.vehicle@2.0-default-impl-lib",
        "android.hardware.automotive.vehicle@2.0-libproto-native",
        "libjsoncpp",
        "libqemu_pipe",
    ],
}

從 Android.bp 的定義中,VehicleHal 的服務(wù)名為 android.hardware.automotive.vehicle@2.0-service,啟動(dòng) rc 文件是 android.hardware.automotive.vehicle@2.0-service.rc,入口文件是 VehicleService.cpp,依賴自定義相關(guān)模塊主要有 android.hardware.automotive.vehicle@2.0-manager-lib、android.hardware.automotive.vehicle@2.0-default-impl-lib、android.hardware.automotive.vehicle@2.0-libproto-native。

android.hardware.automotive.vehicle@2.0-manager-lib 模塊是 common 目錄下的文件所編譯的內(nèi)容,主要是 VehicleHal 所以來(lái)的模塊。

android.hardware.automotive.vehicle@2.0-default-impl-lib 模塊是 impl 目錄下的文件所編譯的內(nèi)容,主要是 VehicleHal 的功能實(shí)現(xiàn)模塊。

android.hardware.automotive.vehicle@2.0-libproto-native 模塊是 impl/vhal_v2_0/proto 目錄下的文件所編譯的內(nèi)容,目錄下的文件為 VehicleHalProto.proto 文件,是一種序列化存儲(chǔ)數(shù)據(jù)的方式。

2.3 HIDL 接口

Android Automotive 框架中 Hal 層接口文件有三個(gè),IVehicle.hal、IVehicleCallback.hal 和 types.hal 文件。IVehicle.hal 文件中定義了 Vehicle Hal 對(duì)外提供的接口;IVehicleCallback.hal 文件中定義了 VehicleHal 的回調(diào)接口;types.hal 文件定義了 Vehicle Hal 的屬性定義。

Hidl 文件路徑為:android/hardware/interfaces/automotive/vehicle/2.0。

2.3.1 IVehicle.hal

IVehicle.hal 文件中定義了 Vehicle Hal 對(duì)外提供的接口,上層 CarService 通過(guò) IVehicle.hal 中定義的接口與 Vehicle Hal 通信。

package android.hardware.automotive.vehicle@2.0;

import IVehicleCallback;

interface IVehicle {
  /**
   * Returns a list of all property configurations supported by this vehicle
   * HAL.
   * 返回此車輛HAL支持的所有屬性配置的列表
   */
  getAllPropConfigs() generates (vec<VehiclePropConfig> propConfigs);

  /**
   * Returns a list of property configurations for given properties.
   *
   * If requested VehicleProperty wasn't found it must return
   * StatusCode::INVALID_ARG, otherwise a list of vehicle property
   * configurations with StatusCode::OK
   * 返回給定屬性的屬性配置列表。
   * 如果請(qǐng)求的車輛屬性沒(méi)有找到,它必須返回StatusCode::INVALID_ARG,否則返回一個(gè)車輛屬性配置列表,StatusCode::OK
   */
  getPropConfigs(vec<int32_t> props)
          generates (StatusCode status, vec<VehiclePropConfig> propConfigs);

  /**
   * Get a vehicle property value.
   *
   * For VehiclePropertyChangeMode::STATIC properties, this method must always
   * return the same value always.
   * For VehiclePropertyChangeMode::ON_CHANGE properties, it must return the
   * latest available value.
   *
   * Some properties like RADIO_PRESET requires to pass additional data in
   * GET request in VehiclePropValue object.
   *
   * If there is no data available yet, which can happen during initial stage,
   * this call must return immediately with an error code of
   * StatusCode::TRY_AGAIN.
   * 獲取車輛屬性值。
   * 對(duì)于 VehiclePropertyChangeMode::STATIC 的屬性值,此方法會(huì)返回同一個(gè)值,不會(huì)改變。
   * 對(duì)于 VehiclePropertyChangeMode::ON_CHANGE 的屬性值,此方法會(huì)返回最新值。
   */
  get(VehiclePropValue requestedPropValue)
          generates (StatusCode status, VehiclePropValue propValue);

  /**
   * Set a vehicle property value.
   *
   * Timestamp of data must be ignored for set operation.
   *
   * Setting some properties require having initial state available. If initial
   * data is not available yet this call must return StatusCode::TRY_AGAIN.
   * For a property with separate power control this call must return
   * StatusCode::NOT_AVAILABLE error if property is not powered on.
   * 設(shè)置車輛屬性值。
   * 特殊場(chǎng)景:
   * 設(shè)置一些屬性值需要其初始狀態(tài)可用,如果初始狀態(tài)不可用,需要返回 StatusCode::TRY_AGAIN。
   * 設(shè)置單獨(dú)電源控制的屬性,如果屬性未上電,需要返回 StatusCode::TRY_AGAIN。
   */
  set(VehiclePropValue propValue) generates (StatusCode status);

  /**
   * Subscribes to property events.
   *
   * Clients must be able to subscribe to multiple properties at a time
   * depending on data provided in options argument.
   *
   * @param listener This client must be called on appropriate event.
   * @param options List of options to subscribe. SubscribeOption contains
   *                information such as property Id, area Id, sample rate, etc.
   * 訂閱屬性
   * 客戶端可以一次訂閱多個(gè)屬性,這取決于 options 定義的參數(shù)。
   * 參數(shù) SubscribeOptions 包含 屬性id、區(qū)域id、采樣率 等信息。
   */
  subscribe(IVehicleCallback callback, vec<SubscribeOptions> options)
          generates (StatusCode status);

  /**
   * Unsubscribes from property events.
   *
   * If this client wasn't subscribed to the given property, this method
   * must return StatusCode::INVALID_ARG.
   * 取消訂閱屬性
   * 如果客戶端在此前沒(méi)有對(duì)此屬性進(jìn)行訂閱,則返回 StatusCode::INVALID_ARG。
   */
  unsubscribe(IVehicleCallback callback, int32_t propId)
          generates (StatusCode status);

  /**
   * Print out debugging state for the vehicle hal.
   *
   * The text must be in ASCII encoding only.
   *
   * Performance requirements:
   *
   * The HAL must return from this call in less than 10ms. This call must avoid
   * deadlocks, as it may be called at any point of operation. Any synchronization
   * primitives used (such as mutex locks or semaphores) must be acquired
   * with a timeout.
   *
   * 打印車輛的調(diào)試狀態(tài)。
   */
  debugDump() generates (string s);
};

2.3.2 IVehicleCallback.hal

IVehicleCallback.hal 文件定義了 VehicleHal 的回調(diào)對(duì)象,上層 CarService 通過(guò)注冊(cè)此回調(diào)對(duì)象以監(jiān)聽(tīng)屬性是否改變。VehicleHal 通過(guò)回調(diào)對(duì)象返回狀態(tài)給到客戶端。

package android.hardware.automotive.vehicle@2.0;

interface IVehicleCallback {

    /**
     * Event callback happens whenever a variable that the API user has
     * subscribed to needs to be reported. This may be based purely on
     * threshold and frequency (a regular subscription, see subscribe call's
     * arguments) or when the IVehicle#set method was called and the actual
     * change needs to be reported.
     *
     * These callbacks are chunked.
     *
     * @param values that has been updated.
     * 當(dāng)需要報(bào)告客戶端訂閱的變量時(shí),就會(huì)調(diào)用此回調(diào)函數(shù)。
     * 這可能基于常規(guī)按頻率上報(bào)或者客戶端調(diào)用 IVehicle#set 函數(shù)時(shí)調(diào)用。
     */
    oneway onPropertyEvent(vec<VehiclePropValue> propValues);

    /**
     * This method gets called if the client was subscribed to a property using
     * SubscribeFlags::EVENTS_FROM_ANDROID flag and IVehicle#set(...) method was called.
     *
     * These events must be delivered to subscriber immediately without any
     * batching.
     *
     * @param value Value that was set by a client.
     * 如果客戶端使用 SubscribeFlags::EVENTS_FROM_ANDROID 標(biāo)志訂閱屬性,并且調(diào)用 IVehicle#set 函數(shù),則回調(diào)此方法。
     */
    oneway onPropertySet(VehiclePropValue propValue);

    /**
     * Set property value is usually asynchronous operation. Thus even if
     * client received StatusCode::OK from the IVehicle::set(...) this
     * doesn't guarantee that the value was successfully propagated to the
     * vehicle network. If such rare event occurs this method must be called.
     *
     * @param errorCode - any value from StatusCode enum.
     * @param property - a property where error has happened.
     * @param areaId - bitmask that specifies in which areas the problem has
     *                 occurred, must be 0 for global properties
     * 設(shè)置屬性通常是異步操作,客戶端調(diào)用 IVehicle#set 函數(shù)到接收到 StatusCode::OK 的返回值,也不能保證此屬性成功傳播到車輛網(wǎng)絡(luò),如果發(fā)生這種低概率的事件,則回調(diào)此方法。
     * @ errorCode:StatusCode 枚舉中的任何值。
     * @ property:發(fā)生錯(cuò)誤的屬性。
     * @ areaId:指定問(wèn)題發(fā)生在哪個(gè)區(qū)域的位掩碼,對(duì)于全局屬性必須為 0。
     */
    oneway onPropertySetError(StatusCode errorCode,
                              int32_t propId,
                              int32_t areaId);
};

2.3.3 types.hal

types.hal 中定義了 VehicleHal 的屬性、結(jié)構(gòu)等數(shù)據(jù)。

2.3.3.1 車輛屬性 VehiclePropertyType

下面列舉 types.hal 中定義的 VehiclePropertyType 屬性:

package android.hardware.automotive.vehicle@2.0;

/**
 * Enumerates supported data type for VehicleProperty.
 * 枚舉 VehicleProperty 支持的數(shù)據(jù)類型。
 * Used to create property ID in VehicleProperty enum.
 * 用于在 VehicleProperty enum 中創(chuàng)建屬性 ID。
 */
enum VehiclePropertyType : int32_t { // VehicleProperty 的類型是 string、bool、還是 int32 等等
    STRING          = 0x00100000,
    BOOLEAN         = 0x00200000,
    INT32           = 0x00400000,
    INT32_VEC       = 0x00410000,
    INT64           = 0x00500000,
    INT64_VEC       = 0x00510000,
    FLOAT           = 0x00600000,
    FLOAT_VEC       = 0x00610000,
    BYTES           = 0x00700000,

    /**
     * Any combination of scalar or vector types. The exact format must be
     * provided in the description of the property.
     */
    MIXED           = 0x00e00000, // 這兩個(gè)主要就是 VehicleProperty 用來(lái)進(jìn)行或運(yùn)算的。

    MASK            = 0x00ff0000
};
2.3.3.2 車輛區(qū)域?qū)傩?VehicleArea

下面是 types.hal 中定義的車輛區(qū)域?qū)傩裕?/p>

/**
 * Vehicle Areas
 * Used to construct property IDs in the VehicleProperty enum.
 * 用于在VehicleProperty enum中構(gòu)造屬性id。
 *
 * Some properties may be associated with particular vehicle areas. For
 * example, VehicleProperty:DOOR_LOCK property must be associated with
 * particular door, thus this property must be marked with
 * VehicleArea:DOOR flag.
 * 某些屬性可能與特定車輛區(qū)域相關(guān)。例如,VehicleProperty:DOOR_LOCK 屬性必須與特定的門相關(guān)聯(lián),因此該屬性必須標(biāo)記為 VehicleArea: door 標(biāo)志。
 *
 * Other properties may not be associated with particular vehicle area,
 * these kind of properties must have VehicleArea:GLOBAL flag.
 * 其他屬性可能不與特定的車輛區(qū)域相關(guān)聯(lián),這些屬性必須具有VehicleArea:GLOBAL標(biāo)志。
 *
 * [Definition] Area: An area represents a unique element of an AreaType.
 *   For instance, if AreaType is WINDOW, then an area may be FRONT_WINDSHIELD.
 *
 * [Definition] AreaID: An AreaID is a combination of one or more areas,
 *   and is represented using a bitmask of Area enums. Different AreaTypes may
 *   not be mixed in a single AreaID. For instance, a window area cannot be
 *   combined with a seat area in an AreaID.
 *
 * Rules for mapping a zoned property to AreaIDs:
 *  - A property must be mapped to an array of AreaIDs that are impacted when
 *    the property value changes.
 *  - Each element in the array must represent an AreaID, in which, the
 *    property value can only be changed together in all the areas within
 *    an AreaID and never independently. That is, when the property value
 *    changes in one of the areas in an AreaID in the array, then it must
 *    automatically change in all other areas in the AreaID.
 *  - The property value must be independently controllable in any two
 *    different AreaIDs in the array.
 *  - An area must only appear once in the array of AreaIDs. That is, an
 *    area must only be part of a single AreaID in the array.
 *
 * [Definition] Global Property: A property that applies to the entire car
 *   and is not associated with a specific area. For example, FUEL_LEVEL,
 *   HVAC_STEERING_WHEEL_HEAT.
 *
 * Rules for mapping a global property to AreaIDs:
 *  - A global property must not be mapped to AreaIDs.
*/
enum VehicleArea : int32_t {
    GLOBAL      = 0x01000000, // 全局區(qū)域
    /** WINDOW maps to enum VehicleAreaWindow */
    WINDOW      = 0x03000000, // 窗戶區(qū)域
    /** MIRROR maps to enum VehicleAreaMirror */
    MIRROR      = 0x04000000, // 反光鏡區(qū)域
    /** SEAT maps to enum VehicleAreaSeat */
    SEAT        = 0x05000000, // 座椅區(qū)域
    /** DOOR maps to enum VehicleAreaDoor */
    DOOR        = 0x06000000, // 車門區(qū)域
    /** WHEEL maps to enum VehicleAreaWheel */
    WHEEL       = 0x07000000, // 車輪區(qū)域
    YFVehicleAreaTire = 0x08000000,
    MASK        = 0x0f000000,
};
2.3.3.3 車輛屬性分組類型 VehiclePropertyGroup

下面是 types.hal 中定義的車輛屬性分組類型:

/**
 * Enumerates property groups.
 * 車輛屬性分組枚舉
 *
 * Used to create property ID in VehicleProperty enum.
 * 用于在VehicleProperty enum中創(chuàng)建屬性ID。
 */
enum VehiclePropertyGroup : int32_t { // AndroidO 之后的 treble,用于區(qū)分 android 原生的 property 和廠商的 property。
    /**
     * Properties declared in AOSP must use this flag.
     * AOSP 原生的屬性標(biāo)志
     */
    SYSTEM      = 0x10000000,

    /**
     * Properties declared by vendors must use this flag.
     * 廠商自定義的屬性標(biāo)志
     */
    VENDOR      = 0x20000000,

    MASK        = 0xf0000000,
};

2.3.3.4 車輛屬性 VehicleProperty

下面是 types.hal 中定義的車輛屬性

/**
 * Declares all vehicle properties. VehicleProperty has a bitwise structure.
 * Each property must have:
 *  - a unique id from range 0x0100 - 0xffff
 *  - associated data type using VehiclePropertyType
 *  - property group (VehiclePropertyGroup)
 *  - vehicle area (VehicleArea)
 *
 * Vendors are allowed to extend this enum with their own properties. In this
 * case they must use VehiclePropertyGroup:VENDOR flag when property is
 * declared.
 *
 * When a property's status field is not set to AVAILABLE:
 *  - IVehicle#set may return StatusCode::NOT_AVAILABLE.
 *  - IVehicle#get is not guaranteed to work.
 *
 * Properties set to values out of range must be ignored and no action taken
 * in response to such ill formed requests.
 */
enum VehicleProperty : int32_t {

    /** Undefined property. */
    INVALID = 0x00000000,

    /**
     * VIN of vehicle
     * 車輛 VIN 碼
     *
     * @change_mode VehiclePropertyChangeMode:STATIC
     * @access VehiclePropertyAccess:READ
     */
    INFO_VIN = (
        0x0100
        | VehiclePropertyGroup:SYSTEM // 原生屬性
        | VehiclePropertyType:STRING // 屬性值是 String 類型
        | VehicleArea:GLOBAL), // 全局屬性

    /**
     * Model of vehicle
     * 車輛型號(hào)
     *
     * @change_mode VehiclePropertyChangeMode:STATIC
     * @access VehiclePropertyAccess:READ
     */
    INFO_MODEL = (
        0x0102
        | VehiclePropertyGroup:SYSTEM // 原生屬性
        | VehiclePropertyType:STRING // 屬性值是 String 類型
        | VehicleArea:GLOBAL), // 全局屬性
...
};
2.3.3.5 車輛座位占用狀態(tài) VehicleSeatOccupancyState

下面是 types.hal 中定義的車輛座位占用狀態(tài)值

/**
 * Used by seat occupancy to enumerate the current occupancy state of the seat.
 * 由座位占用使用,以枚舉座位的當(dāng)前占用狀態(tài)
 */
enum  VehicleSeatOccupancyState : int32_t {

    UNKNOWN = 0,
    VACANT = 1, // 空閑
    OCCUPIED = 2 // 占用
};
2.3.3.6 燈光狀態(tài)屬性 VehicleLightState

下面是 types.hal 中定義的燈光狀態(tài)屬性

/**
 * Used by lights state properties to enumerate the current state of the lights.
 * 由燈光狀態(tài)屬性使用,枚舉燈光的當(dāng)前狀態(tài)。
 * Most XXX_LIGHTS_STATE properties will only report ON and OFF states.  Only
 * the HEADLIGHTS_STATE property will report DAYTIME_RUNNING.
 * 大多數(shù) XXX_LIGHTS_STATE 屬性將只報(bào)告 ON 和 OFF 狀態(tài)。只有 headlight_state 屬性會(huì)報(bào)告 DAYTIME_RUNNING。
 */
enum  VehicleLightState : int32_t {

    OFF = 0,
    ON = 1,
    DAYTIME_RUNNING = 2
};
2.3.3.7 車燈開(kāi)關(guān)屬性 VehicleLightSwitch

下面是 types.hal 中定義的車燈開(kāi)關(guān)屬性

/**
 * Used by lights switch properties to enumerate user selected switch setting.
 * 由燈開(kāi)關(guān)屬性使用,枚舉用戶選擇的開(kāi)關(guān)設(shè)置。
 * XXX_LIGHTS_SWITCH properties report the switch settings that the user
 * selects.  The switch setting may be decoupled from the state reported if the
 * user selects AUTOMATIC.
 * XXX_LIGHTS_SWITCH 屬性報(bào)告用戶選擇的開(kāi)關(guān)設(shè)置。如果用戶選擇 AUTOMATIC,開(kāi)關(guān)設(shè)置可能與報(bào)告的狀態(tài)分離。
 */
enum VehicleLightSwitch : int32_t {
    OFF = 0,
    ON = 1,
    /**
     * Daytime running lights mode.  Most cars automatically use DRL but some
     * cars allow the user to activate them manually.
     * 日間行車燈模式。大多數(shù)汽車自動(dòng)使用DRL,但有些汽車允許用戶手動(dòng)激活它們。
     */
    DAYTIME_RUNNING = 2,
    /**
     * Allows the vehicle ECU to set the lights automatically
     * 允許車輛ECU自動(dòng)設(shè)置燈光
     */
    AUTOMATIC = 0x100,
};
2.3.3.8 車輛充電連接線類型 EvConnectorType

下面是 types.hal 中定義的車輛充電連接線類型屬性

/**
 * Used by INFO_EV_CONNECTOR_TYPE to enumerate the type of connectors
 * available to charge the vehicle.
 * 由 INFO_EV_CONNECTOR_TYPE 使用,枚舉可用于給車輛充電的連接器類型。
 */
enum EvConnectorType : int32_t {
    /**
     * Default type if the vehicle does not know or report the EV connector
     * type.
     * 如果車輛不知道或不報(bào)告EV連接器類型,則默認(rèn)類型
     */
    UNKNOWN = 0,
    IEC_TYPE_1_AC = 1,              // aka Yazaki
    IEC_TYPE_2_AC = 2,              // aka Mennekes
    IEC_TYPE_3_AC = 3,              // aka Scame
    IEC_TYPE_4_DC = 4,              // aka CHAdeMO
    IEC_TYPE_1_CCS_DC = 5,          // aka Combo 1
    IEC_TYPE_2_CCS_DC = 6,          // aka Combo 2
    TESLA_ROADSTER = 7,
    TESLA_HPWC = 8,
    TESLA_SUPERCHARGER = 9,
    GBT_AC = 10,
    GBT_DC = 11,

    /**
     * Connector type to use when no other types apply. Before using this
     * value, work with Google to see if the EvConnectorType enum can be
     * extended with an appropriate value.
     */
    OTHER = 101,
};
2.3.3.9 端口位置屬性 PortLocationType

下面是 types.hal 中定義的用于枚舉燃油門或燃油口位置屬性。

/**
 * Used by INFO_FUEL_DOOR_LOCATION/INFO_CHARGE_PORT_LOCATION to enumerate fuel door or
 * ev port location.
 * 用于描述 INFO_FUEL_DOOR_LOCATION 和 INFO_CHARGE_PORT_LOCATION 信號(hào)的燃油門或燃油口位置。
 */
enum PortLocationType : int32_t {
    /**
     * Default type if the vehicle does not know or report the Fuel door
     * and ev port location.
     */
    UNKNOWN = 0,
    FRONT_LEFT = 1,
    FRONT_RIGHT = 2,
    REAR_RIGHT = 3,
    REAR_LEFT = 4,
    FRONT = 5,
    REAR = 6,
};
2.3.3.10 風(fēng)扇方向?qū)傩?VehicleHvacFanDirection

下面是 types.hal 中定義的風(fēng)扇方向?qū)傩浴?/p>

/**
 * Bit flags for fan direction
 * 風(fēng)扇方向的位標(biāo)志
 */
enum VehicleHvacFanDirection : int32_t {
    FACE = 0x1,
    FLOOR = 0x2,
    DEFROST = 0x4,
};
2.3.3.11 車輛油量屬性 VehicleOilLevel

下面是 types.hal 中定義的車輛油量屬性。

enum VehicleOilLevel : int32_t {
    /**
     * Oil level values
     */
    CRITICALLY_LOW = 0,
    LOW = 1,
    NORMAL = 2,
    HIGH = 3,
    ERROR = 4,
};
2.3.3.12 車輛輸入事件屬性 VehicleHwKeyInputAction

下面是 types.hal 中定義的車輛輸入事件屬性。

enum VehicleHwKeyInputAction : int32_t {
    /** Key down */
    ACTION_DOWN = 1, // 輸入事件按下

    /** Key up */
    ACTION_UP = 0, // 輸入事件抬起
};
2.3.3.13 車輛屬性修改模式 VehiclepropertyChangeMode

下面是 types.hal 中定義的屬性是否可以改變的配置。

/**
 * This describes how value of property can change.
 * 描述屬性是否可以改變
 */
enum VehiclePropertyChangeMode : int32_t {
    /**
     * Property of this type must never be changed. Subscription is not supported
     * for these properties.
     * STATIC 表示屬性不可修改
     */
    STATIC = 0x00,

    /**
     * Properties of this type must report when there is a change.
     * IVehicle#get call must return the current value.
     * Set operation for this property is assumed to be asynchronous. When the
     * property is read (using IVehicle#get) after IVehicle#set, it may still
     * return old value until underlying H/W backing this property has actually
     * changed the state. Once state is changed, the property must dispatch
     * changed value as event.
     * ON_CHANGE 表示屬性必須在改變時(shí)報(bào)告
     */
    ON_CHANGE = 0x01,

    /**
     * Properties of this type change continuously and require a fixed rate of
     * sampling to retrieve the data.  Implementers may choose to send extra
     * notifications on significant value changes.
     * CONTINUOUS 屬性在不斷變化,需要固定的速率來(lái)檢索數(shù)據(jù)
     */
    CONTINUOUS = 0x02,
};
2.3.3.14 車輛屬性訪問(wèn) VehiclePropertyAccess

下面是 types.hal 中定義的車輛屬性訪問(wèn)配置。

/**
 * Property config defines the capabilities of it. User of the API
 * must first get the property config to understand the output from get()
 * commands and also to ensure that set() or events commands are in sync with
 * the expected output.
 * 屬性定義功能訪問(wèn)模式。
 */
enum VehiclePropertyAccess : int32_t {
    NONE = 0x00,

    READ = 0x01, // 只讀
    WRITE = 0x02, // 只寫(xiě)
    READ_WRITE = 0x03, // 讀寫(xiě)
};
2.3.3.15 車輛屬性狀態(tài) VehiclePropertyStatus

下面是 types.hal 中定義的車輛屬性狀態(tài)。

/**
 * Property status is a dynamic value that may change based on the vehicle state.
 * 屬性狀態(tài)是一個(gè)動(dòng)態(tài)值,可能會(huì)根據(jù)車輛狀態(tài)而改變。
 */
enum VehiclePropertyStatus : int32_t {
    /** Property is available and behaving normally */
    AVAILABLE   = 0x00, // 屬性可用且運(yùn)行正常
    /**
     * A property in this state is not available for reading and writing.  This
     * is a transient state that depends on the availability of the underlying
     * implementation (e.g. hardware or driver). It MUST NOT be used to
     * represent features that this vehicle is always incapable of.  A get() of
     * a property in this state MAY return an undefined value, but MUST
     * correctly describe its status as UNAVAILABLE A set() of a property in
     * this state MAY return NOT_AVAILABLE. The HAL implementation MUST ignore
     * the value of the status field when writing a property value coming from
     * Android.
     */
    UNAVAILABLE = 0x01, // 處于此狀態(tài)的屬性不可用于讀寫(xiě)。這是一種瞬態(tài),依賴于底層實(shí)現(xiàn)的可用性(例如硬件或驅(qū)動(dòng)程序)。
    /** There is an error with this property. */
    ERROR       = 0x02,
};
2.3.3.16 汽車齒輪屬性 VehicleGear

下面是 types.hal 中定義的汽車齒輪屬性。

/**
 * Various gears which can be selected by user and chosen in system.
 * 各種齒輪可由用戶選擇,并在系統(tǒng)中選擇。
 */
enum VehicleGear : int32_t {
    GEAR_NEUTRAL = 0x0001,
    GEAR_REVERSE = 0x0002,
    GEAR_PARK = 0x0004,
    GEAR_DRIVE = 0x0008,
    GEAR_1 = 0x0010,
    GEAR_2 = 0x0020,
    GEAR_3 = 0x0040,
    GEAR_4 = 0x0080,
    GEAR_5 = 0x0100,
    GEAR_6 = 0x0200,
    GEAR_7 = 0x0400,
    GEAR_8 = 0x0800,
    GEAR_9 = 0x1000,
};
2.3.3.17 汽車座椅區(qū)域?qū)傩?VehicleAreaSeat

下面是 types.hal 中定義的汽車座椅區(qū)域?qū)傩浴?/p>

/**
 * Various Seats in the car.
 * 汽車?yán)锏母鞣N座位。
 */
enum VehicleAreaSeat : int32_t {
    ROW_1_LEFT   = 0x0001,
    ROW_0_CENTER = 0x0002,
    ROW_1_RIGHT  = 0x0004,
    ROW_2_LEFT   = 0x0010,
    ROW_2_CENTER = 0x0020,
    ROW_2_RIGHT  = 0x0040,
    ROW_3_LEFT   = 0x0100,
    ROW_3_CENTER = 0x0200,
    ROW_3_RIGHT  = 0x0400
};
2.3.3.18 汽車玻璃區(qū)域?qū)傩?VehicleAreaWindow

下面是 types.hal 中定義的汽車玻璃區(qū)域?qū)傩浴?/p>

/**
 * Various windshields/windows in the car.
 * 汽車的各種擋風(fēng)玻璃/窗戶。
 */
enum VehicleAreaWindow : int32_t {
    FRONT_WINDSHIELD  = 0x00000001, // 前擋風(fēng)玻璃
    REAR_WINDSHIELD   = 0x00000002, // 后擋風(fēng)玻璃
    ROW_1_LEFT        = 0x00000010,
    ROW_1_RIGHT       = 0x00000040,
    ROW_2_LEFT        = 0x00000100,
    ROW_2_RIGHT       = 0x00000400,
    ROW_3_LEFT        = 0x00001000,
    ROW_3_RIGHT       = 0x00004000,

    ROOF_TOP_1        = 0x00010000,
    ROOF_TOP_2        = 0x00020000,

};
2.3.3.19 車輛門區(qū)域?qū)傩?VehicleAreaDoor

下面是 types.hal 中定義的車輛門區(qū)域?qū)傩浴?/p>

enum VehicleAreaDoor : int32_t {
    ROW_1_LEFT = 0x00000001,
    ROW_1_RIGHT = 0x00000004,
    ROW_2_LEFT = 0x00000010,
    ROW_2_RIGHT = 0x00000040,
    ROW_3_LEFT = 0x00000100,
    ROW_3_RIGHT = 0x00000400,
    HOOD = 0x10000000,
    REAR = 0x20000000,
};
2.3.3.20 車輛鏡子區(qū)域?qū)傩?VehicleAreaMirror

下面是 types.hal 中定義的車輛鏡子區(qū)域?qū)傩浴?/p>

enum VehicleAreaMirror : int32_t {
    DRIVER_LEFT = 0x00000001,
    DRIVER_RIGHT = 0x00000002,
    DRIVER_CENTER = 0x00000004,
};
2.3.3.21 車輛轉(zhuǎn)向燈屬性 VehicleTurnSignal

下面是 types.hal 中定義的車輛轉(zhuǎn)向燈屬性。

enum VehicleTurnSignal : int32_t {
    NONE = 0x00,
    RIGHT = 0x01,
    LEFT = 0x02,
};
2.3.3.22 車輛區(qū)域配置結(jié)構(gòu)體 VehicleAreaConfig

下面是 types.hal 中定義的車輛區(qū)域配置結(jié)構(gòu)體。

struct VehicleAreaConfig {
    /**
     * Area id is ignored for VehiclePropertyGroup:GLOBAL properties.
     * 對(duì)于全局屬性,忽略 Area 區(qū)域 id。
     */
    int32_t areaId;

    /**
     * If the property has @data_enum, leave the range to zero.
     *
     * Range will be ignored in the following cases:
     *    - The VehiclePropertyType is not INT32, INT64 or FLOAT.
     *    - Both of min value and max value are zero.
     */

    int32_t minInt32Value;
    int32_t maxInt32Value;

    int64_t minInt64Value;
    int64_t maxInt64Value;

    float minFloatValue;
    float maxFloatValue;
};
2.3.3.23 車輛屬性配置 VehiclePropConfig

下面是 types.hal 中定義的車輛屬性配置。

struct VehiclePropConfig { // Vehicle Property 的配置
    /** Property identifier */
    int32_t prop; // property 標(biāo)識(shí)符

    /**
     * Defines if the property is read or write or both.
     */
    VehiclePropertyAccess access; // 定義屬性是讀還是寫(xiě),還是兩者兼而有之

    /**
     * Defines the change mode of the property.
     */
    VehiclePropertyChangeMode changeMode; // 定義屬性的更改模式

    /**
     * Contains per-area configuration.
     */
    vec<VehicleAreaConfig> areaConfigs; // 包含每個(gè)區(qū)域的配置

    /** Contains additional configuration parameters */
    vec<int32_t> configArray; // 包含其他配置參數(shù)

    /**
     * Some properties may require additional information passed over this
     * string. Most properties do not need to set this.
     */
    string configString; // 某些屬性可能需要通過(guò)該字符串傳遞額外的信息

    /**
     * Min sample rate in Hz.
     * Must be defined for VehiclePropertyChangeMode::CONTINUOUS
     */
    float minSampleRate; // 最小采樣率(Hz)

    /**
     * Must be defined for VehiclePropertyChangeMode::CONTINUOUS
     * Max sample rate in Hz.
     */
    float maxSampleRate; // 最大采樣率(Hz)
};
2.3.3.24 車輛屬性值 VehiclePropValue

下面是 types.hal 中定義的車輛屬性值。

/**
 * Encapsulates the property name and the associated value. It
 * is used across various API calls to set values, get values or to register for
 * events.
 * 封裝屬性名和關(guān)聯(lián)值。它在各種 API 調(diào)用中用于設(shè)置值、獲取值或注冊(cè)事件。
 */
struct VehiclePropValue {
    /** Time is elapsed nanoseconds since boot */
    int64_t timestamp; // 從 boot 開(kāi)始的時(shí)間

    /**
     * Area type(s) for non-global property it must be one of the value from
     * VehicleArea* enums or 0 for global properties.
     * 對(duì)于非全局屬性,區(qū)域類型必須是VehicleArea*枚舉中的值之一;對(duì)于全局屬性必須是0。
     */
    int32_t areaId;

    /** Property identifier */
    int32_t prop; // 屬性標(biāo)識(shí)符

    /** Status of the property */
    VehiclePropertyStatus status; // 屬性狀態(tài)

    /**
     * Contains value for a single property. Depending on property data type of
     * this property (VehiclePropetyType) one field of this structure must be filled in.
     * 包含單個(gè)屬性的值。根據(jù)該屬性的屬性數(shù)據(jù)類型(vehiclepetytype),必須填充該結(jié)構(gòu)的一個(gè)字段。
     */
    struct RawValue {
        /**
         * This is used for properties of types VehiclePropertyType#INT
         * and VehiclePropertyType#INT_VEC
         */
        vec<int32_t> int32Values;

        /**
         * This is used for properties of types VehiclePropertyType#FLOAT
         * and VehiclePropertyType#FLOAT_VEC
         */
        vec<float> floatValues;

        /** This is used for properties of type VehiclePropertyType#INT64 */
        vec<int64_t> int64Values;

        /** This is used for properties of type VehiclePropertyType#BYTES */
        vec<uint8_t> bytes;

        /** This is used for properties of type VehiclePropertyType#STRING */
        string stringValue;
    };

    RawValue value;
};

2.4 啟動(dòng)流程

2.4.1 VehicleHal 類圖

下面是 VehicleHal 的類圖
AndroidAutomotive模塊介紹(四)VehicleHal介紹,Android Automotive,android

2.4.2 VehicleHal 啟動(dòng)序列圖

下面是 VehicleHal 啟動(dòng)序列圖
AndroidAutomotive模塊介紹(四)VehicleHal介紹,Android Automotive,android

2.4.3 VehicleHal 啟動(dòng)流程
2.4.3.1 VehicleService.cpp

VehicleHal 的入口文件是 VehicleService.cpp。路徑為:android/hardware/interfaces/automotive/vehicle/2.0/default。下面是 VehicleService.cpp 的內(nèi)容:

#define LOG_TAG "automotive.vehicle@2.0-service"
#include <android/log.h>
#include <hidl/HidlTransportSupport.h>

#include <iostream>

#include <vhal_v2_0/VehicleHalManager.h>
#include <vhal_v2_0/EmulatedVehicleHal.h>

using namespace android;
using namespace android::hardware;
using namespace android::hardware::automotive::vehicle::V2_0;

int main(int /* argc */, char* /* argv */ []) {
    // 創(chuàng)建 VehiclePropertyStore 對(duì)象
    auto store = std::make_unique<VehiclePropertyStore>();
    // 創(chuàng)建 EmulatedVehicleHal 對(duì)象
    auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get());
    // 創(chuàng)建 VehicleEmulator 對(duì)象
    auto emulator = std::make_unique<impl::VehicleEmulator>(hal.get());
    // 創(chuàng)建 VehicleHalManager 對(duì)象
    auto service = std::make_unique<VehicleHalManager>(hal.get());

    configureRpcThreadpool(4, true /* callerWillJoin */);

    // 注冊(cè) VehicleService 服務(wù)
    ALOGI("Registering as service...");
    status_t status = service->registerAsService();

    if (status != OK) {
        ALOGE("Unable to register vehicle service (%d)", status);
        return 1;
    }

    ALOGI("Ready");
    joinRpcThreadpool();

    return 1;
}

從 VehicleService.cpp 中可以發(fā)現(xiàn),主要初始化了 Vehicle 相關(guān)服務(wù)類,并注冊(cè) Vehicle 服務(wù)。下面可以來(lái)簡(jiǎn)單跟蹤下各類的功能。

2.4.3.2 VehiclePropertyStore.cpp

VehiclePropertyStore 類是用于封裝與存儲(chǔ)和訪問(wèn)配置、存儲(chǔ)和修改車輛屬性值相關(guān)的工作。內(nèi)部主要維護(hù)一個(gè) PropertyMap mPropertyValues,PropertyMap = std::map<RecordId, VehiclePropValue>;用于通過(guò) RecordId 保存對(duì)應(yīng)的 VehiclePropValue 值。

VehiclePropValue.h :

android/hardware/interfaces/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h

VehiclePropertyStore.cpp :

android/hardware/interfaces/automotive/vehicle/2.0/default/common/src/VehiclePropertyStore.cpp

車輛屬性在 VehiclePropertyStore 是存儲(chǔ)在有序的 Map 集合中,這樣可以更加方便的獲取屬性的值。VehiclePropertyStore 的使用是線程安全的,方法間使用同步阻塞保證線程安全。

下面是 VehiclePropertyStore.h 頭文件的內(nèi)容:

class VehiclePropertyStore {
public:
    /* Function that used to calculate unique token for given VehiclePropValue */
    using TokenFunction = std::function<int64_t(const VehiclePropValue& value)>;

private:
    // 定義 RecordConfig 結(jié)構(gòu)體
    struct RecordConfig {
        VehiclePropConfig propConfig;
        TokenFunction tokenFunction;
    };

    // 定義 RecordId 結(jié)構(gòu)體
    struct RecordId {
        int32_t prop; // propid
        int32_t area; // areaid
        int64_t token;

        bool operator==(const RecordId& other) const;
        bool operator<(const RecordId& other) const;
    };

    // 定義 RecordId 和 vehiclePropValue 對(duì)應(yīng)的 Map 集合
    using PropertyMap = std::map<RecordId, VehiclePropValue>;
    using PropertyMapRange = std::pair<PropertyMap::const_iterator, PropertyMap::const_iterator>;

public:
    // 注冊(cè) Property 函數(shù)
    void registerProperty(const VehiclePropConfig& config, TokenFunction tokenFunc = nullptr);

    /* Stores provided value. Returns true if value was written returns false if config for
     * example wasn't registered. */
    // 寫(xiě)入 VehiclePropValue 值
    bool writeValue(const VehiclePropValue& propValue, bool updateStatus);

    // 移除 VehiclePropValue 值
    void removeValue(const VehiclePropValue& propValue);
    // 通過(guò) propId 移除 VehiclePropValue 值
    void removeValuesForProperty(int32_t propId);

    // 獲取所有的 VehiclePropValue 值
    std::vector<VehiclePropValue> readAllValues() const;
    std::vector<VehiclePropValue> readValuesForProperty(int32_t propId) const;
    std::unique_ptr<VehiclePropValue> readValueOrNull(const VehiclePropValue& request) const;
    std::unique_ptr<VehiclePropValue> readValueOrNull(int32_t prop, int32_t area = 0,
                                                      int64_t token = 0) const;

    // 獲取所有的 VehiclePropConfig 值
    std::vector<VehiclePropConfig> getAllConfigs() const;
    // 根據(jù) propId 獲取 VehiclePropConfig 值
    const VehiclePropConfig* getConfigOrNull(int32_t propId) const;
    const VehiclePropConfig* getConfigOrDie(int32_t propId) const;

private:
    RecordId getRecordIdLocked(const VehiclePropValue& valuePrototype) const;
    const VehiclePropValue* getValueOrNullLocked(const RecordId& recId) const;
    PropertyMapRange findRangeLocked(int32_t propId) const;

private:
    using MuxGuard = std::lock_guard<std::mutex>;
    mutable std::mutex mLock;
    std::unordered_map<int32_t /* VehicleProperty */, RecordConfig> mConfigs;

    PropertyMap mPropertyValues;  // Sorted map of RecordId : VehiclePropValue.
};
2.4.3.3 EmulatedVehicleHal

EmulatedVehicleHal 的文件路徑如下:

EmulatedVehicleHal.h 路徑為:

android/hardware/interfaces/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h

EmulatedVehicleHal.cpp 路徑為:

android/hardware/interfaces/automotive/vehicle/2.0/defaultandroid/hardware/interfaces/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp

EmulatedVehicleHal 可以理解為 VehicleHal 功能的真正實(shí)施類,EmulatedVehicleHal 實(shí)現(xiàn)了 EmulatedVehicleHalIface 和 VehicleHal 的功能。上層的 Binder 在 Hal 層的流轉(zhuǎn)后,最終是通過(guò) EmulatedVehicleHal 去處理的。下面是 EmulatedVehicleHal 頭文件的內(nèi)容:

class EmulatedVehicleHal : public EmulatedVehicleHalIface { // EmulatedVehicleHalIface 繼承了 VehicleHal
public:
    EmulatedVehicleHal(VehiclePropertyStore* propStore);
    ~EmulatedVehicleHal() = default;
    
    //  Methods from VehicleHal
    // 實(shí)現(xiàn)了 VehicleHal 接口功能,上層的 Binder 調(diào)用會(huì)調(diào)用到這里
    void onCreate() override;
    std::vector<VehiclePropConfig> listProperties() override;
    VehiclePropValuePtr get(const VehiclePropValue& requestedPropValue,
                            StatusCode* outStatus) override;
    StatusCode set(const VehiclePropValue& propValue) override;
    StatusCode subscribe(int32_t property, float sampleRate) override;
    StatusCode unsubscribe(int32_t property) override;

    //  Methods from EmulatedVehicleHalIface
    // 實(shí)現(xiàn)了 EmulatedVehicleHalIface 接口功能
    bool setPropertyFromVehicle(const VehiclePropValue& propValue) override;
    std::vector<VehiclePropValue> getAllProperties() const override;
    
private:
    constexpr std::chrono::nanoseconds hertzToNanoseconds(float hz) const {
        return std::chrono::nanoseconds(static_cast<int64_t>(1000000000L / hz));
    }   
    
    StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request);
    void onFakeValueGenerated(const VehiclePropValue& value);
    VehiclePropValuePtr createApPowerStateReq(VehicleApPowerStateReq req, int32_t param);
    VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode,
                                             int32_t targetDisplay); 
                                             
    void onContinuousPropertyTimer(const std::vector<int32_t>& properties);
    bool isContinuousProperty(int32_t propId) const;
    void initStaticConfig();
    void initObd2LiveFrame(const VehiclePropConfig& propConfig);
    void initObd2FreezeFrame(const VehiclePropConfig& propConfig);
    StatusCode fillObd2FreezeFrame(const VehiclePropValue& requestedPropValue,
                                   VehiclePropValue* outValue);
    StatusCode fillObd2DtcInfo(VehiclePropValue* outValue);
    StatusCode clearObd2FreezeFrames(const VehiclePropValue& propValue);

    /* Private members */
    VehiclePropertyStore* mPropStore;
    std::unordered_set<int32_t> mHvacPowerProps;
    RecurrentTimer mRecurrentTimer;
    GeneratorHub mGeneratorHub;
};
2.4.3.4 VehicleEmulator

VehicleEmulator 的文件路徑如下:

VehicleEmulator.h 的文件路徑為:android/hardware/interfaces/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.h

VehicleEmulator.cpp 的文件路徑為:

android/hardware/interfaces/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.cpp

VehicleEmulator 的解釋是通過(guò) ADB 或 Pipe 從主機(jī)端提供控制接口來(lái)模擬車輛。

VehicleEmulator 可以理解為通過(guò) SPI 通信與 MCU 芯片建立通信,連通車身 Can 網(wǎng)絡(luò)來(lái)獲取車輛的信號(hào)的處理類。廠商基于 VehicleEmulator 的功能搭建廠商自身的車身通信功能,例如通過(guò) DBus 與 MCU 通信,獲取來(lái)自 MCU 的車身數(shù)據(jù);MCU 通過(guò) Can 網(wǎng)絡(luò)獲取車身其他固件,例如空調(diào)、座椅等其他 ECU 件的數(shù)據(jù)。

下面是 VehicleEmulator.h 文件的內(nèi)容:

class VehicleEmulator;  // Forward declaration.

/** Extension of VehicleHal that used by VehicleEmulator. */
// 定義 EmulatedVehicleHalIface 類,擴(kuò)展 VehicleHal 接口。
class EmulatedVehicleHalIface : public VehicleHal {
public:
    virtual bool setPropertyFromVehicle(const VehiclePropValue& propValue) = 0;
    virtual std::vector<VehiclePropValue> getAllProperties() const = 0;

    void registerEmulator(VehicleEmulator* emulator) {
        ALOGI("%s, emulator: %p", __func__, emulator);
        std::lock_guard<std::mutex> g(mEmulatorLock);
        mEmulator = emulator;
    }

protected:
    VehicleEmulator* getEmulatorOrDie() {
        std::lock_guard<std::mutex> g(mEmulatorLock);
        if (mEmulator == nullptr) abort();
        return mEmulator;
    }

private:
    mutable std::mutex mEmulatorLock;
    VehicleEmulator* mEmulator;
};

/**
 * Emulates vehicle by providing controlling interface from host side either through ADB or Pipe.
 */
// 定義 VehicleEmulator 類,通過(guò) socket、pipe 模擬車輛
class VehicleEmulator : public MessageProcessor {
   public:
    VehicleEmulator(EmulatedVehicleHalIface* hal);
    virtual ~VehicleEmulator();

    void doSetValueFromClient(const VehiclePropValue& propValue);
    void processMessage(emulator::EmulatorMessage const& rxMsg,
                        emulator::EmulatorMessage& respMsg) override;

   private:
    friend class ConnectionThread;
    using EmulatorMessage = emulator::EmulatorMessage;

    void doGetConfig(EmulatorMessage const& rxMsg, EmulatorMessage& respMsg);
    void doGetConfigAll(EmulatorMessage const& rxMsg, EmulatorMessage& respMsg);
    void doGetProperty(EmulatorMessage const& rxMsg, EmulatorMessage& respMsg);
    void doGetPropertyAll(EmulatorMessage const& rxMsg, EmulatorMessage& respMsg);
    void doSetProperty(EmulatorMessage const& rxMsg, EmulatorMessage& respMsg);
    void populateProtoVehicleConfig(emulator::VehiclePropConfig* protoCfg,
                                    const VehiclePropConfig& cfg);
    void populateProtoVehiclePropValue(emulator::VehiclePropValue* protoVal,
                                       const VehiclePropValue* val);

private:
    EmulatedVehicleHalIface* mHal;
    std::unique_ptr<SocketComm> mSocketComm;
    std::unique_ptr<PipeComm> mPipeComm;
};
2.4.3.5 VehicleHalManager

VehicleHalManager 的文件路徑如下:

VehicleHalManager.h 文件路徑為:android/hardware/interfaces/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHalManager.h

VehicleHalManager.cpp 文件路徑為:

android/hardware/interfaces/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp

VehicleHalManager 類是 IVehicle HIDL 接口和廠商實(shí)現(xiàn)之間的一個(gè)代理。VehicleHalManager 直接繼承了 IVehicle,上層調(diào)用 Hild 接口時(shí),會(huì)最先調(diào)用到此類中,VehicleHalManager 在初始化時(shí)獲取 VehicleHal 對(duì)象,廠商需要實(shí)現(xiàn) VehicleHal 類以提供 VehicleHal 的功能。

下面是 VehicleHalManager.h 文件的內(nèi)容:

/**
 * This class is a thick proxy between IVehicle HIDL interface and vendor's implementation.
 *
 * It has some boilerplate code like batching and caching property values, checking permissions,
 * etc. Vendors must implement VehicleHal class.
 */
// VehicleHalManager 繼承 IVehicle 類,提供 Hidl 接口調(diào)用
class VehicleHalManager : public IVehicle {
public:
    // 構(gòu)造函數(shù)需要傳入 VehicleHal 類對(duì)象,具體 Hidl 接口功能實(shí)現(xiàn)由 VehicleHal 提供
    VehicleHalManager(VehicleHal* vehicleHal)
        : mHal(vehicleHal),
          mSubscriptionManager(std::bind(&VehicleHalManager::onAllClientsUnsubscribed,
                                         this, std::placeholders::_1)) {
        init();
    }

    virtual ~VehicleHalManager();

    void init();

    // ---------------------------------------------------------------------------------------------
    // Methods derived from IVehicle 實(shí)現(xiàn) Hidl 接口函數(shù)
    Return<void> getAllPropConfigs(getAllPropConfigs_cb _hidl_cb)  override;
    Return<void> getPropConfigs(const hidl_vec<int32_t>& properties,
                                getPropConfigs_cb _hidl_cb)  override;
    Return<void> get(const VehiclePropValue& requestedPropValue,
                     get_cb _hidl_cb)  override;
    Return<StatusCode> set(const VehiclePropValue& value)  override;
    Return<StatusCode> subscribe(const sp<IVehicleCallback>& callback,
                                const hidl_vec<SubscribeOptions>& options)  override;
    Return<StatusCode> unsubscribe(const sp<IVehicleCallback>& callback,
                                   int32_t propId)  override;
    Return<void> debugDump(debugDump_cb _hidl_cb = nullptr) override;

private:
    using VehiclePropValuePtr = VehicleHal::VehiclePropValuePtr;
    // Returns true if needs to call again shortly.
    using RetriableAction = std::function<bool()>;

    // ---------------------------------------------------------------------------------------------
    // Events received from VehicleHal
    void onHalEvent(VehiclePropValuePtr  v);
    void onHalPropertySetError(StatusCode errorCode, int32_t property,
                               int32_t areaId);

    // ---------------------------------------------------------------------------------------------
    // This method will be called from BatchingConsumer thread
    void onBatchHalEvent(const std::vector<VehiclePropValuePtr >& values);

    void handlePropertySetEvent(const VehiclePropValue& value);

    const VehiclePropConfig* getPropConfigOrNull(int32_t prop) const;

    bool checkWritePermission(const VehiclePropConfig &config) const;
    bool checkReadPermission(const VehiclePropConfig &config) const;
    void onAllClientsUnsubscribed(int32_t propertyId);

    static bool isSubscribable(const VehiclePropConfig& config,
                               SubscribeFlags flags);
    static bool isSampleRateFixed(VehiclePropertyChangeMode mode);
    static float checkSampleRate(const VehiclePropConfig& config,
                                 float sampleRate);
    static ClientId getClientId(const sp<IVehicleCallback>& callback);
private:
    VehicleHal* mHal;  // 保存 VehicleHal 對(duì)象
    std::unique_ptr<VehiclePropConfigIndex> mConfigIndex;
    SubscriptionManager mSubscriptionManager;

    hidl_vec<VehiclePropValue> mHidlVecOfVehiclePropValuePool;

    ConcurrentQueue<VehiclePropValuePtr> mEventQueue;
    BatchingConsumer<VehiclePropValuePtr> mBatchingConsumer;
    VehiclePropValuePool mValueObjectPool;
};

3、總結(jié)

本篇主要描述了 Android 原生的 Automotive 框架中 VehicleHal 的邏輯。簡(jiǎn)單來(lái)說(shuō),VehicleHal 層主要是完成了對(duì)上層 Hidl 接口功能的實(shí)現(xiàn),具體實(shí)現(xiàn)依賴廠商的邏輯,從框架上是封裝了廠商的 VechielHal 實(shí)現(xiàn),提供車輛網(wǎng)絡(luò)信號(hào)的設(shè)置和獲取功能。

上一篇:AndroidAutomotive模塊介紹(三)CarService服務(wù)

到了這里,關(guān)于AndroidAutomotive模塊介紹(四)VehicleHal介紹的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Android Automotive 14(2) 多屏模擬器

    Android Automotive 14(2) 多屏模擬器

    上篇說(shuō)到AAOS14 (Android Automotive OS 14)環(huán)境搭建完畢,今天記錄一下操作模擬器多屏的過(guò)程。 從Android Automotive OS 14 Releases看,第一項(xiàng)更新重點(diǎn)介紹了 Car Framework Display and Window Manager ,比如在multi-user方面的更新: 從目前的新能源車型看,越來(lái)越多的車型,配置了豐富的車內(nèi)屏幕,

    2024年02月21日
    瀏覽(56)
  • Android Studio Automotive虛擬設(shè)備創(chuàng)建過(guò)程

    Android Studio Automotive虛擬設(shè)備創(chuàng)建過(guò)程

    AS添加運(yùn)行Automotive設(shè)備的過(guò)程 虛擬器的創(chuàng)建過(guò)程就是在Device Manager里添加對(duì)應(yīng)設(shè)備并且再選擇對(duì)應(yīng)的鏡像版本最后產(chǎn)生虛擬設(shè)備 如下過(guò)程: 可以看到,有手機(jī)、平板、穿戴設(shè)備、TV、Automotive等設(shè)備 點(diǎn)擊下方的 New Hardware Profile我們可以自己創(chuàng)建設(shè)備,選擇設(shè)備類型、分辨率、

    2024年02月19日
    瀏覽(28)
  • Android GNSS 模塊分析(一)整體介紹 - App

    Android GNSS 模塊分析(一)整體介紹 - App

    目錄 1、前言 2、Android GNSS 介紹 3、Android GNSS 各層級(jí)流程分析 ? ? ? ? 3.1 API 接口層 ? ? ? ? 3.2 Framework 服務(wù)層 ? ? ? ? 3.3 JNI 層級(jí)調(diào)用 ? ? ? ? 3.4 Native 層 / Hal 層 4、GNSS NMEA 數(shù)據(jù)概述 正文 1 前言 ????????大家好,本章節(jié)是介紹 Android GNSS 整體框架服務(wù)。此篇為學(xué)習(xí)記錄

    2023年04月09日
    瀏覽(16)
  • Android UpdateEngine 模塊分析(三)升級(jí)觸發(fā)以及Action機(jī)制介紹

    Android UpdateEngine 模塊分析(三)升級(jí)觸發(fā)以及Action機(jī)制介紹

    前面分析了 UpdateEngine 模塊的編譯和啟動(dòng)流程,對(duì)于 UpdateEngine 模塊已經(jīng)有了初步的了解,接下來(lái)我們從升級(jí)的功能出發(fā),分析 UpdateEngine 的升級(jí)過(guò)程,升級(jí)過(guò)程的內(nèi)容非常的多,準(zhǔn)備從 UpdateEngine 的 Action 機(jī)制開(kāi)始分析,UpdateEngine 的升級(jí)過(guò)程有很多步驟,每一個(gè)步驟由一個(gè)

    2024年02月05日
    瀏覽(21)
  • Android14之Android Rust模塊編譯語(yǔ)法(一百八十七)

    Android14之Android Rust模塊編譯語(yǔ)法(一百八十七)

    簡(jiǎn)介: CSDN博客專家,專注Android/Linux系統(tǒng),分享多mic語(yǔ)音方案、音視頻、編解碼等技術(shù),與大家一起成長(zhǎng)! 優(yōu)質(zhì)專欄: Audio工程師進(jìn)階系列 【 原創(chuàng)干貨持續(xù)更新中…… 】?? 優(yōu)質(zhì)專欄: 多媒體系統(tǒng)工程師系列 【 原創(chuàng)干貨持續(xù)更新中…… 】?? 人生格言: 人生從來(lái)沒(méi)有捷徑

    2024年02月22日
    瀏覽(46)
  • Android與EPS8266模塊通信(一)編寫(xiě)Android客戶端

    Android與EPS8266模塊通信(一)編寫(xiě)Android客戶端

    開(kāi)發(fā)環(huán)境 Windows 10 Android Studio 2021.2.1 編寫(xiě)布局文件,這里需要兩個(gè)按鈕,一個(gè)按鈕用來(lái)連接esp8266開(kāi)啟的熱點(diǎn),一個(gè)按鈕用來(lái)控制LED的開(kāi)啟和關(guān)閉。 布局效果圖 4. 編碼MainActivity代碼,ESP8266的IP地址為192.168.4.1,端口號(hào)為80 運(yùn)行在真機(jī)上的效果圖 最后,完整源碼下載地址 https

    2024年02月11日
    瀏覽(19)
  • Android -BLE 藍(lán)牙模塊開(kāi)發(fā)

    Android-Ble藍(lán)牙開(kāi)發(fā)Demo示例–掃描,連接,發(fā)送和接收數(shù)據(jù),分包解包(附源碼) - 簡(jiǎn)書(shū) 前言 萬(wàn)物互聯(lián)的物聯(lián)網(wǎng)時(shí)代的已經(jīng)來(lái)臨,ble藍(lán)牙開(kāi)發(fā)在其中扮演著舉重若輕的角色。最近剛好閑一點(diǎn),抽時(shí)間梳理下這塊的知識(shí)點(diǎn)。 涉及ble藍(lán)牙通訊的客戶端(開(kāi)啟、掃描、連接、發(fā)送... https://

    2024年02月09日
    瀏覽(26)
  • Android.mk 常用模塊類型

    生成的是動(dòng)態(tài)庫(kù)(.so 文件) 生成的是靜態(tài)庫(kù)(.a 文件) 用于編譯 Java 代碼并生成可執(zhí)行的 Java 程序(.jar 文件) 用于編譯 C/C++ 代碼并生成可執(zhí)行的 C/C++ 程序

    2024年02月02日
    瀏覽(19)
  • Android 出現(xiàn)4G模塊無(wú)法上網(wǎng)問(wèn)題

    Android 出現(xiàn)4G模塊無(wú)法上網(wǎng)問(wèn)題

    作者簡(jiǎn)介: 一個(gè)平凡而樂(lè)于分享的小比特,中南民族大學(xué)通信工程專業(yè)研究生在讀,研究方向無(wú)線聯(lián)邦學(xué)習(xí) 擅長(zhǎng)領(lǐng)域:驅(qū)動(dòng)開(kāi)發(fā),嵌入式軟件開(kāi)發(fā),BSP開(kāi)發(fā) 作者主頁(yè):一個(gè)平凡而樂(lè)于分享的小比特的個(gè)人主頁(yè) 文章收錄專欄:RK3568_Android11_驅(qū)動(dòng)開(kāi)發(fā),此專欄為RK3568開(kāi)發(fā)板And

    2024年04月23日
    瀏覽(32)
  • RK3588 Android 12 北斗模塊調(diào)試

    北斗模塊用的MTK RS1612M3 , http://www.sragps.com/web/down.html,可以查看相關(guān)資料,用串口和系統(tǒng)通訊 Android12中主要包括串口設(shè)備樹(shù)修改,GPS2.0加載,gps.default.so編譯和上層應(yīng)用測(cè)試,以下主要記錄測(cè)試中碰到的難點(diǎn) 板子上用的串口8,因此打開(kāi)uart8的設(shè)備樹(shù)配置 uart8 { status = “okay”;

    2024年02月15日
    瀏覽(31)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包