HAL AIDL cảm biến

Lớp trừu tượng phần cứng (HAL) của cảm biến là giao diện giữa khung cảm biến Android và các cảm biến của thiết bị, chẳng hạn như gia tốc kế hoặc con quay hồi chuyển. HAL Cảm biến xác định các hàm phải được triển khai để cho phép khung kiểm soát các cảm biến.

Sensors AIDL HAL có trong Android 13 trở lên cho các thiết bị mới và thiết bị được nâng cấp. HAL AIDL của Cảm biến (dựa trên HAL Cảm biến 2.1) sử dụng giao diện HAL AIDL và hiển thị các loại cảm biến IMU trục hạn chế và thiết bị theo dõi đầu.

Giao diện HAL AIDL

Nguồn tài liệu chính cho Sensors AIDL HAL nằm trong định nghĩa HAL tại hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl.

Triển khai HAL AIDL của Cảm biến

Để triển khai Sensors AIDL HAL, một đối tượng phải mở rộng giao diện ISensors và triển khai tất cả các hàm được xác định trong hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl.

Khởi chạy HAL

Khung cảm biến Android phải khởi động HAL cảm biến thì mới có thể sử dụng. Khung gọi hàm initialize() để cung cấp 3 tham số cho Sensors HAL: 2 bộ mô tả FMQ và 1 con trỏ trỏ đến đối tượng ISensorsCallback.

HAL sử dụng bộ mô tả đầu tiên để tạo FMQ Sự kiện dùng để ghi các sự kiện cảm biến vào khung. HAL sử dụng bộ mô tả thứ hai để tạo WakeLock FMQ dùng để đồng bộ hoá khi HAL phát hành khoá đánh thức cho các sự kiện cảm biến WAKE_UP. HAL phải lưu con trỏ đến đối tượng ISensorsCallback để có thể gọi mọi hàm gọi lại cần thiết.

Hàm initialize() phải là hàm đầu tiên được gọi khi khởi tạo HAL Cảm biến.

Hiển thị các cảm biến hiện có

Để lấy danh sách tất cả các cảm biến tĩnh có sẵn trong thiết bị, hãy sử dụng hàm getSensorsList(). Hàm này trả về một danh sách các cảm biến, mỗi cảm biến được xác định duy nhất bằng handle của nó. Không được thay đổi giá trị nhận dạng cho một cảm biến nhất định khi quy trình lưu trữ Sensors HAL khởi động lại. Tên người dùng có thể thay đổi khi thiết bị khởi động lại và khi máy chủ hệ thống khởi động lại.

Nếu một số cảm biến có cùng loại cảm biến và thuộc tính đánh thức, thì cảm biến đầu tiên trong danh sách được gọi là cảm biến mặc định và được trả về cho các ứng dụng sử dụng hàm getDefaultSensor(int sensorType, bool wakeUp).

Tính ổn định của danh sách cảm biến

Sau khi Sensors HAL khởi động lại, nếu dữ liệu do getSensorsList() trả về cho thấy có sự thay đổi đáng kể so với danh sách cảm biến được truy xuất trước khi khởi động lại, thì khung sẽ kích hoạt quá trình khởi động lại thời gian chạy Android. Những thay đổi đáng kể đối với danh sách cảm biến bao gồm các trường hợp thiếu cảm biến có một tay cầm nhất định hoặc cảm biến đó đã thay đổi thuộc tính, hoặc trường hợp xuất hiện các cảm biến mới. Mặc dù việc khởi động lại thời gian chạy Android sẽ gây gián đoạn cho người dùng, nhưng đây là việc bắt buộc vì khung Android không còn đáp ứng được hợp đồng Android API rằng các cảm biến tĩnh (không động) sẽ không thay đổi trong suốt thời gian hoạt động của một ứng dụng. Điều này cũng có thể ngăn khung thiết lập lại các yêu cầu cảm biến đang hoạt động do ứng dụng đưa ra. Do đó, các nhà cung cấp HAL nên ngăn chặn những thay đổi không cần thiết đối với danh sách cảm biến.

Để đảm bảo các thao tác ổn định của cảm biến, HAL phải ánh xạ một cách xác định một cảm biến vật lý nhất định trong thiết bị với thao tác của cảm biến đó. Mặc dù giao diện Sensors HAL không bắt buộc phải triển khai cụ thể, nhưng nhà phát triển có một số lựa chọn để đáp ứng yêu cầu này.

Ví dụ: bạn có thể sắp xếp danh sách cảm biến bằng cách kết hợp các thuộc tính cố định của từng cảm biến, chẳng hạn như nhà cung cấp, kiểu máy và loại cảm biến. Một lựa chọn khác dựa trên thực tế là bộ cảm biến tĩnh của thiết bị được cố định trong phần cứng, vì vậy, HAL cần biết thời điểm tất cả các cảm biến dự kiến đã hoàn tất quá trình khởi tạo trước khi trả về từ getSensorsList(). Danh sách các cảm biến dự kiến này có thể được biên dịch thành tệp nhị phân HAL hoặc được lưu trữ trong một tệp cấu hình trong hệ thống tệp, đồng thời có thể dùng thứ tự xuất hiện để lấy các mã nhận dạng ổn định. Mặc dù giải pháp tốt nhất phụ thuộc vào các chi tiết cụ thể về việc triển khai HAL của bạn, nhưng yêu cầu chính là các thao tác cảm biến không thay đổi trong quá trình khởi động lại HAL.

Định cấu hình cảm biến

Trước khi được kích hoạt, cảm biến phải được định cấu hình với khoảng thời gian lấy mẫu và độ trễ báo cáo tối đa bằng cách sử dụng hàm batch().

Bạn có thể định cấu hình lại cảm biến bất cứ lúc nào bằng cách sử dụng batch() mà không làm mất dữ liệu cảm biến.

Khoảng thời gian lấy mẫu

Khoảng thời gian lấy mẫu có ý nghĩa khác nhau tuỳ thuộc vào loại cảm biến đang được định cấu hình:

  • Liên tục: Các sự kiện cảm biến được tạo ra với tốc độ liên tục.
  • Khi thay đổi: Các sự kiện được tạo không nhanh hơn khoảng thời gian lấy mẫu và có thể được tạo với tốc độ chậm hơn khoảng thời gian lấy mẫu nếu giá trị đo được không thay đổi.
  • Một lần: Khoảng thời gian lấy mẫu sẽ bị bỏ qua.
  • Đặc biệt: Để biết thêm thông tin chi tiết, hãy xem phần Các loại cảm biến.

Để tìm hiểu về mối tương tác giữa khoảng thời gian lấy mẫu và các chế độ báo cáo của cảm biến, hãy xem phần Chế độ báo cáo.

Độ trễ tối đa khi báo cáo

Độ trễ báo cáo tối đa đặt thời gian tối đa tính bằng nano giây mà các sự kiện có thể bị trì hoãn và lưu trữ trong FIFO phần cứng trước khi được ghi vào FMQ Sự kiện thông qua HAL trong khi SoC đang hoạt động.

Giá trị bằng 0 cho biết các sự kiện phải được báo cáo ngay khi được đo, bỏ qua hoàn toàn FIFO hoặc làm trống FIFO ngay khi một sự kiện từ cảm biến xuất hiện trong FIFO.

Ví dụ: một gia tốc kế được kích hoạt ở tần số 50 Hz với độ trễ báo cáo tối đa bằng 0 sẽ kích hoạt gián đoạn 50 lần mỗi giây khi SoC ở trạng thái thức.

Khi độ trễ báo cáo tối đa lớn hơn 0, các sự kiện cảm biến không cần được báo cáo ngay khi chúng được phát hiện. Các sự kiện có thể được tạm thời lưu trữ trong FIFO phần cứng và được báo cáo theo lô, miễn là không có sự kiện nào bị trễ quá độ trễ báo cáo tối đa. Tất cả sự kiện kể từ lô trước đều được ghi lại và trả về cùng một lúc. Điều này làm giảm số lượng gián đoạn được gửi đến SoC và cho phép SoC chuyển sang chế độ tiêu thụ điện năng thấp hơn trong khi cảm biến đang ghi lại và xử lý dữ liệu theo lô.

Mỗi sự kiện đều có một dấu thời gian liên kết với sự kiện đó. Việc trì hoãn thời gian báo cáo một sự kiện không được ảnh hưởng đến dấu thời gian của sự kiện. Dấu thời gian phải chính xác và tương ứng với thời gian sự kiện thực tế diễn ra, chứ không phải thời gian sự kiện được báo cáo.

Để biết thêm thông tin và yêu cầu về việc báo cáo các sự kiện cảm biến có độ trễ báo cáo tối đa khác 0, hãy xem phần Xử lý hàng loạt.

Kích hoạt cảm biến

Khung này bật và tắt các cảm biến bằng hàm activate(). Trước khi kích hoạt cảm biến, trước tiên, khung này phải định cấu hình cảm biến bằng batch().

Sau khi cảm biến bị vô hiệu hoá, các sự kiện cảm biến bổ sung từ cảm biến đó không được ghi vào FMQ sự kiện.

Cảm biến xả nước

Nếu một cảm biến được định cấu hình để xử lý hàng loạt dữ liệu cảm biến, thì khung này có thể buộc việc truyền ngay lập tức các sự kiện cảm biến theo lô bằng cách gọi flush(). Thao tác này khiến các sự kiện cảm biến theo lô cho trình xử lý cảm biến được chỉ định ngay lập tức được ghi vào Event FMQ. HAL Cảm biến phải thêm một sự kiện hoàn tất việc xoá vào cuối các sự kiện cảm biến được ghi do kết quả của một lệnh gọi đến flush().

Quá trình xoá diễn ra không đồng bộ (tức là hàm này phải trả về ngay lập tức). Nếu quá trình triển khai sử dụng một FIFO cho nhiều cảm biến, thì FIFO đó sẽ được xoá và sự kiện xoá hoàn tất chỉ được thêm cho cảm biến đã chỉ định.

Nếu cảm biến được chỉ định không có FIFO (không thể đệm), hoặc nếu FIFO trống vào thời điểm gọi, thì flush() vẫn phải thành công và gửi một sự kiện hoàn tất việc xoá cho cảm biến đó. Điều này áp dụng cho tất cả các cảm biến, ngoại trừ cảm biến một lần.

Nếu flush() được gọi cho một cảm biến một lần, thì flush() phải trả về BAD_VALUE và không tạo sự kiện hoàn tất việc xoá.

Ghi các sự kiện cảm biến vào FMQ

Event FMQ được Sensors HAL dùng để đẩy các sự kiện cảm biến vào khung cảm biến Android.

Event FMQ là một FMQ được đồng bộ hoá, tức là mọi nỗ lực ghi nhiều sự kiện hơn vào FMQ so với dung lượng có sẵn sẽ dẫn đến việc ghi không thành công. Trong trường hợp đó, HAL sẽ xác định xem có nên ghi nhóm sự kiện hiện tại thành 2 nhóm sự kiện nhỏ hơn hay ghi tất cả các sự kiện cùng nhau khi có đủ dung lượng hay không.

Khi Sensors HAL đã ghi số lượng sự kiện cảm biến mong muốn vào Event FMQ, Sensors HAL phải thông báo cho khung rằng các sự kiện đã sẵn sàng bằng cách ghi bit EventQueueFlagBits::READ_AND_PROCESS vào hàm EventFlag::wake của Event FMQ. Bạn có thể tạo EventFlag từ Event FMQ bằng cách sử dụng EventFlag::createEventFlag và hàm getEventFlagWord() của Event FMQ.

HAL AIDL của Cảm biến hỗ trợ cả writewriteBlocking trên Event FMQ. Phương thức triển khai mặc định cung cấp thông tin tham khảo để sử dụng write. Nếu hàm writeBlocking được dùng, thì cờ readNotification phải được đặt thành EventQueueFlagBits::EVENTS_READ. Cờ này được khung đặt khi đọc các sự kiện từ FMQ sự kiện. Bạn phải đặt cờ thông báo ghi thành EventQueueFlagBits::READ_AND_PROCESS. Cờ này sẽ thông báo cho khung rằng các sự kiện đã được ghi vào Event FMQ.

Sự kiện WAKE_UP

Sự kiện WAKE_UP là những sự kiện cảm biến khiến bộ xử lý ứng dụng (AP) thức dậy và xử lý sự kiện ngay lập tức. Bất cứ khi nào một sự kiện WAKE_UP được ghi vào FMQ sự kiện, HAL Cảm biến phải bảo mật khoá đánh thức để đảm bảo hệ thống luôn ở trạng thái hoạt động cho đến khi khung có thể xử lý sự kiện. Khi nhận được sự kiện WAKE_UP, khung sẽ bảo mật khoá đánh thức của chính nó, cho phép HAL Cảm biến giải phóng khoá đánh thức. Để đồng bộ hoá khi Sensors HAL phát hành khoá đánh thức, hãy sử dụng Wake Lock FMQ.

HAL Cảm biến phải đọc Wake Lock FMQ để xác định số lượng sự kiện WAKE_UP mà khung đã xử lý. HAL chỉ nên giải phóng khoá đánh thức cho các sự kiện WAKE_UP nếu tổng số sự kiện WAKE_UP chưa được xử lý là 0. Sau khi xử lý các sự kiện cảm biến, khung sẽ đếm số lượng sự kiện được đánh dấu là sự kiện WAKE_UP và ghi số này trở lại Wake Lock FMQ.

Khung này đặt thông báo ghi WakeLockQueueFlagBits::DATA_WRITTEN trên Wake Lock FMQ bất cứ khi nào ghi dữ liệu vào Wake Lock FMQ.

Cảm biến động

Cảm biến động là những cảm biến không phải là một phần vật lý của thiết bị nhưng có thể được dùng làm đầu vào cho thiết bị, chẳng hạn như tay cầm chơi game có gia tốc kế.

Khi một cảm biến động được kết nối, hàm onDynamicSensorConnected trong ISensorsCallback phải được gọi từ Sensors HAL. Thao tác này sẽ thông báo cho khung về cảm biến động mới và cho phép kiểm soát cảm biến thông qua khung, đồng thời cho phép các ứng dụng sử dụng các sự kiện của cảm biến.

Tương tự, khi một cảm biến động bị ngắt kết nối, bạn phải gọi hàm onDynamicSensorDisconnected trong ISensorsCallback để khung có thể xoá mọi cảm biến không còn dùng được nữa.

Kênh trực tiếp

Kênh trực tiếp là một phương thức hoạt động trong đó các sự kiện cảm biến được ghi vào bộ nhớ cụ thể thay vì vào FMQ sự kiện, bỏ qua Khung cảm biến Android. Một ứng dụng đăng ký kênh trực tiếp phải đọc các sự kiện cảm biến trực tiếp từ bộ nhớ đã dùng để tạo kênh trực tiếp và sẽ không nhận được các sự kiện cảm biến thông qua khung. Hàm configDirectReport() tương tự như batch() đối với hoạt động bình thường và định cấu hình kênh báo cáo trực tiếp.

Hàm registerDirectChannel()unregisterDirectChannel() tạo hoặc huỷ một kênh trực tiếp mới.

Chế độ hoạt động

Hàm setOperationMode() cho phép khung định cấu hình một cảm biến để khung có thể chèn dữ liệu cảm biến vào cảm biến. Điều này hữu ích cho việc kiểm thử, đặc biệt là đối với các thuật toán nằm bên dưới khung.

Hàm injectSensorData() thường được dùng để đẩy các tham số hoạt động vào Sensors HAL. Bạn cũng có thể dùng hàm này để chèn các sự kiện cảm biến vào một cảm biến cụ thể.

Xác nhận kết quả

Để xác thực việc triển khai Sensors HAL, hãy chạy các kiểm thử CTS và VTS của cảm biến.

Các bài kiểm thử CTS

Các kiểm thử CTS cảm biến có trong cả kiểm thử CTS tự động và ứng dụng CTS Verifier thủ công.

Các bài kiểm thử tự động nằm trong cts/tests/sensor/src/android/hardware/cts. Các kiểm thử này xác minh chức năng tiêu chuẩn của cảm biến, chẳng hạn như kích hoạt cảm biến, phân lô và tốc độ sự kiện cảm biến.

Các bài kiểm thử CTS Verifier nằm trong cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors. Các kiểm thử này yêu cầu người vận hành kiểm thử nhập dữ liệu theo cách thủ công và đảm bảo rằng các cảm biến báo cáo giá trị chính xác.

Việc vượt qua các bài kiểm thử CTS là điều kiện tiên quyết để đảm bảo rằng thiết bị đang được kiểm thử đáp ứng mọi yêu cầu của CDD.

Kiểm thử VTS

Các bài kiểm thử VTS cho Sensors AIDL HAL nằm trong hardware/interfaces/sensors/aidl/vts/. Các kiểm thử này đảm bảo rằng HAL Cảm biến được triển khai đúng cách và tất cả các yêu cầu trong ISensors.aidlISensorsCallback.aidl đều được đáp ứng đúng cách.

Khởi chạy HAL

Bạn phải hỗ trợ hàm initialize() để thiết lập FMQ giữa khung và HAL.

Hiển thị các cảm biến hiện có

Trong Sensors AIDL HAL, 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 Sensors HAL khởi động lại. Một yêu cầu mới đối với hàm getSensorsList() là hàm này phải trả về cùng một giá trị trong một lần khởi động thiết bị, ngay cả khi khởi động lại HAL Cảm biến. Điều này cho phép khung cố gắng thiết lập lại các 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.

Ghi các sự kiện cảm biến vào FMQ

Thay vì chờ poll() được gọi, trong Sensors AIDL HAL, Sensors HAL phải chủ động ghi các sự kiện cảm biến vào Event FMQ bất cứ khi nào có sự kiện cảm biến. HAL cũng chịu trách nhiệm ghi các bit chính xác vào EventFlag để gây ra một hoạt động đọc FMQ trong khung.

Sự kiện WAKE_UP

Trong Sensors HAL 1.0, HAL có thể giải phóng khoá đánh thức cho mọi sự kiện WAKE_UP trong mọi lệnh gọi tiếp theo đến poll() sau khi WAKE_UP được đăng lên poll() vì điều này cho biết khung đã xử lý tất cả các sự kiện cảm biến và đã lấy được khoá đánh thức (nếu cần). Vì trong HAL AIDL của Cảm biến, HAL không còn được thông báo khi khung hình đã xử lý các sự kiện được ghi vào FMQ nữa, nên Wake Lock FMQ cho phép khung hình giao tiếp với HAL khi khung hình đã xử lý các sự kiện WAKE_UP.

Trong Sensors AIDL HAL, khoá đánh thức do Sensors HAL bảo mật cho các sự kiện WAKE_UP phải bắt đầu bằng SensorsHAL_WAKEUP.

Cảm biến động

Các cảm biến động được trả về bằng hàm poll() trong Sensors HAL 1.0. HAL AIDL của Cảm biến yêu cầu gọi onDynamicSensorsConnectedonDynamicSensorsDisconnected trong ISensorsCallback bất cứ khi nào các 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ỏ ISensorsCallback được cung cấp thông qua hàm initialize().

Chế độ hoạt động

Bạn phải hỗ trợ chế độ DATA_INJECTION cho các cảm biến WAKE_UP.

Hỗ trợ Multi-HAL

HAL AIDL của Cảm biến hỗ trợ nhiều HAL bằng cách sử dụng khung Nhiều HAL của Cảm biến. Để biết thông tin chi tiết về cách triển khai, hãy xem phần Chuyển từ HAL cảm biến 2.1.