Cảm biến đa HAL

Lớp HAL (HAL) cho cảm biến là một khung cho phép HAL cảm biến hoạt động cùng với HAL cảm biến khác. Cảm biến Multi-HAL cảm biến tải động các lớp HAL (HAL) cho cảm biến được lưu trữ dưới dạng thư viện động trên phân vùng nhà cung cấp và cung cấp cho họ lệnh gọi lại có thể xử lý các sự kiện đăng, thu nạp và mở khoá chế độ thức. Lớp trừu tượng phần cứng (HAL) của cảm biến là một lớp HAL (HAL) cho cảm biến, được tích hợp thành một đối tượng dùng chung trên phân vùng nhà cung cấp và được sử dụng bởi khung đa HAL. Các HAL phụ này không phụ thuộc vào nhau hoặc phụ thuộc vào mã nhiều-HAL có chứa hàm chính cho quy trình.

Sensors Multi-HAL 2.1 (có trên các thiết bị chạy Android 11 trở lên) là một phiên bản lặp lại của Sensors Multi-HAL 2.0, hỗ trợ tải các HAL phụ có thể hiển thị loại cảm biến góc bản lề. Để hỗ trợ loại cảm biến này, HAL phụ phải sử dụng các API HAL phụ được xác định trong Tiêu đề SubHal 2.1.

Đối với các thiết bị chạy Android 13 trở lên sử dụng Sensors AIDL HAL, bạn có thể sử dụng lớp shim nhiều HAL để cho phép nhiều chức năng HAL. Để biết thông tin chi tiết về cách triển khai, hãy xem phần Sử dụng cảm biến Multi-HAL với cảm biến AIDL HAL.

Sự khác biệt giữa Sensors Multi-HAL 2 và Sensors HAL 2

Cảm biến Multi-HAL 2, có trên các thiết bị chạy Android 10 trở lên, đưa ra một số đối tượng trừu tượng ở đầu HAL cảm biến 2 để giúp bạn để tương tác với API HAL. Cảm biến Multi-HAL 2 giới thiệu Proxy để xử lý việc triển khai giao diện HAL 2 của Cảm biến và V2_1/SubHal (hoặc V2_0/SubHal) để cho phép HalProxy tương tác với các HAL phụ.

Giao diện ISensorsSubHal khác với 2.1/ISensors.hal (hoặc 2.0/ISensors.hal) giao diện theo các cách sau:

  • Phương thức khởi tạo truyền một IHalProxyCallback thay vì hai FMQ và ISensorsCallback.
  • HAL phụ phải triển khai một hàm gỡ lỗi để cung cấp thông tin gỡ lỗi trong báo cáo lỗi.
  • HAL phụ phải triển khai hàm tên để HAL phụ đã tải khác biệt với các HAL phụ khác.

Điểm khác biệt chính giữa Sensors Multi-HAL 2 và Sensors HAL 2 là ở các hàm khởi chạy. Thay vì cung cấp FMQ, IHalProxyCallback giao diện cung cấp hai phương thức, một phương thức để đăng sự kiện cảm biến đến các cảm biến khung và một phương thức để tạo khoá chế độ thức. Ẩn sâu, Cảm biến Multi-HAL quản lý tất cả các hoạt động tương tác với FMQ để đảm bảo kịp thời phân phối sự kiện cảm biến cho tất cả các HAL phụ. Bạn nên sử dụng phương thức createScopedWakelock để uỷ quyền cho HAL phụ chịu trách nhiệm tính thời gian chờ khoá chế độ thức cho HAL đa cảm biến và tập trung việc sử dụng khoá chế độ thức vào một khoá chế độ thức chung cho toàn bộ HAL đa cảm biến, giúp giảm thiểu các lệnh gọi khoá và mở khoá.

Các cảm biến Multi-HAL 2 cũng được tích hợp sẵn một số tính năng an toàn. Phương thức này xử lý các trường hợp FMQ của cảm biến đã đầy hoặc khi khung cảm biến Android khởi động lại và cần đặt lại trạng thái cảm biến. Ngoài ra, khi các sự kiện được đăng lên lớp HalProxy nhưng khung cảm biến không thể chấp nhận các sự kiện ngay lập tức, Sensors Multi-HAL có thể di chuyển các sự kiện đó sang luồng trong nền để cho phép công việc tiếp tục trên tất cả các HAL phụ trong khi chờ đăng các sự kiện.

Mã nguồn và triển khai tham chiếu

Tất cả mã Multi-HAL của cảm biến đều có trong hardware/interfaces/sensors/common/default/2.X/multihal/. Dưới đây là gợi ý về một số tài nguyên.

  • HalProxy.h: Đối tượng HalProxy được tạo thực thể bằng nhiều lớp HAL (HAL) cho Cảm biến và xử lý truyền dữ liệu từ các HAL phụ sang khung cảm biến.
  • HalProxy.cpp: Việc triển khai HalProxy chứa tất cả logic cần thiết để giao tiếp đa điểm giữa các HAL phụ và khung cảm biến.
  • SubHal.h: Giao diện ISensorsSubHal xác định giao diện mà các lớp trừu tượng phụ (HAL) phải thực hiện theo để tương thích với HalProxy. HAL phụ triển khai phương thức khởi chạy để có thể sử dụng đối tượng HalProxyCallback cho postEventscreateScopedWakelock.

    Để triển khai Multi-HAL 2.0, hãy sử dụng phiên bản 2.0 của SubHal.h.

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/: Các bài kiểm thử đơn vị này xác minh việc triển khai HalProxy.

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/: Ví dụ về cách triển khai HAL phụ này sử dụng các cảm biến giả để tạo dữ liệu giả. Hữu ích để kiểm thử cách nhiều HAL phụ tương tác trên một thiết bị.

Triển khai

Phần này mô tả cách triển khai Lớp trừu tượng phần cứng (HAL) cho cảm biến trong phần sau trường hợp:

Sử dụng Sensors Multi-HAL với Sensors AIDL HAL

Để cho phép tính năng nhiều lớp trừu tượng (HAL) với lớp trừu tượng phần cứng (HAL) cho cảm biến, hãy nhập AIDL Mô-đun lớp đệm nhiều HAL, được tìm thấy trong phần cứng/giao diện/cảm biến/aidl/default/multihal/. Mô-đun này xử lý việc chuyển đổi giữa các loại định nghĩa HAL của cảm biến AIDL và HIDL, đồng thời xác định một trình bao bọc xung quanh giao diện nhiều HAL được mô tả trong phần Triển khai cảm biến nhiều HAL 2.1. Lớp đệm nhiều HAL của AIDL tương thích với các thiết bị triển khai Sensors Multi-HAL 2.1.

Lớp đệm nhiều HAL AIDL cho phép bạn hiển thị trình theo dõi đầu và các loại cảm biến IMU trục giới hạn trong HAL AIDL của cảm biến. Để sử dụng các loại cảm biến này do giao diện AIDL HAL xác định, hãy đặt trường type trong cấu trúc SensorInfo trong quá trình triển khai getSensorsList_2_1(). Việc này là an toàn vì các trường loại cảm biến được hỗ trợ bằng số nguyên của HAL cảm biến AIDL và HIDL không trùng lặp.

Triển khai cảm biến Multi-HAL 2.1

Để triển khai Cảm biến Multi-HAL 2.1 trên thiết bị mới, hãy làm theo các bước sau:

  1. Triển khai giao diện ISensorsSubHal như mô tả trong SubHal.h.
  2. Triển khai phương thức sensorsHalGetSubHal_2_1 trong SubHal.h.
  3. Thêm mục tiêu cc_library_shared để tạo HAL phụ mới triển khai. Khi thêm mục tiêu:

    1. Đảm bảo mục tiêu được đẩy đến một vị trí nào đó trên phân vùng của nhà cung cấp thiết bị.
    2. Trong tệp cấu hình nằm tại /vendor/etc/sensors/hals.conf, thêm đường dẫn đến thư viện trên một dòng mới. Nếu cần, hãy tạo Tệp hals.conf.

    Để biết ví dụ về mục nhập Android.bp để tạo thư viện HAL phụ, hãy xem hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp.

  4. Xoá tất cả android.hardware.sensors mục nhập khỏi manifest.xml chứa danh sách các HAL được hỗ trợ trên thiết bị.

  5. Xoá tất cả dịch vụ android.hardware.sensorsservice.rc tệp khỏi tệp device.mk và thêm android.hardware.sensors@2.1-service.multihalandroid.hardware.sensors@2.1-service.multihal.rc thành PRODUCT_PACKAGES.

Khi khởi động, HalProxy sẽ khởi động, tìm HAL phụ mới triển khai và khởi chạy HAL phụ đó bằng cách gọi sensorsHalGetSubHal_2_1.

Cổng từ Cảm biến Multi-HAL 2.0 sang Multi-HAL 2.1

Để chuyển từ Multi-HAL 2.0 sang Multi-HAL 2.1, hãy thực hiện SubHal giao diện và biên dịch lại HAL phụ của bạn.

Dưới đây là sự khác biệt giữa giao diện SubHal 2.0 và 2.1:

  • IHalProxyCallback sử dụng các kiểu được tạo trong phiên bản 2.1 của thông số kỹ thuật ISensors.hal.
  • Hàm initialize() truyền một giá trị mới IHalProxyCallback thay vì từ giao diện SubHal 2.0
  • Các lớp trừu tượng phần cứng phụ phải triển khai getSensorsList_2_1injectSensorData_2_1 thay vì getSensorsListinjectSensorData vì các phương thức này sử dụng các loại mới được thêm vào phiên bản 2.1 của thông số kỹ thuật ISensors.hal.
  • Các lớp trừu tượng phần cứng phụ phải hiển thị sensorsHalGetSubHal_2_1 thay vì sensorsHalGetSubHal cho Multi-HAL để coi chúng là phiên bản 2.1 HAL phụ.

Cổng từ Sensors HAL 2.0

Khi nâng cấp lên Sensors Multi-HAL 2.0 từ Sensors HAL 2.0, hãy đảm bảo việc triển khai HAL đáp ứng các yêu cầu sau.

Khởi chạy HAL

Cảm biến HAL 2.0 có chức năng khởi động cho phép dịch vụ cảm biến truyền FMQ và lệnh gọi lại cảm biến động. Trong Cảm biến Multi-HAL 2.0, Hàm initialize() truyền một lệnh gọi lại duy nhất phải được dùng để đăng các sự kiện cảm biến, nhận khoá chế độ thức cũng như thông báo về kết nối cảm biến động và ngắt kết nối.

Đăng các sự kiện cảm biến lên quy trình triển khai Multi-HAL

Thay vì đăng sự kiện cảm biến thông qua FMQ, HAL phụ phải ghi sự kiện cảm biến vào IHalProxyCallback khi có sự kiện cảm biến.

Sự kiện WAKE_UP

Trong Sensors HAL 2.0, HAL có thể quản lý khoá chế độ thức để triển khai. Trong Multi-HAL 2.0 của cảm biến, các HAL phụ cho phép triển khai Multi-HAL để quản lý khoá chế độ thức và có thể yêu cầu khoá chế độ thức bằng cách gọi createScopedWakelock. Bạn phải lấy và chuyển khoá chế độ thức trong phạm vi đã khoá đến postEvents khi đăng sự kiện đánh thức cho quá trình triển khai Multi-HAL.

Cảm biến động

Cảm biến Multi-HAL 2.0 yêu cầu onDynamicSensorsConnectedonDynamicSensorsDisconnected inch IHalProxyCallback được gọi bất cứ khi nào kết nối cảm biến động thay đổi. Các lệnh gọi lại này có sẵn trong con trỏ IHalProxyCallback được cung cấp thông qua hàm initialize().

Cổng từ Cảm biến HAL 1.0

Khi nâng cấp lên Cảm biến Multi-HAL 2.0 từ Cảm biến HAL 1.0, đảm bảo HAL đáp ứng các yêu cầu sau.

Khởi chạy HAL

Bạn phải hỗ trợ hàm initialize() để thiết lập lệnh gọi lại giữa HAL phụ và việc triển khai Đa HAL.

Hiển thị các cảm biến có sẵn

Trong Sensors Multi-HAL 2.0, hàm getSensorsList() phải trả về cùng một giá trị trong một lần khởi động thiết bị, ngay cả khi các cảm biến khởi động lại HAL. Điều này cho phép khung cố gắng thiết lập lại kết nối cảm biến nếu máy chủ hệ thống khởi động lại. Giá trị do getSensorsList() trả về có thể thay đổi sau khi thiết bị khởi động lại.

Đăng sự kiện cảm biến lên quá trình triển khai Multi-HAL

Trong Cảm biến HAL 2.0, thay vì đợi poll() được gọi, lớp HAL phụ phải chủ động ghi sự kiện cảm biến vào IHalProxyCallback bất cứ khi nào có sự kiện cảm biến.

Sự kiện WAKE_UP

Trong Cảm biến HAL 1.0, HAL có thể quản lý khóa chế độ thức để thực hiện. Trong Multi-HAL 2.0 của cảm biến, các HAL phụ cho phép triển khai Multi-HAL để quản lý khoá chế độ thức và có thể yêu cầu khoá chế độ thức bằng cách gọi createScopedWakelock. Bạn phải lấy và chuyển khoá chế độ thức trong phạm vi đã khoá đến postEvents khi đăng sự kiện đánh thức đến quá trình triển khai Multi-HAL.

Cảm biến động

Trong Cảm biến HAL 1.0, các cảm biến động được trả về thông qua hàm poll(). Sensors Multi-HAL 2.0 yêu cầu onDynamicSensorsConnectedonDynamicSensorsDisconnected trong IHalProxyCallback được gọi bất cứ khi nào các kết nối cảm biến động thay đổi. Những lệnh gọi lại này là có sẵn như một phần của con trỏ IHalProxyCallback được cung cấp qua hàm initialize().

Cổng từ Sensors Multi-HAL 1.0

Để chuyển một phương thức triển khai hiện có từ Sensors Multi-HAL 1.0, hãy làm theo các bước sau.

  1. Đảm bảo rằng cấu hình HAL của cảm biến nằm tại /vendor/etc/sensors/hals.conf. Quá trình này có thể bao gồm việc di chuyển tệp nằm lúc /system/etc/sensors/hals.conf.
  2. Xoá mọi tham chiếu đến hardware/hardware.hhardware/sensors.h vì những tính năng này không được hỗ trợ cho HAL 2.0.
  3. Chuyển các HAL phụ như mô tả trong phần Chuyển từ Sensors Hal 1.0.
  4. Đặt Sensors Multi-HAL 2.0 làm HAL được chỉ định bằng cách làm theo các bước 3 và 4 trong phần Triển khai Sensors Multi-HAL 2.0.

Xác nhận kết quả

Chạy VTS

Khi bạn đã tích hợp một hoặc nhiều HAL phụ với Cảm biến Multi-Hal 2.1, sử dụng Bộ thử nghiệm nhà cung cấp (VTS) để đảm bảo lớp trừu tượng phần cứng (HAL) phụ của bạn việc triển khai đáp ứng tất cả các yêu cầu do giao diện HAL của Cảm biến đặt ra.

Để chỉ chạy các bài kiểm tra VTS của cảm biến khi VTS được thiết lập trên máy chủ, thực thi các lệnh sau:

vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsHalSensorsV2_0Target && \
  vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsHalSensorsV2_1Target

Nếu bạn đang chạy lớp đệm AIDL Multi-HAL, hãy chạy VtsAidlHalSensorsTargetTest.

vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsAidlHalSensorsTargetTest

Chạy kiểm thử đơn vị

Các chương trình kiểm thử đơn vị trong HalProxy_test.cpp kiểm thử HalProxy bằng các HAL phụ giả mạo được tạo bản sao trong chương trình kiểm thử đơn vị và không được tải động. Khi tạo một HAL phụ mới, những bài kiểm thử này sẽ đóng vai trò là hướng dẫn về cách thêm kiểm thử đơn vị xác minh rằng HAL phụ mới được triển khai đúng cách.

Để chạy kiểm thử, hãy thực thi các lệnh sau:

cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest

Kiểm thử bằng các HAL phụ giả

Các lớp trừu tượng phụ (HAL) giả là những cách triển khai giả của giao diện ISensorsSubHal. Các HAL phụ hiển thị các danh sách cảm biến khác nhau. Khi cảm biến được kích hoạt, họ định kỳ đăng các sự kiện cảm biến được tạo tự động lên HalProxy dựa trên các khoảng thời gian được chỉ định trong một yêu cầu cảm biến nhất định.

Có thể sử dụng HAL phụ giả để kiểm tra xem mã Multi-HAL đầy đủ hoạt động như thế nào với các lớp HAL phụ khác được đưa vào hệ thống và để áp lực cho nhiều khía cạnh của Mã Multi-HAL của cảm biến.

Có hai HAL phụ giả mạo tại hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/.

Để tạo và đẩy các HAL phụ giả mạo đến một thiết bị, hãy thực hiện các bước sau:

  1. Chạy các lệnh sau để tạo và đẩy 3 loại giả HAL phụ cho thiết bị:

    $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests/
    mma
    adb push \
      $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so \
      /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so
    adb push \
      $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so \
      /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so
    adb push \
      $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so \
      /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
  2. Cập nhật cấu hình HAL cảm biến tại /vendor/etc/sensors/hals.conf bằng các đường dẫn cho các HAL phụ giả mạo.

    /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so
    /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so
    /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
    
  3. Khởi động lại HalProxy và tải các HAL phụ mới được liệt kê trong cấu hình.

    adb shell stop
    adb shell start

Gỡ lỗi

Nhà phát triển có thể gỡ lỗi cho khung này bằng cách dùng lệnh lshal. Để yêu cầu đầu ra gỡ lỗi của HAL Cảm biến, hãy chạy lệnh sau:

adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default

Sau đó, thông tin về trạng thái hiện tại của HalProxy và các lớp trừu tượng phần cứng (HAL phụ) của nó đến thiết bị đầu cuối. Dưới đây là ví dụ về kết quả lệnh cho đối tượng HalProxy và các HAL phụ giả mạo.

Internal values:
  Threads are running: true
  Wakelock timeout start time: 200 ms ago
  Wakelock timeout reset time: 73208 ms ago
  Wakelock ref count: 0
  # of events on pending write queue: 0
  # of non-dynamic sensors across all subhals: 8
  # of dynamic sensors across all subhals: 0
SubHals (2):
  Name: FakeSubHal-OnChange
  Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2
  Name: FakeSubHal-OnChange
  Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2

Nếu số được chỉ định cho # of events on pending write queue là một số lớn (1000 trở lên), thì điều này cho biết có nhiều sự kiện đang chờ ghi vào khung cảm biến. Điều này cho biết dịch vụ cảm biến bị tắc nghẽn hoặc gặp sự cố và không xử lý các sự kiện cảm biến, hoặc gần đây một lô lớn sự kiện cảm biến đã được đăng từ một HAL phụ.

Nếu số lượt tham chiếu khoá chế độ thức lớn hơn 0, thì tức là HalProxy đã có khoá chế độ thức. Giá trị này chỉ được lớn hơn 0 nếu ScopedWakelock được tổ chức một cách có chủ đích hoặc nếu sự kiện đánh thức được gửi tới HalProxy và có không được khung cảm biến xử lý.

Chỉ số mô tả tệp đã chuyển đến phương thức gỡ lỗi của HalProxy sẽ được chuyển đến mỗi HAL phụ để các nhà phát triển phải triển khai phương thức gỡ lỗi như một phần của Giao diện ISensorsSubHal.