当前位置: 首页 > news >正文

AndroidAutomotive模块介绍(四)VehicleHal介绍

前言

前面的文章中,描述了 Android Automotive 的框架中应用、Framework 层服务等知识,本篇文章将会继续按照 Android Automotive 框架介绍 Vehicle Hal 层服务的内容。

上一篇:AndroidAutomotive模块介绍(三)CarService服务

正文

1、VehicleHal 介绍

本篇文档将对 Andorid Automotive 框架中 VehicleHal 层展开介绍。VehicleHal 即为车辆硬件抽象层的定义。可以理解为 Android Automotive OS 中的硬件抽象层接口,包括车辆属性和方法;各厂商制造商会根据定义的 Hal 接口,实现定制化的模块服务。

VehicleHal 是链接 Android Automotive Car Services 与制造商实现车辆控制服务进程的桥梁,通过标准化接口对上层提供服务,对于服务的实现依赖厂商的定制化,可以忽略汽车制造商的具体实现,也就是说 CarService 调用 VehicleHal 定义的标准接口,厂商实现这些接口。

2、VehicleHal 模块功能

2.1 rc 文件

VehicleHal 的代码路径为:android/hardware/interfaces/automotive/vehicle/2.0/default。路径下有 android.hardware.automotive.vehicle@2.0-service.rc 文件,在开机阶段通过此 rc 文件,将 VehicleHal 进程启动,下面来看下 android.hardware.automotive.vehicle@2.0-service.rc 文件的定义

service vendor.vehicle-hal-2.0 /vendor/bin/hw/android.hardware.automotive.vehicle@2.0-serviceclass haluser vehicle_networkgroup system inet
    2.2 编译

    对于 VehicleHal 的编译,可以对以下两个 Android.bp 文件介绍。

    • Hidl 接口编译
    • VehicleHal 服务编译

    VehicleHal 定义的 Hal 接口编译介绍,Android.bp 文件路径为:android/hardware/interfaces/automotive/vehicle/2.0,目录结构如下:

    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 接口编译,包含三个文件 types.hal、IVehicle.hal、IVehicleCallback.hal 文件。

        VehicleHal 服务编译介绍,Android.bp 文件路径为:android/hardware/interfaces/automotive/vehicle/2.0/default,目录结构如下:

        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 的服务名为 android.hardware.automotive.vehicle@2.0-service,启动 rc 文件是 android.hardware.automotive.vehicle@2.0-service.rc,入口文件是 VehicleService.cpp,依赖自定义相关模块主要有 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 目录下的文件所编译的内容,主要是 VehicleHal 所以来的模块。

          android.hardware.automotive.vehicle@2.0-default-impl-lib 模块是 impl 目录下的文件所编译的内容,主要是 VehicleHal 的功能实现模块。

          android.hardware.automotive.vehicle@2.0-libproto-native 模块是 impl/vhal_v2_0/proto 目录下的文件所编译的内容,目录下的文件为 VehicleHalProto.proto 文件,是一种序列化存储数据的方式。

          2.3 HIDL 接口

          Android Automotive 框架中 Hal 层接口文件有三个,IVehicle.hal、IVehicleCallback.hal 和 types.hal 文件。IVehicle.hal 文件中定义了 Vehicle Hal 对外提供的接口;IVehicleCallback.hal 文件中定义了 VehicleHal 的回调接口;types.hal 文件定义了 Vehicle Hal 的属性定义。

          Hidl 文件路径为:android/hardware/interfaces/automotive/vehicle/2.0。

          2.3.1 IVehicle.hal

          IVehicle.hal 文件中定义了 Vehicle Hal 对外提供的接口,上层 CarService 通过 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* 返回给定属性的属性配置列表。* 如果请求的车辆属性没有找到,它必须返回StatusCode::INVALID_ARG,否则返回一个车辆属性配置列表,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.* 获取车辆属性值。* 对于 VehiclePropertyChangeMode::STATIC 的属性值,此方法会返回同一个值,不会改变。* 对于 VehiclePropertyChangeMode::ON_CHANGE 的属性值,此方法会返回最新值。*/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.* 设置车辆属性值。* 特殊场景:* 设置一些属性值需要其初始状态可用,如果初始状态不可用,需要返回 StatusCode::TRY_AGAIN。* 设置单独电源控制的属性,如果属性未上电,需要返回 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.* 订阅属性* 客户端可以一次订阅多个属性,这取决于 options 定义的参数。* 参数 SubscribeOptions 包含 属性id、区域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.* 取消订阅属性* 如果客户端在此前没有对此属性进行订阅,则返回 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.** 打印车辆的调试状态。*/debugDump() generates (string s);
          };
            2.3.2 IVehicleCallback.hal

            IVehicleCallback.hal 文件定义了 VehicleHal 的回调对象,上层 CarService 通过注册此回调对象以监听属性是否改变。VehicleHal 通过回调对象返回状态给到客户端。

            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.* 当需要报告客户端订阅的变量时,就会调用此回调函数。* 这可能基于常规按频率上报或者客户端调用 IVehicle#set 函数时调用。*/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 标志订阅属性,并且调用 IVehicle#set 函数,则回调此方法。*/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* 设置属性通常是异步操作,客户端调用 IVehicle#set 函数到接收到 StatusCode::OK 的返回值,也不能保证此属性成功传播到车辆网络,如果发生这种低概率的事件,则回调此方法。* @ errorCode:StatusCode 枚举中的任何值。* @ property:发生错误的属性。* @ areaId:指定问题发生在哪个区域的位掩码,对于全局属性必须为 0。*/oneway onPropertySetError(StatusCode errorCode,int32_t propId,int32_t areaId);
            };
              2.3.3 types.hal

              types.hal 中定义了 VehicleHal 的属性、结构等数据。

              2.3.3.1 车辆属性 VehiclePropertyType

              下面列举 types.hal 中定义的 VehiclePropertyType 属性:

              package android.hardware.automotive.vehicle@2.0;/*** Enumerates supported data type for VehicleProperty.* 枚举 VehicleProperty 支持的数据类型。* Used to create property ID in VehicleProperty enum.* 用于在 VehicleProperty enum 中创建属性 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, // 这两个主要就是 VehicleProperty 用来进行或运算的。MASK            = 0x00ff0000
              };
              
                2.3.3.2 车辆区域属性 VehicleArea

                下面是 types.hal 中定义的车辆区域属性:

                /*** Vehicle Areas* Used to construct property IDs in the VehicleProperty enum.* 用于在VehicleProperty enum中构造属性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.* 某些属性可能与特定车辆区域相关。例如,VehicleProperty:DOOR_LOCK 属性必须与特定的门相关联,因此该属性必须标记为 VehicleArea: door 标志。** Other properties may not be associated with particular vehicle area,* these kind of properties must have VehicleArea:GLOBAL flag.* 其他属性可能不与特定的车辆区域相关联,这些属性必须具有VehicleArea:GLOBAL标志。** [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, // 全局区域/** WINDOW maps to enum VehicleAreaWindow */WINDOW      = 0x03000000, // 窗户区域/** MIRROR maps to enum VehicleAreaMirror */MIRROR      = 0x04000000, // 反光镜区域/** SEAT maps to enum VehicleAreaSeat */SEAT        = 0x05000000, // 座椅区域/** DOOR maps to enum VehicleAreaDoor */DOOR        = 0x06000000, // 车门区域/** WHEEL maps to enum VehicleAreaWheel */WHEEL       = 0x07000000, // 车轮区域YFVehicleAreaTire = 0x08000000,MASK        = 0x0f000000,
                };
                
                  2.3.3.3 车辆属性分组类型 VehiclePropertyGroup

                  下面是 types.hal 中定义的车辆属性分组类型:

                  /*** Enumerates property groups.* 车辆属性分组枚举** Used to create property ID in VehicleProperty enum.* 用于在VehicleProperty enum中创建属性ID。*/
                  enum VehiclePropertyGroup : int32_t { // AndroidO 之后的 treble,用于区分 android 原生的 property 和厂商的 property。/*** Properties declared in AOSP must use this flag.* AOSP 原生的属性标志*/SYSTEM      = 0x10000000,/*** Properties declared by vendors must use this flag.* 厂商自定义的属性标志*/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* 车辆型号** @change_mode VehiclePropertyChangeMode:STATIC* @access VehiclePropertyAccess:READ*/INFO_MODEL = (0x0102| VehiclePropertyGroup:SYSTEM // 原生属性| VehiclePropertyType:STRING // 属性值是 String 类型| VehicleArea:GLOBAL), // 全局属性
                    ...
                    };
                    
                    2.3.3.5 车辆座位占用状态 VehicleSeatOccupancyState

                    下面是 types.hal 中定义的车辆座位占用状态值

                    /*** Used by seat occupancy to enumerate the current occupancy state of the seat.* 由座位占用使用,以枚举座位的当前占用状态*/
                    enum  VehicleSeatOccupancyState : int32_t {UNKNOWN = 0,VACANT = 1, // 空闲OCCUPIED = 2 // 占用
                    };
                    
                      2.3.3.6 灯光状态属性 VehicleLightState

                      下面是 types.hal 中定义的灯光状态属性

                      /*** Used by lights state properties to enumerate the current state of the lights.* 由灯光状态属性使用,枚举灯光的当前状态。* Most XXX_LIGHTS_STATE properties will only report ON and OFF states.  Only* the HEADLIGHTS_STATE property will report DAYTIME_RUNNING.* 大多数 XXX_LIGHTS_STATE 属性将只报告 ON 和 OFF 状态。只有 headlight_state 属性会报告 DAYTIME_RUNNING。*/
                      enum  VehicleLightState : int32_t {OFF = 0,ON = 1,DAYTIME_RUNNING = 2
                      };
                      
                        2.3.3.7 车灯开关属性 VehicleLightSwitch

                        下面是 types.hal 中定义的车灯开关属性

                        /*** Used by lights switch properties to enumerate user selected switch setting.* 由灯开关属性使用,枚举用户选择的开关设置。* 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 属性报告用户选择的开关设置。如果用户选择 AUTOMATIC,开关设置可能与报告的状态分离。*/
                        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.* 日间行车灯模式。大多数汽车自动使用DRL,但有些汽车允许用户手动激活它们。*/DAYTIME_RUNNING = 2,/*** Allows the vehicle ECU to set the lights automatically* 允许车辆ECU自动设置灯光*/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.* 如果车辆不知道或不报告EV连接器类型,则默认类型*/UNKNOWN = 0,IEC_TYPE_1_AC = 1,              // aka YazakiIEC_TYPE_2_AC = 2,              // aka MennekesIEC_TYPE_3_AC = 3,              // aka ScameIEC_TYPE_4_DC = 4,              // aka CHAdeMOIEC_TYPE_1_CCS_DC = 5,          // aka Combo 1IEC_TYPE_2_CCS_DC = 6,          // aka Combo 2TESLA_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 信号的燃油门或燃油口位置。*/
                            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 风扇方向属性 VehicleHvacFanDirection

                              下面是 types.hal 中定义的风扇方向属性。

                              /*** Bit flags for fan direction* 风扇方向的位标志*/
                              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 表示属性必须在改变时报告*/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 属性在不断变化,需要固定的速率来检索数据*/CONTINUOUS = 0x02,
                                    };
                                    
                                      2.3.3.14 车辆属性访问 VehiclePropertyAccess

                                      下面是 types.hal 中定义的车辆属性访问配置。

                                      /*** 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.* 属性定义功能访问模式。*/
                                      enum VehiclePropertyAccess : int32_t {NONE = 0x00,READ = 0x01, // 只读WRITE = 0x02, // 只写READ_WRITE = 0x03, // 读写
                                      };
                                      
                                        2.3.3.15 车辆属性状态 VehiclePropertyStatus

                                        下面是 types.hal 中定义的车辆属性状态。

                                        /*** Property status is a dynamic value that may change based on the vehicle state.* 属性状态是一个动态值,可能会根据车辆状态而改变。*/
                                        enum VehiclePropertyStatus : int32_t {/** Property is available and behaving normally */AVAILABLE   = 0x00, // 属性可用且运行正常/*** 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, // 处于此状态的属性不可用于读写。这是一种瞬态,依赖于底层实现的可用性(例如硬件或驱动程序)。/** 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.* 各种齿轮可由用户选择,并在系统中选择。*/
                                          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 汽车座椅区域属性 VehicleAreaSeat

                                            下面是 types.hal 中定义的汽车座椅区域属性。

                                            /*** Various Seats in the car.* 汽车里的各种座位。*/
                                            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 汽车玻璃区域属性 VehicleAreaWindow

                                              下面是 types.hal 中定义的汽车玻璃区域属性。

                                              /*** Various windshields/windows in the car.* 汽车的各种挡风玻璃/窗户。*/
                                              enum VehicleAreaWindow : int32_t {FRONT_WINDSHIELD  = 0x00000001, // 前挡风玻璃REAR_WINDSHIELD   = 0x00000002, // 后挡风玻璃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 车辆门区域属性 VehicleAreaDoor

                                                下面是 types.hal 中定义的车辆门区域属性。

                                                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 车辆镜子区域属性 VehicleAreaMirror

                                                  下面是 types.hal 中定义的车辆镜子区域属性。

                                                  enum VehicleAreaMirror : int32_t {DRIVER_LEFT = 0x00000001,DRIVER_RIGHT = 0x00000002,DRIVER_CENTER = 0x00000004,
                                                  };
                                                  
                                                    2.3.3.21 车辆转向灯属性 VehicleTurnSignal

                                                    下面是 types.hal 中定义的车辆转向灯属性。

                                                    enum VehicleTurnSignal : int32_t {NONE = 0x00,RIGHT = 0x01,LEFT = 0x02,
                                                    };
                                                    
                                                      2.3.3.22 车辆区域配置结构体 VehicleAreaConfig

                                                      下面是 types.hal 中定义的车辆区域配置结构体。

                                                      struct VehicleAreaConfig {/*** Area id is ignored for VehiclePropertyGroup:GLOBAL properties.* 对于全局属性,忽略 Area 区域 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 标识符/*** Defines if the property is read or write or both.*/VehiclePropertyAccess access; // 定义属性是读还是写,还是两者兼而有之/*** Defines the change mode of the property.*/VehiclePropertyChangeMode changeMode; // 定义属性的更改模式/*** Contains per-area configuration.*/vec<VehicleAreaConfig> areaConfigs; // 包含每个区域的配置/** Contains additional configuration parameters */vec<int32_t> configArray; // 包含其他配置参数/*** Some properties may require additional information passed over this* string. Most properties do not need to set this.*/string configString; // 某些属性可能需要通过该字符串传递额外的信息/*** 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.* 封装属性名和关联值。它在各种 API 调用中用于设置值、获取值或注册事件。*/
                                                        struct VehiclePropValue {/** Time is elapsed nanoseconds since boot */int64_t timestamp; // 从 boot 开始的时间/*** Area type(s) for non-global property it must be one of the value from* VehicleArea* enums or 0 for global properties.* 对于非全局属性,区域类型必须是VehicleArea*枚举中的值之一;对于全局属性必须是0。*/int32_t areaId;/** Property identifier */int32_t prop; // 属性标识符/** Status of the property */VehiclePropertyStatus status; // 属性状态/*** Contains value for a single property. Depending on property data type of* this property (VehiclePropetyType) one field of this structure must be filled in.* 包含单个属性的值。根据该属性的属性数据类型(vehiclepetytype),必须填充该结构的一个字段。*/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 启动流程
                                                          2.4.1 VehicleHal 类图

                                                          下面是 VehicleHal 的类图
                                                          在这里插入图片描述

                                                          2.4.2 VehicleHal 启动序列图

                                                          下面是 VehicleHal 启动序列图
                                                          在这里插入图片描述

                                                          2.4.3 VehicleHal 启动流程
                                                          2.4.3.1 VehicleService.cpp

                                                          VehicleHal 的入口文件是 VehicleService.cpp。路径为:android/hardware/interfaces/automotive/vehicle/2.0/default。下面是 VehicleService.cpp 的内容:

                                                          #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 */ []) {// 创建 VehiclePropertyStore 对象auto store = std::make_unique<VehiclePropertyStore>();// 创建 EmulatedVehicleHal 对象auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get());// 创建 VehicleEmulator 对象auto emulator = std::make_unique<impl::VehicleEmulator>(hal.get());// 创建 VehicleHalManager 对象auto service = std::make_unique<VehicleHalManager>(hal.get());configureRpcThreadpool(4, true /* callerWillJoin */);// 注册 VehicleService 服务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 中可以发现,主要初始化了 Vehicle 相关服务类,并注册 Vehicle 服务。下面可以来简单跟踪下各类的功能。

                                                            2.4.3.2 VehiclePropertyStore.cpp

                                                            VehiclePropertyStore 类是用于封装与存储和访问配置、存储和修改车辆属性值相关的工作。内部主要维护一个 PropertyMap mPropertyValues,PropertyMap = std::map<RecordId, VehiclePropValue>;用于通过 RecordId 保存对应的 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 是存储在有序的 Map 集合中,这样可以更加方便的获取属性的值。VehiclePropertyStore 的使用是线程安全的,方法间使用同步阻塞保证线程安全。

                                                            下面是 VehiclePropertyStore.h 头文件的内容: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 功能的真正实施类,EmulatedVehicleHal 实现了 EmulatedVehicleHalIface 和 VehicleHal 的功能。上层的 Binder 在 Hal 层的流转后,最终是通过 EmulatedVehicleHal 去处理的。下面是 EmulatedVehicleHal 头文件的内容:

                                                            class EmulatedVehicleHal : public EmulatedVehicleHalIface { // EmulatedVehicleHalIface 继承了 VehicleHal
                                                            public:EmulatedVehicleHal(VehiclePropertyStore* propStore);~EmulatedVehicleHal() = default;//  Methods from VehicleHal// 实现了 VehicleHal 接口功能,上层的 Binder 调用会调用到这里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// 实现了 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 的解释是通过 ADB 或 Pipe 从主机端提供控制接口来模拟车辆。

                                                              VehicleEmulator 可以理解为通过 SPI 通信与 MCU 芯片建立通信,连通车身 Can 网络来获取车辆的信号的处理类。厂商基于 VehicleEmulator 的功能搭建厂商自身的车身通信功能,例如通过 DBus 与 MCU 通信,获取来自 MCU 的车身数据;MCU 通过 Can 网络获取车身其他固件,例如空调、座椅等其他 ECU 件的数据。

                                                              下面是 VehicleEmulator.h 文件的内容:

                                                              class VehicleEmulator;  // Forward declaration./** Extension of VehicleHal that used by VehicleEmulator. */
                                                              // 定义 EmulatedVehicleHalIface 类,扩展 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 类,通过 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 接口和厂商实现之间的一个代理。VehicleHalManager 直接继承了 IVehicle,上层调用 Hild 接口时,会最先调用到此类中,VehicleHalManager 在初始化时获取 VehicleHal 对象,厂商需要实现 VehicleHal 类以提供 VehicleHal 的功能。

                                                                下面是 VehicleHalManager.h 文件的内容:

                                                                /*** 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 接口调用
                                                                class VehicleHalManager : public IVehicle {
                                                                public:// 构造函数需要传入 VehicleHal 类对象,具体 Hidl 接口功能实现由 VehicleHal 提供VehicleHalManager(VehicleHal* vehicleHal): mHal(vehicleHal),mSubscriptionManager(std::bind(&VehicleHalManager::onAllClientsUnsubscribed,this, std::placeholders::_1)) {init();}virtual ~VehicleHalManager();void init();// ---------------------------------------------------------------------------------------------// Methods derived from IVehicle 实现 Hidl 接口函数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 VehicleHalvoid onHalEvent(VehiclePropValuePtr  v);void onHalPropertySetError(StatusCode errorCode, int32_t property,int32_t areaId);// ---------------------------------------------------------------------------------------------// This method will be called from BatchingConsumer threadvoid 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 对象std::unique_ptr<VehiclePropConfigIndex> mConfigIndex;SubscriptionManager mSubscriptionManager;hidl_vec<VehiclePropValue> mHidlVecOfVehiclePropValuePool;ConcurrentQueue<VehiclePropValuePtr> mEventQueue;BatchingConsumer<VehiclePropValuePtr> mBatchingConsumer;VehiclePropValuePool mValueObjectPool;
                                                                };
                                                                

                                                                  本篇主要描述了 Android 原生的 Automotive 框架中 VehicleHal 的逻辑。简单来说,VehicleHal 层主要是完成了对上层 Hidl 接口功能的实现,具体实现依赖厂商的逻辑,从框架上是封装了厂商的 VechielHal 实现,提供车辆网络信号的设置和获取功能。

                                                                  上一篇:AndroidAutomotive模块介绍(三)CarService服务

                                                                  相关文章:

                                                                  AndroidAutomotive模块介绍(四)VehicleHal介绍

                                                                  前言 前面的文章中&#xff0c;描述了 Android Automotive 的框架中应用、Framework 层服务等知识&#xff0c;本篇文章将会继续按照 Android Automotive 框架介绍 Vehicle Hal 层服务的内容。 上一篇&#xff1a;AndroidAutomotive模块介绍&#xff08;三&#xff09;CarSer…...

                                                                  Pingora vs. Nginx vs. 其他主流代理服务器性能对比

                                                                  Pingora vs. Nginx vs. 其他主流代理服务器性能对比 核心对比概览 特性Pingora (Cloudflare)NginxEnvoyHAProxyCaddyTraefik开发公司CloudflareNginx, Inc/F5Lyft/CNCFHAProxy TechApache 2.0社区Containous核心语言RustCCCGoGo并发模型异步/多线程事件驱动事件驱动事件驱动协…...

                                                                  4月23日作业

                                                                  需求&#xff1a; 1&#xff0c;R5为ISP&#xff0c;其上只能配置IP地址&#xff1b; R5与其他所有直连设备间均使用公有IP&#xff1b;环回地址为100.1.1.1/32 2&#xff0c;R4设备为企业出口路由器 3&#xff0c;整个OSPF环境IP基于172.16.0.0/16划分&#xff1b; 4&…...

                                                                  5.学习笔记-SpringMVC(P53-P60)

                                                                  1.响应 &#xff08;1&#xff09;响应页面 &#xff08;2&#xff09;响应数据&#xff08;异步提交&#xff09;&#xff1a;文本数据、json数据 2.REST风格 (1)REST:表现形式状态转换。 (2)传统风格资源描述形式 3.Restful入门案例 5.基于RESTful页面数据…...

                                                                  安卓14默认赋予应用权限

                                                                  安卓14上赋予应用默认权限的方式跟之前的不太一样了 需要修改两个地方&#xff0c;一个是frameworks\base\services\core\java\com\android\server\pm\permission\Permission.java public boolean isNormal() {//eturn (mPermissionInfo.protectionLevel & PermissionInfo…...

                                                                  数据的加载与保存

                                                                  加载数据的方法 选项参数&#xff1a;可以通过选项参数传入URL地址、用户名、密码和数据表名称等。 路径参数&#xff1a;可以传入加载数据的路径。 MySQL语句&#xff1a;可以直接导入MySQL语句来加载数据。 保存数据的方法通用方法&#xff1a;使用df.write方法保存数据。…...

                                                                  网络编程——通信三要素

                                                                  一、概述 &#xff08;一&#xff09;网络编程 可以让设备中的程序与网络上的其他设备中的程序进行数据交互&#xff0c;实现网络通信 Java.net包下提供了网络编程的解决方案。 &#xff08;二&#xff09;通信的基本架构 1. CS架构&#xff08;Client客户端/Server服务端…...

                                                                  es-存储与搜索优化

                                                                  字段选型优化 链接&#xff1a;es-字段类型详解与优化建议 存储优化 es的底层使用Lucene,Lucene的存储的核心文件包括&#xff1a; 原始数据存储&#xff08;Store&#xff09;、倒排索引&#xff08;Inverted Index&#xff09;、列式存储&#xff08;DocValues&#xff09…...

                                                                  Hadoop 集群扩容新增节点操作文档

                                                                  Hadoop 集群扩容新增节点操作文档 一、前期准备 1. 环境检查&#xff08;所有新节点&#xff09; 确保 JDK 安装&#xff1a; java -version确保 Hadoop 安装&#xff1a; hadoop version添加主机名映射&#xff08;所有节点&#xff09;&#xff1a; cat >> /etc/h…...

                                                                  高光谱相机在工业检测中的应用:LED屏检、PCB板缺陷检测

                                                                  随着工业检测精度要求的不断提升&#xff0c;传统机器视觉技术逐渐暴露出对非可见光物质特性识别不足、复杂缺陷检出率低等局限性。高光谱相机凭借其独特的光谱分析能力&#xff0c;为工业检测提供了革命性的解决方案。以下结合中达瑞和VIX系列推扫式高光谱相机的技术特点与实际…...

                                                                  07-IDEA企业开发工具-开发入门程序

                                                                  1. IDEA创建Java项目的代码结构 项目结构: IDEA中的Java项目包含四种主要结构&#xff1a;工程(Project)、模块(Module)、包(Package)、类(Class)。 工程(Project): 代表整个项目&#xff0c;通常是一个磁盘目录或文件夹。模块(Module): 工程下的子单元&#xff0c;用于划分项…...

                                                                  即插即用模块(3) -LSK 特征提取

                                                                  paper&#xff1a;LSKNet: A Foundation Lightweight Backbone for Remote Sensing Code&#xff1a;https://github.com/zcablii/LSKNet 大型选择性内核块 (LSK Block) 功能 通过动态调整感受野&#xff0c;自适应提取遥感图像中目标的上下文信息&#xff0c;增强目标与环境关…...

                                                                  彩虹表攻击与Nest密码存储

                                                                  文章目录 前言&#x1f9e8; 什么是彩虹表攻击&#xff1f;&#x1f4f7; 图中解析左侧是彩虹表&#xff1a;右侧是用户数据库中的数据&#xff1a; &#x1f510; 如何防御彩虹表攻击&#xff1f;✅ 1. **使用 Salt 加密&#xff08;推荐&#xff09;**✅ 2. **使用强哈希函数…...

                                                                  vue keep-alive标签的运用

                                                                  keep-alive&#xff0c;想必大家都不会很陌生&#xff0c;在一些选项卡中会使用到。其实&#xff0c;它的作用大概就是把组件的数据给缓存起来。 比如果我有一个选项卡&#xff0c;标签一&#xff0c;标签二&#xff0c;标签三。现在&#xff0c;我需要实现&#xff0c;当我在标…...

                                                                  python编写一段爱心代码

                                                                  代码编写 1. 导入模块和常量定义 python import random from math import sin, cos, pi, log from tkinter import *CANVAS_WIDTH 640 # 画布的宽 CANVAS_HEIGHT 480 # 画布的高 CANVAS_CENTER_X CANVAS_WIDTH / 2 # 画布中心的X轴坐标 CANVAS_CENTER_Y CANVAS_HEIGH…...

                                                                  Python流程控制

                                                                  目录 一&#xff0c;条件判断&#xff1a;if语句 1.基本语法与示例 2.多重条件判断&#xff08;elif&#xff09; 3.常见错误与避坑指南 1.缩进错误 2.遗漏冒号 二&#xff0c;循环结构&#xff1a;while与for 1.while循环 2.Python的注释 3.字符串的格式化输出 4.fo…...

                                                                  机器人雅克比Jacobian矩阵程序

                                                                  % 定义机器人的连杆参数 L1 Link(d, 0, a, 0, alpha, pi/2); L2 Link(d, 0, a, 1, alpha, 0); L3 Link(d, 0, a, 1, alpha, 0);% 创建机器人对象 robot SerialLink([L1, L2, L3], name, MyRobot);% 设置机器人的关节角度&#xff08;弧度&#xff09; q [0, pi/4, pi/6];%…...

                                                                  Qt Creator中自定义应用程序的可执行文件图标

                                                                  要在Qt Creator中为你的应用程序设置自定义可执行文件图标&#xff0c;你需要按照以下步骤操作&#xff1a; Windows平台设置方法 准备图标文件&#xff1a; 创建一个.ico格式的图标文件&#xff08;推荐使用256x256像素&#xff0c;包含多种尺寸&#xff09; 可以使用在线工…...

                                                                  应该怎样理解“被劫持“

                                                                  通常, 在 iOS 开发相关的语境中&#xff0c;「被劫持」的精确定义 一句话&#xff1a;任何「未经应用或服务器授权&#xff0c;第三方改变了客户端—服务器之间解析结果、传输路径或数据内容」的情形&#xff0c;都视为网络被劫持。 具体可拆成 六大类&#xff0c;每类都对应可…...

                                                                  RocketMQ面试题:进阶部分

                                                                  &#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…...

                                                                  【k8s系列7-更新中】kubeadm搭建Kubernetes高可用集群-三主两从

                                                                  主机准备 结合前面的章节,这里需要5台机器,可以先创建一台虚拟机作为基础虚拟机。优先把5台机器的公共部分优先在一台机器上配置好 1、配置好静态IP地址 2、主机名宇IP地址解析 [root@localhost ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost…...

                                                                  12、高阶组件:魔法增幅器——React 19 HOC模式

                                                                  一、魔法增幅器的本质 "高阶组件是魔法师用咒语叠加的炼金术&#xff0c;"霍格沃茨魔咒研究院院长凝视着发光的增幅器&#xff0c;"通过函数式能量场的嵌套&#xff0c;让基础组件获得预言家日报式的逻辑继承&#xff01;" ——以神秘事务司的「维度叠加理…...

                                                                  Linux避免文件误删详解(Linux Avoids File Deletion Errors with Detailed Explanation)

                                                                  Linux避免文件误删详解 背景 大家都知道&#xff0c;rm指令在Linux中非常牛&#xff0c;rm -rf更是牛中的霸主。什么删系统跑路、删库跑路就是这个指令造成的。可以看出指令虽然牛&#xff0c;但是危险性极高。那么怎么避免某些时候的这种误操作造成的影响呢&#xff0c;阿祥…...

                                                                  模板方法模式:定义算法骨架的设计模式

                                                                  模板方法模式&#xff1a;定义算法骨架的设计模式 一、模式核心&#xff1a;模板方法定义算法骨架&#xff0c;具体步骤延迟到子类实现 在软件开发中&#xff0c;经常会遇到这样的情况&#xff1a;某个算法的步骤是固定的&#xff0c;但具体步骤的实现可能因不同情况而有所不…...

                                                                  QT之Q_PROPERTY介绍以及在QWidget中的用法

                                                                  目录 一、 Q_PROPERTY介绍 1、 Q_PROPERTY是什么 2、Q_PROPERTY 的语法 3、Q_PROPERTY 的作用 二、在QWidget中的用法 1、示例1&#xff1a;自带属性 2、 示例2&#xff1a;自建属性第一种 3、 示例3&#xff1a;自建属性第二种 4、动态属性 三、注意事项 四、总结 一…...

                                                                  MySQL 8 自动安装脚本(CentOS-7 系统)

                                                                  文章目录 一、MySQL 8 自动安装脚本脚本说明&#x1f4cc; 使用脚本前提条件1. 操作系统2. 用户权限3. 网络要求 &#x1f4cc; 脚本的主要功能1. 环境检查2. MySQL 自动安装3. 自动配置 MySQL4. 防火墙配置5. 验证与输出 &#x1f4cc; 适用场景 二、执行sh脚本1. 给予脚本执行…...

                                                                  软件测试基础知识(2) -- 软件评测师(十三)

                                                                  3 基于风险的测试 风险是当前未发生而未来有肯会发生并造成一定负面影响的事件。 3.1 基于风险的测试概述 &#xff08;1&#xff09;测试计划内容的核心&#xff1a; 1&#xff09;测什么&#xff1a;从风险出发&#xff0c;需要明确地列举出要测试哪些具体的功能和非功能的质…...

                                                                  axios 在请求拦截器中设置Content-Type无效问题

                                                                  Axios 会根据请求数据自动设置 Content-Type&#xff1a; 当请求体为空时&#xff0c;Axios 会移除 Content-Type 头部 当请求体为对象时&#xff0c;默认设置为 application/json 当请求体为 URLSearchParams 时&#xff0c;默认设置为 application/x-www-form-urlencoded …...

                                                                  MFC案例:使用键盘按键放大、缩小窗口图像的实验

                                                                  当在对话框窗口居中显示一幅图像时&#xff0c;图像的尺寸可能大于或小于窗口的尺寸&#xff0c;这时我们希望通过使用按键“”进行图像放大显示&#xff0c;使用按键“-”进行缩小显示&#xff08;当然也可以使用其它按键&#xff09;。下面开始使用MFC进行这个实验&#xff0…...

                                                                  本地(NAS/服务器)与云端(Docker/Kubernetes)部署详解与对比

                                                                  本地&#xff08;NAS/服务器&#xff09;与云端&#xff08;Docker/Kubernetes&#xff09;部署详解与对比 一、本地部署&#xff08;NAS/服务器&#xff09; 适用场景&#xff1a; 需要完全控制硬件和数据&#xff08;如隐私敏感场景&#xff09;。小规模应用或测试环境。网…...

                                                                  如何解决极狐GitLab 合并冲突?

                                                                  极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 合并冲突 (BASIC ALL) 合并冲突发生在合并请求的两个分支&#xff08;源分支和目标分支&#xff09;对相同代码行进行了不同…...

                                                                  DeepSeek在物联网设备中的应用:通过轻量化模型实现本地化数据分析

                                                                  文章目录 一、引言二、DeepSeek轻量化模型的技术原理1. 模型量化2. 模型剪枝3. 动态精度调整 三、本地化数据分析的实现路径1. 硬件环境配置2. 模型加载与推理3. 数据预处理与后处理 四、行业应用案例1. 医疗智能穿戴设备2. 工业设备预测性维护3. 智能家居能耗优化 五、性能优化…...

                                                                  opencv--图像

                                                                  像素(像素点) 定义&#xff1a; Pixel 是 Picture Element&#xff08;图像元素&#xff09;的缩写&#xff0c;是数字图像中最小的独立单位。每个像素代表图像中的一个点的颜色和亮度信息。 关键特性&#xff1a; 颜色&#xff1a;通过不同的色彩模型&#xff08;如RGB、CMYK…...

                                                                  【KWDB 创作者计划】_嵌入式硬件篇---数字电子器件

                                                                  文章目录 前言一、系列前缀(如 "74" 或 "54")74(商用级)54(工业级)二、逻辑家族(如 "LS"、"HC"、"HCT" 等)TTL(晶体管-晶体管逻辑)家族CMOS(互补金属氧化物半导体)家族BiCMOS(双极 CMOS)家族三、功能编号(如…...

                                                                  前端加密介绍与实战

                                                                  前端数据加密 文章目录 前端数据加密前端数据加密介绍为什么需要前端数据加密&#xff1f;前端数据加密的常见方式前端数据加密的实现场景&#xff1a;加密用户密码并发送到后端步骤 1&#xff1a;安装加密库步骤 2&#xff1a;实现加密逻辑步骤 3&#xff1a;后端解密 实战总结…...

                                                                  DAG(有向无环图)计算模型面试内容整理-拓扑排序(Topological Sort)和节点依赖与并行度

                                                                  拓扑排序(Topological Sort) 拓扑排序(Topological Sort): 拓扑排序是针对有向无环图(DAG)的一种线性排序方法。这种排序方法的特点是,对于DAG中的每一条有向边 (A → B),在拓扑排序中节点A总是排在节点B之前。...

                                                                  AI语音助手自定义角色百度大模型 【全新AI开发套件掌上AI+4w字教程+零基础上手】

                                                                  1、简介 此项目主要使用ESP32-S3实现一个自定义角色的AI语音聊天助手&#xff08;比如医生角色&#xff09;&#xff0c;可以通过该项目熟悉ESP32-S3 arduino的开发&#xff0c;百度语音识别&#xff0c;百度语音合成API调用&#xff0c;百度APPBuilder API的调用实现自定义角…...

                                                                  【Java面试笔记:基础】13.谈谈接口和抽象类有什么区别?

                                                                  在 Java 中,接口(Interface) 和 抽象类(Abstract Class) 都是实现多态和代码抽象的机制,但它们在设计目的、语法特性及使用场景上有显著差异。 1. 接口和抽象类的区别 接口(Interface) 定义:接口是对行为的抽象,是抽象方法的集合,用于定义 API 规范。 特点: 不能…...

                                                                  内存管理(Linux程序设计)

                                                                  内存管理 目录 内存管理 一.简单的内存分配 代码功能概述 代码流程图 变量声明 动态内存分配 内存分配错误检查 向内存写入字符串 设置退出状态并退出程序 二.请求全部的物理内存 代码功能概述 变量声明 三..可用内存 四.滥用内存 1.代码功能&#xff08;预期 …...

                                                                  Prompt 结构化提示工程

                                                                  Prompt 结构化提示工程 目前ai开发工具都大同小异&#xff0c;随着deepseek的流行&#xff0c;ai工具的能力都差不太多&#xff0c;功能基本都覆盖到了。而prompt能力反而是需要更加关注的&#xff08;说白了就是能不能把需求清晰的输出成文档&#xff09;。因此大家可能需要加…...

                                                                  Postman设置了Cookies但是请求不携带Cookie

                                                                  1 问题说明 使用Postman工具往往要向本地服务器发送请求携带Cookie便于测试接口&#xff0c;但是在Send下面的Cookies选项中设置域名127.0.0.1&#xff0c;并添加Cookie&#xff0c;发现发送的请求怎么都不会携带Cookie&#xff1a; 通过Fiddler抓包发现并没有Cookie&#xff1…...

                                                                  微服务Nacos组件的介绍、安装、使用

                                                                  微服务Nacos组件的介绍、安装、使用 在微服务架构日渐普及的今天&#xff0c;服务注册与配置管理成了系统架构中的关键环节。阿里巴巴开源的 Nacos&#xff08;Naming and Configuration Service&#xff09;正是解决这一问题的利器。本文将为你全面介绍 Nacos 的概念、安装方…...

                                                                  深度剖析塔能科技精准节能方案:技术创新与实践价值

                                                                  在能源管理领域不断追求高效与可持续发展的进程中&#xff0c;塔能科技的精准节能方案逐渐成为行业内备受瞩目的焦点。 精准节能&#xff1a;核心技术与实现路径 塔能科技的精准节能理念建立在对能源消耗的精细监测与深度分析基础之上。以其节能管理平台为例&#xff0c;该平台…...

                                                                  AI PPT创作原理解析:让你的演示文稿更智能

                                                                  在当今信息爆炸的时代&#xff0c;演示文稿已成为我们工作和学习中不可或缺的一部分。然而&#xff0c;制作一份高质量的PPT往往需要投入大量的时间和精力。随着人工智能技术的迅猛发展&#xff0c;AI PPT创作工具应运而生&#xff0c;极大地简化了PPT的制作过程。本文将深入解…...

                                                                  ollama本地搭建大模型

                                                                  dajdaj人工智能&#xff0c;现在流行的大模型有很多&#xff0c;像流行的&#xff1a;gpt-3.5-turbo、通义千问2.5&#xff0c;Llama3&#xff1b; 本地安装大模型有什么好处 大模型都是开源的&#xff0c;安装在自己的电脑上也是免费使用的&#xff1b;可以结合自己的私有文…...

                                                                  AIGC(生成式AI)试用 31 -- AI做软件程序测试 2

                                                                  接上文 AIGC&#xff08;生成式AI&#xff09;试用 30 -- AI做软件程序测试 1 整合测试项提问并输出测试用例思考并调整提问方式&#xff0c;为完整的输年程序测试提问准备 - 再次对需求提问 --> 实际是之前的提问记录找不到了&#xff0c;不过有新发现&#xff1b;不妨后…...

                                                                  【深度学习与大模型基础】第13章-什么是机器学习

                                                                  1. 什么是机器学习&#xff1f; 想象你在教一个小朋友认猫&#xff1a; 传统编程&#xff1a;你写一本《猫的100条特征手册》&#xff08;比如有胡须、尖耳朵&#xff09;&#xff0c;让计算机对照检查。 机器学习&#xff1a;你直接给计算机看1000张猫和狗的图片&#xff0c…...

                                                                  大数据利器Kafka

                                                                  大数据利器Kafka&#xff1a;从入门到实战的全面指南 在大数据的世界里&#xff0c;Kafka就像是一个高效的“数据快递员”&#xff0c;负责在不同的系统之间快速、可靠地传递数据。今天&#xff0c;咱们就一起来深入了解一下这个强大的工具。Kafka是由LinkedIn开发的分布式发布…...

                                                                  工具指南:免费将 PDF 转换为 Word 的 10 个工具

                                                                  可移植文档格式或 PDF 是大多数企业使用的流行文件格式&#xff0c;主要用于共享项目材料并确保整个团队协同工作。它还有助于避免处理大量文档和丢失关键数据。使用顶级 PDF 转换器还可以更轻松地高效地进行日常活动。企业可以依靠专业的文档扫描服务对其他格式的文档进行 PDF…...

                                                                  Elasticsearch复习笔记

                                                                  文章目录 ES 基础为什么用 Elasticsearch初识和安装概述安装 elasticsearch安装 Kibana 倒排索引正向索引倒排索引正向和倒排 基础概念文档和字段索引和映射MySQL 和 elasticsearch IK 分词器安装 IK 分词器使用 IK 分词器拓展词典 ES 索引库操作Mapping 映射属性ES 索引库的 C…...