Lớp trừu tượng phần cứng cảm biến (HAL) là giao diện giữa khung cảm biến Android và 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. Cảm biến HAL xác định các chức năng phải được triển khai để cho phép khung điều khiển các cảm biến.
Cảm biến HAL 2.0 có sẵn trong Android 10 trở lên cho các thiết bị mới và nâng cấp. Cảm biến HAL 2.0 dựa trên Cảm biến HAL 1.0 nhưng có một số điểm khác biệt chính khiến nó không thể tương thích ngược. Cảm biến HAL 2.0 sử dụng Hàng đợi tin nhắn nhanh (FMQ) để gửi các sự kiện cảm biến từ HAL vào khung cảm biến Android.
Cảm biến HAL 2.1 có sẵn trong Android 11 trở lên cho các thiết bị mới và nâng cấp. Cảm biến HAL 2.1 là phiên bản lặp lại của Cảm biến HAL 2.0, hiển thị loại cảm biến HINGE_ANGLE và cập nhật các phương pháp khác nhau để chấp nhận loại HINGE_ANGLE
.
Giao diện HAL 2.1
Nguồn tài liệu chính cho Cảm biến HAL 2.1 nằm trong định nghĩa HAL tại phần cứng/giao diện/cảm biến/2.1/ISensors.hal . Nếu có xung đột về yêu cầu giữa trang này và ISensors.hal
, hãy sử dụng yêu cầu trong ISensors.hal
.
Giao diện HAL 2.0
Nguồn tài liệu chính cho Cảm biến HAL 2.0 nằm trong định nghĩa HAL tại hardware/interfaces/sensors/2.0/ISensors.hal . Nếu có xung đột về yêu cầu giữa trang này và ISensors.hal
, hãy sử dụng yêu cầu trong ISensors.hal
.
Triển khai Cảm biến HAL 2.0 và HAL 2.1
Để triển khai Cảm biến HAL 2.0 hoặc 2.1, đối tượng phải mở rộng giao diện ISensors
và triển khai tất cả các chức năng được xác định trong 2.0/ISensors.hal
hoặc 2.1/ISensors.hal
.
Khởi tạo HAL
Cảm biến HAL phải được khung cảm biến Android khởi tạo trước khi có thể sử dụng. Khung này gọi hàm initialize()
cho HAL 2.0 và hàm initialize_2_1()
cho HAL 2.1 để cung cấp ba tham số cho Bộ cảm biến HAL: hai bộ mô tả FMQ và một con trỏ tới đối tượng ISensorsCallback
.
HAL sử dụng bộ mô tả đầu tiên để tạo FMQ sự kiện được sử 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 FMQ Wake Lock được sử dụng để đồng bộ hóa khi HAL giải phóng khóa đánh thức cho các sự kiện cảm biến WAKE_UP
. HAL phải lưu một con trỏ tới đối tượng ISensorsCallback
để có thể gọi bất kỳ hàm gọi lại cần thiết nào.
Hàm initialize()
hoặc initialize_2_1()
phải là hàm đầu tiên được gọi khi khởi tạo Cảm biến HAL.
Hiển thị các cảm biến có sẵn
Để có 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()
trên HAL 2.0 và hàm getSensorsList_2_1()
trên HAL 2.1. 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ởi phần điều khiển của nó. Tay cầm của một cảm biến nhất định không được thay đổi khi quá trình lưu trữ Cảm biến HAL khởi động lại. Tay cầm có thể thay đổi khi khởi động lại thiết bị và khi khởi động lại máy chủ hệ thống.
Nếu một số cảm biến dùng chung 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 sẽ được gọi là cảm biến mặc định và được trả về các ứng dụng sử dụng chức năng getDefaultSensor(int sensorType, bool wakeUp)
.
Độ ổn định của danh sách cảm biến
Sau khi khởi động lại HAL cảm biến, nếu dữ liệu được trả về bởi getSensorsList()
hoặc getSensorsList_2_1()
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 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 cảm biến có tay cầm nhất định bị thiếu hoặc đã thay đổi thuộc tính hoặc khi giới thiệu cảm biến mới. Mặc dù việc khởi động lại thời gian chạy Android gây gián đoạn cho người dùng nhưng điều này là bắt buộc vì khung Android không còn có thể đáp ứng hợp đồng API Android mà các cảm biến tĩnh (không động) không thay đổi trong suốt vòng đời của ứ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 thực hiện. Do đó, các nhà cung cấp HAL nên ngăn chặn những thay đổi có thể tránh được trong danh sách cảm biến.
Để đảm bảo các tay cầm cảm biến ổn định, 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ị tới tay cầm của nó. Mặc dù giao diện HAL của Cảm biến không bắt buộc phải triển khai cụ thể nhưng các nhà phát triển có sẵn một số tùy chọn để đáp ứng yêu cầu này.
Ví dụ: danh sách cảm biến có thể được sắp xếp bằng cách sử dụng 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 tùy 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, do đó HAL cần biết khi nào 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 quay lại từ getSensorsList()
hoặc getSensorsList_2_1()
. 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 tệp cấu hình trong hệ thống tệp và thứ tự xuất hiện có thể được sử dụng để lấy ra các thẻ điều khiển ổn định. Mặc dù giải pháp tốt nhất phụ thuộc vào chi tiết triển khai cụ thể HAL của bạn, nhưng yêu cầu chính là bộ điều khiển cảm biến không thay đổi khi HAL khởi động lại.
Cấu hình cảm biến
Trước khi kích hoạt cảm biến, 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 hàm batch()
.
Cảm biến phải có khả năng được cấu hình lại bất kỳ 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.
Thời gian lấy mẫu
Khoảng thời gian lấy mẫu có ý nghĩa khác nhau tùy theo 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 ra không nhanh hơn khoảng thời gian lấy mẫu và có thể được tạo ra 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.
- One-shot: Khoảng thời gian lấy mẫu bị bỏ qua.
- Đặc biệt: Để biết thêm chi tiết, xem Các loại cảm biến .
Để tìm hiểu về sự tương tác giữa khoảng thời gian lấy mẫu và chế độ báo cáo của cảm biến, hãy xem Chế độ báo cáo .
Độ trễ báo cáo tối đa
Độ 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à được 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 vẫn hoạt động.
Giá trị bằng 0 biểu thị rằng các sự kiện phải được báo cáo ngay khi chúng được đo, hoặc bỏ qua FIFO hoàn toàn hoặc làm trống FIFO ngay khi có một sự kiện từ cảm biế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ẽ ngắt 50 lần mỗi giây khi SoC hoạt động.
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 phải được báo cáo ngay khi chúng được phát hiện. Các sự kiện có thể được lưu trữ tạm thời trong FIFO phần cứng và được báo cáo theo đợt, miễn là không có sự kiện nào bị trì hoãn nhiều hơn độ trễ báo cáo tối đa. Tất cả các sự kiện kể từ đợt 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ần ngắt được gửi tới SoC và cho phép SoC chuyển sang chế độ năng lượng thấp hơn trong khi cảm biến đang thu thập và phân khối dữ liệu.
Mỗi sự kiện có một dấu thời gian gắn liền với nó. Việc trì hoãn thời điểm báo cáo 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 điểm sự kiện xảy ra trên thực tế chứ không phải thời điểm 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 nhóm .
Kích hoạt cảm biến
Khung này kích hoạt và vô hiệu hóa 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 phải định cấu hình cảm biến bằng batch()
.
Sau khi tắt cảm biến, 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ếu một cảm biến được định cấu hình để xử lý dữ liệu cảm biến theo lô, thì khung có thể buộc xóa ngay lập tức các sự kiện cảm biến theo lô bằng cách gọi lệnh flush()
. Điều này khiến các sự kiện cảm biến theo lô cho bộ điều khiển cảm biến được chỉ định sẽ được ghi ngay vào FMQ sự kiện. HAL cảm biến phải thêm một sự kiện hoàn thành tuôn ra vào cuối các sự kiện cảm biến được ghi dưới dạng lệnh gọi tới flush()
.
Việc xóa xảy ra không đồng bộ (nghĩa 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 duy nhất cho một số cảm biến thì FIFO đó sẽ bị xóa và sự kiện hoàn tất tuôn ra chỉ được thêm vào cho cảm biến đã chỉ định.
Nếu cảm biến được chỉ định không có FIFO (không thể lưu vào bộ đệm) hoặc nếu FIFO trống tại thời điểm cuộc gọi, flush()
vẫn phải thành công và gửi một sự kiện hoàn thành tuôn ra 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 cảm biến một lần, thì flush()
phải trả về BAD_VALUE
và không tạo ra sự kiện hoàn thành xóa.
Ghi các sự kiện cảm biến vào FMQ
FMQ sự kiện được HAL cảm biến sử dụng để đẩy các sự kiện cảm biến vào khung cảm biến Android.
FMQ sự kiện là một FMQ được đồng bộ hóa, có nghĩa là mọi nỗ lực ghi nhiều sự kiện vào FMQ hơn dung lượng có sẵn sẽ dẫn đến việc ghi không thành công. Trong trường hợp như vậy, HAL nên xác định xem nên ghi tập hợp sự kiện hiện tại thành hai nhóm sự kiện nhỏ hơn hay viết tất cả các sự kiện cùng nhau khi có đủ không gian.
Khi HAL cảm biến đã ghi số lượng sự kiện cảm biến mong muốn vào FMQ sự kiện, HAL cảm biến 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 FMQ sự kiện. EventFlag có thể được tạo từ Event FMQ bằng cách sử dụng EventFlag::createEventFlag
và hàm getEventFlagWord()
của Event FMQ.
Cảm biến HAL 2.0/2.1 hỗ trợ cả write
và writeBlocking
trên FMQ sự kiện. Việc triển khai mặc định cung cấp một tham chiếu cho việc sử dụng write
. Nếu sử dụng chức năng writeBlocking
, cờ readNotification
phải được đặt thành EventQueueFlagBits::EVENTS_READ
, được đặt bởi khung khi đọc các sự kiện từ FMQ sự kiện. Cờ thông báo ghi phải được đặt thành EventQueueFlagBits::READ_AND_PROCESS
để thông báo cho khung rằng các sự kiện đã được ghi vào FMQ sự kiện.
sự kiện WAKE_UP
Sự kiện WAKE_UP
là các 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 sự kiện WAKE_UP
được ghi vào FMQ sự kiện, HAL cảm biến phải bảo mật khóa đánh thức để đảm bảo hệ thống luôn 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 khóa đánh thức của chính nó, cho phép HAL cảm biến giải phóng khóa đánh thức của nó. Để đồng bộ hóa khi Cảm biến HAL giải phóng khóa đánh thức, hãy sử dụng FMQ Wake Lock.
HAL cảm biến phải đọc FMQ Wake Lock để xác định số lượng sự kiện WAKE_UP
mà khung đã xử lý. HAL chỉ nên mở khóa chế độ 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ý bằng 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 nó ghi dữ liệu vào Wake Lock FMQ.
Cảm biến động
Cảm biến động là các cảm biến không phải là một bộ phận vật lý của thiết bị nhưng có thể được sử 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ừ Cảm biến HAL. Điều này thông báo cho khung của cảm biến động mới và cho phép cảm biến được điều khiển thông qua khung và để khách hàng sử dụng các sự kiện của cảm biến.
Tương tự, khi cảm biến động bị ngắt kết nối, hàm onDynamicSensorDisconnected
trong ISensorsCallback
phải được gọi để khung có thể loại bỏ bất kỳ cảm biến nào không còn khả dụng.
Kênh trực tiếp
Kênh trực tiếp là 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áy khách đă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ớ được sử 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()
để hoạt động bình thường và định cấu hình kênh báo cáo trực tiếp.
Các hàm registerDirectChannel()
và unregisterDirectChannel()
tạo hoặc hủy 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 cảm biến để khung có thể đưa dữ liệu cảm biến vào cảm biến. Điều này rất hữu ích cho việc thử nghiệm, đặc biệt đối với các thuật toán tồn tại bên dưới khuôn khổ.
Hàm injectSensorData()
trong HAL 2.0 và hàm injectSensorsData_2_1()
trong HAL 2.0 thường được sử dụng để đẩy các tham số vận hành vào Cảm biến HAL. Chức năng này cũng có thể được sử dụng để đưa các sự kiện cảm biến vào một cảm biến cụ thể.
Thẩm định
Để xác thực việc triển khai HAL cảm biến của bạn, hãy chạy thử nghiệm CTS và VTS cảm biến.
xét nghiệm CTS
Kiểm tra CTS cảm biến tồn tại trong cả kiểm tra CTS tự động và ứng dụng Trình xác minh CTS thủ công.
Các bài kiểm tra tự động được đặt trong cts/tests/sensor/src/android/hardware/cts . Các thử nghiệm 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 mẻ và tỷ lệ sự kiện của cảm biến.
Các bài kiểm tra của Trình xác minh CTS được đặt trong cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors . Những thử nghiệm này yêu cầu người vận hành thử nghiệm nhập dữ liệu thủ công và đảm bảo rằng các cảm biến báo cáo các giá trị chính xác.
Việc vượt qua các bài kiểm tra CTS là rất quan trọng để đảm bảo rằng thiết bị được kiểm tra đáp ứng tất cả các yêu cầu của CDD.
kiểm tra VTS
Các thử nghiệm VTS cho Cảm biến HAL 2.0 được đặt trong phần cứng/giao diện/cảm biến/2.0/vts . Các thử nghiệm VTS cho Cảm biến HAL 2.1 được đặt trong phần cứng/giao diện/cảm biến/2.1/vts . Các thử nghiệm này đảm bảo rằng Cảm biến HAL được triển khai đúng cách và tất cả các yêu cầu trong ISensors.hal
và ISensorsCallback.hal
đều được đáp ứng đúng cách.
Nâng cấp lên Cảm biến HAL 2.1 từ 2.0
Khi nâng cấp lên Cảm biến HAL 2.1 từ 2.0, việc triển khai HAL của bạn phải bao gồm các phương thức initialize_2_1()
, getSensorsList_2_1()
và injectSensorsData_2_1()
cùng với các loại HAL 2.1. Các phương pháp này phải đáp ứng các yêu cầu tương tự được nêu cho HAL 2.0 ở trên.
Bởi vì HAL phiên bản phụ phải hỗ trợ tất cả các chức năng từ các HAL trước đó, nên HAL 2.1 phải hỗ trợ được khởi tạo dưới dạng HAL 2.0. Để tránh sự phức tạp khi hỗ trợ cả hai phiên bản HAL, chúng tôi khuyên bạn nên sử dụng Multi-HAL 2.1.
Để biết ví dụ về cách triển khai Cảm biến 2.1 HAL của riêng bạn, hãy xem Sensors.h .
Nâng cấp lên Cảm biến HAL 2.0 từ 1.0
Khi nâng cấp lên Cảm biến HAL 2.0 từ 1.0, hãy đảm bảo việc triển khai HAL của bạn đáp ứng các yêu cầu sau.
Khởi tạo HAL
Hàm initialize()
phải được hỗ trợ để thiết lập FMQ giữa khung và HAL.
Hiển thị các cảm biến có sẵn
Trong Cảm biến 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 khởi động lại Cảm biến HAL. Yêu cầu mới của 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ủa 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ị được getSensorsList()
trả về có thể thay đổi sau khi thiết bị thực hiện khởi động lại.
Ghi các sự kiện cảm biến vào FMQ
Thay vì chờ cuộc poll()
được gọi, trong Cảm biến HAL 2.0, Cảm biến HAL phải chủ động ghi các sự kiện cảm biến vào FMQ sự kiện 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
để đọc FMQ trong khung.
sự kiện WAKE_UP
Trong Sensors HAL 1.0, HAL có thể mở khóa đánh thức của nó cho bất kỳ sự kiện WAKE_UP
nào trong bất kỳ lệnh gọi tiếp theo nào tới poll()
sau khi WAKE_UP
được đăng lên poll()
vì điều này cho thấy rằng khung đã xử lý tất cả các sự kiện cảm biến và đã nhận được một khóa đánh thức, nếu cần thiết. Bởi vì, trong Sensors HAL 2.0, HAL không còn biết khi nào khung xử lý các sự kiện được ghi vào FMQ, Wake Lock FMQ cho phép khung giao tiếp với HAL khi nó đã xử lý các sự kiện WAKE_UP
.
Trong Cảm biến HAL 2.0, khóa chế độ thức được bảo mật bằng Cảm biến HAL cho các sự kiện WAKE_UP
phải bắt đầu bằng SensorsHAL_WAKEUP
.
Cảm biến động
Cảm biến động được trả về bằng hàm poll()
trong Cảm biến HAL 1.0. Cảm biến HAL 2.0 yêu cầu gọi onDynamicSensorsConnected
và onDynamicSensorsDisconnected
trong ISensorsCallback
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 như một phần của con trỏ ISensorsCallback
được cung cấp thông qua hàm initialize()
.
Chế độ hoạt động
Chế độ DATA_INJECTION
cho cảm biến WAKE_UP
phải được hỗ trợ trong Cảm biến HAL 2.0.
Hỗ trợ đa HAL
Cảm biến HAL 2.0 và 2.1 hỗ trợ multi-HAL bằng cách sử dụng khung Cảm biến Multi-HAL . Để biết chi tiết triển khai, hãy xem Chuyển từ cảm biến HAL 1.0 .