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. 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ảm biến.
Cảm biến AIDL HAL có trong Android 13 và cao hơn đối với các thiết bị mới và thiết bị đã nâng cấp. Cảm biến AIDL HAL, dựa trên Cảm biến HAL 2.1, sử dụng Giao diện AIDL HAL và hiển thị thiết bị theo dõi chuyển động của đầu và các loại cảm biến IMU trục giới hạn.
Giao diện AIDL HAL
Nguồn tài liệu chính cho lớp trừu tượng phần cứng (HAL) của cảm biến là trong HAL định nghĩa tại phần cứng/giao diện/cảm biến/aidl/android/hardware/sensors/ISensors.aidl.
Triển khai AIDL HAL của cảm biến
Để triển khai AIDL HAL của cảm biến, đối tượng phải mở rộng ISensors
giao diện và triển khai tất cả các hàm được xác định trong
phần cứng/giao diện/cảm biến/aidl/android/hardware/sensors/ISensors.aidl.
Khởi chạy HAL
HAL của cảm biến phải được khung cảm biến Android khởi chạy trước khi
. Khung này gọi hàm initialize()
để cung cấp 3
các tham số cho HAL của Cảm biến: hai phần mô tả FMQ và một con trỏ đến một
Đối tượng ISensorsCallback
.
HAL sử dụng bộ mô tả đầu tiên để tạo FMQ sự kiện dùng để ghi cảm biến
các sự kiện vào khung. HAL sử dụng chỉ số mô tả thứ hai để tạo ra Wake
Khoá FMQ dùng để đồng bộ hoá khi HAL mở khoá chế độ thức cho WAKE_UP
các sự kiện của cảm biến. HAL phải lưu con trỏ vào đối tượng ISensorsCallback
để
để bất kỳ hàm callback cần thiết nào được gọi.
Hàm initialize()
phải là hàm đầu tiên được gọi khi khởi tạo
HAL của cảm biến.
Hiển thị các cảm biến có sẵn
Để xem danh sách tất cả cảm biến tĩnh hiện có 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ởi tên người dùng của nó. Không được thay đổi tên người dùng của một cảm biến cụ thể
khi quá trình lưu trữ HAL của cảm biến khởi động lại. Tên người dùng có thể thay đổi qua
thiết bị khởi động lại và trên máy chủ hệ thống khởi động lại.
Nếu một vài cảm biến dùng chung một 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ề
ứng dụng dù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ủa cảm biến, nếu dữ liệu mà getSensorsList()
trả về
cho biết thay đổi đáng kể so với danh sách cảm biến được lấy trước
khởi động lại, khung sẽ kích hoạt quá trình khởi động lại
Android Runtime. Thay đổi đáng kể đối với danh sách cảm biến bao gồm các trường hợp mà
cảm biến có tên người dùng cụ thể bị thiếu hoặc đã thay đổi thuộc tính hoặc vị trí mới
các cảm biến. Mặc dù việc khởi động lại môi trường thời gian chạy Android có thể gây gián đoạn
cho người dùng. Đây là yêu cầu bắt buộc do khung Android không còn đáp ứng được
Hợp đồng API Android mà các cảm biến tĩnh (không động) không thay đổi trong khoảng thời gian
vòng đời của một ứng dụng. Việc này cũng có thể khiến khung này không thiết lập lại được
các yêu cầu đang hoạt động đối với cảm biến do ứng dụng đưa ra. Do đó, nhà cung cấp HAL nên
ngăn chặn những thay đổi có thể tránh được đối với danh sách cảm biến.
Để đảm bảo tay cầm cảm biến ổn định, HAL phải ánh xạ một cách quyết định một cảm biến vật lý trong thiết bị vào tay cầm. Mặc dù không có cách triển khai cụ thể được uỷ nhiệm bởi giao diện HAL của Cảm biến, nhà phát triển có một số tuỳ chọn để đáp ứng yêu cầu này.
Ví dụ: có thể sắp xếp danh sách cảm biến bằng cách sử dụng tổ hợp các thuộc tính
các thuộc tính cố định, 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 vào
trên thực tế, tập hợp các 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 thời điểm tất cả cảm biến dự kiến đã khởi chạy xong trước
trở về từ getSensorsList()
. Danh sách này
các cảm biến dự kiến có thể được biên dịch vào 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 và thứ tự hiển thị có thể được sử dụng
để tìm ra tên người dùng ổn định. Mặc dù giải pháp tốt nhất phụ thuộc vào HAL
các chi tiết triển khai cụ thể, yêu cầu chính là cảm biến phải xử lý
không thay đổi khi HAL (Lớp trừu tượng phần cứng) khởi động lại.
Định cấu hình cảm biến
Trước khi kích hoạt một cảm biến, bạn phải định cấu hình cảm biến bằng cách lấy mẫu
khoảng thời gian và độ trễ báo cáo tối đa bằng cách sử dụng hàm batch()
.
Bạn phải có thể định cấu hình lại một cảm biến bất cứ lúc nào bằng cách sử dụng batch()
mà không cần
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 dựa trên 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 với tốc độ liên tục.
- Khi thay đổi: 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 so với khoảng thời gian lấy mẫu nếu giá trị được đo lường sẽ không thay đổi.
- Một lần: Khoảng thời gian lấy mẫu bị bỏ qua.
- Đặc biệt: Để biết thêm chi tiết, hãy xem 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, hãy xem Chế độ báo cáo.
Độ trễ báo cáo tối đa
Độ trễ báo cáo tối đa giúp đặ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 của sự kiện thông qua HAL trong khi SoC đang hoạt động.
Giá trị bằng 0 cho biết rằng sự kiện cần được báo cáo ngay khi được đo lường, bỏ qua hoàn toàn FIFO hoặc xoá FIFO ngay khi một sự kiện từ cảm biến sẽ xuất hiện trong FIFO.
Ví dụ: gia tốc kế kích hoạt ở tốc độ 50 Hz với giá trị báo cáo tối đa độ trễ trong số 0 điều kiện kích hoạt sẽ làm gián đoạn 50 lần mỗi giây khi SoC bật.
Khi độ trễ báo cáo tối đa lớn hơn 0, các sự kiện cảm biến sẽ không cần được báo cáo ngay khi phát hiện thấy chúng. Các sự kiện có thể diễn ra tạm thời được 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 trễ nhiều hơn độ trễ báo cáo tối đa. Tất cả sự kiện kể từ lô trước đó sẽ được ghi lại và trả về cùng một lúc. Điều này giúp giảm số lượng làm gián đoạn quá trình gửi đến SoC và cho phép SoC chuyển sang chế độ tiết kiệm pin trong khi cảm biến đang thu thập và phân lô dữ liệu.
Mỗi sự kiện đều có một dấu thời gian tương ứng. Trì hoãn thời gian mà sự kiện được báo cáo không được ảnh hưởng đến dấu thời gian của sự kiện. Dấu thời gian phải là 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 báo cáo.
Để biết thêm thông tin và các yêu cầu về cách báo cáo sự kiện cảm biến bằng độ trễ báo cáo tối đa khác 0, hãy xem phần Tạo lô.
Kích hoạt cảm biến
Khung này sẽ bật và tắt các cảm biến bằng hàm activate()
.
Trước khi kích hoạt một cảm biến, khung đầu tiên phải định cấu hình cảm biến
đang sử dụng batch()
.
Sau khi một cảm biến bị tắt, các sự kiện cảm biến khác từ cảm biến đó không được được ghi vào FMQ của sự kiện.
Cảm biến xả nước
Nếu một cảm biến được định cấu hình để phân lô dữ liệu cảm biến, khung có thể buộc
một lượt xoá ngay lập tức các sự kiện cảm biến theo lô bằng cách gọi flush()
. Điều này khiến
các sự kiện cảm biến được phân theo lô
cho tên người dùng cảm biến được chỉ định là ngay lập tức
được ghi vào FMQ của sự kiện. Lớp trừu tượng phần cứng (HAL) của cảm biến phải thêm một sự kiện hoàn tất xả dữ liệu
vào cuối các sự kiện cảm biến được ghi lại theo lệnh gọi đến
flush()
.
Việc xả 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 cho nhiều cảm biến, thì FIFO đó sẽ xả nước và sự kiện hoàn tất xả nước chỉ được thêm vào cho cảm biến được chỉ định.
Nếu cảm biến được chỉ định không có FIFO (không có khả năng tải vào bộ đệm) hoặc nếu FIFO
trống tại thời điểm gọi, flush()
vẫn phải thành công và gửi một lỗi
sự kiện hoàn tất cho cảm biến đó. Chế độ này áp dụng cho mọi cảm biến không phải cảm biến chụp một lần
các cảm biế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 một sự kiện hoàn tất xả dữ liệu.
Ghi các sự kiện cảm biến vào FMQ
FMQ của sự kiện được HAL của cảm biến sử dụng để đẩy các sự kiện cảm biến vào Android khung cảm biến.
FMQ của sự kiện là một FMQ được đồng bộ hoá, tức là mọi nỗ lực ghi thêm sự kiện gửi đến FMQ so với không gian có sẵn cho phép dẫn đến lỗi ghi. Trong trường hợp như vậy, HAL phải xác định xem có ghi nhóm hiện tại hay không gồm các sự kiện dưới dạng hai nhóm sự kiện nhỏ hơn hoặc để viết tất cả các sự kiện khi có đủ dung lượng.
Khi HAL của cảm biến đã ghi số lượng sự kiện cảm biến mong muốn vào
FMQ của sự kiện, HAL của cảm biến phải thông báo cho khung rằng các sự kiện đã sẵn sàng
ghi bit EventQueueFlagBits::READ_AND_PROCESS
vào FMQ của sự kiện
EventFlag::wake
. Bạn có thể tạo Eventflag bằng FMQ của sự kiện
sử dụng EventFlag::createEventFlag
và getEventFlagWord()
của FMQ của sự kiện
.
AIDL HAL của cảm biến hỗ trợ cả write
và writeBlocking
trên Event FMQ.
Phương thức triển khai mặc định cung cấp tệp tham chiếu để sử dụng write
. Nếu
Hàm writeBlocking
được dùng, cờ readNotification
phải được đặt thành
EventQueueFlagBits::EVENTS_READ
do khung này đặt khi đọc
các sự kiện từ FMQ của 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 của 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 trình xử lý ứng dụng (AP)
đánh thức 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ới sự kiện FMQ, HAL của Cảm biến phải thiết lập khóa chế độ thức để đảm bảo rằng
hệ thống vẫn ở trạng thái bật cho đến khi khung có thể xử lý sự kiện đó. Sau khi nhận được
WAKE_UP
, khung này bảo mật khoá chế độ thức riêng, cho phép
HAL của cảm biến để mở khóa chế độ thức. Để đồng bộ hoá khi HAL của cảm biến
phát hành khoá chế độ thức, hãy sử dụng FMQ của Khoá chế độ thức.
HAL của cảm biến phải đọc FMQ của Khoá chế độ thức để xác định số lượng WAKE_UP
các sự kiện mà khung đã xử lý. HAL chỉ nên mở khoá 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ý là 0.
Sau khi xử lý các sự kiện cảm biến, khung sẽ đếm số lượng sự kiện
đã đánh dấu là sự kiện WAKE_UP
và ghi số này trở lại FMQ của Khoá chế độ thức.
Khung này đặt cách ghi WakeLockQueueFlagBits::DATA_WRITTEN
thông báo trên FMQ khoá chế độ thức mỗi khi ghi dữ liệu vào FMQ của Khoá chế độ thức.
Cảm biến động
Cảm biến động là cảm biến không thuộc về thiết bị nhưng có thể được dùng làm dữ liệu đầu vào cho thiết bị, chẳng hạn như tay điều khiển trò chơi có gia tốc kế.
Khi một cảm biến động được kết nối, hàm onDynamicSensorConnected
trong
Phải gọi ISensorsCallback
qua lớp trừu tượng phần cứng (HAL) của cảm biến. Điều này thông báo cho
khung của cảm biến động mới và cho phép kiểm soát cảm biến
thông qua khung và để ứng dụ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 như vậy
khung có thể xoá bất kỳ cảm biến nào không 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 mà trong đó sự kiện cảm biến được ghi vào
bộ nhớ cụ thể thay vì sự kiện FMQ bỏ qua Cảm biến Android
Khung. Ứ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 sự kiện cảm biến thông qua khung này. configDirectReport()
tương tự như batch()
để hoạt động bình thường và định cấu hình lệnh chuyển hướng
kênh báo cáo.
Các hàm registerDirectChannel()
và unregisterDirectChannel()
tạo
hoặc huỷ bỏ 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ể chèn dữ liệu cảm biến vào cảm biến. Thông tin này hữu ích cho
kiểm thử, đặc biệt là đối với các thuật toán tồn tại bên dưới khung.
Hàm injectSensorData()
thường được dùng để đẩy hoạt động
vào HAL của cảm biến. Hàm này cũng có thể dùng để chèn cảm biến
sự kiệ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 HAL của cảm biến, hãy chạy CTS và VTS của cảm biến kiểm thử.
Bài kiểm thử CTS
Bài kiểm tra CTS cảm biến tồn tại trong cả kiểm tra CTS tự động và Trình xác minh CTS thủ công .
Các bài kiểm thử tự động nằm trong cts/tests/sensor/src/android/hardware/cts. Những quá trình 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ủa cảm biến.
Các bài kiểm tra Trình xác minh CTS nằm ở cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors. Những bài kiểm thử này yêu cầu thông tin đầu vào thủ công từ người điều hành kiểm thử và đảm bảo rằng 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 rất quan trọng để đảm bảo rằng thiết bị được kiểm thử đáp ứng tất cả yêu cầu của CDD.
Xét nghiệm VTS
Bài kiểm tra VTS cho Cảm biến AIDL HAL được đặt ở
phần cứng/giao diện/cảm biến/aidl/vts/.
Những bài kiểm thử này đảm bảo rằng HAL của Cảm biến được triển khai đúng cách và
các yêu cầu trong ISensors.aidl
và ISensorsCallback.aidl
đã được đáp ứng đúng cách.
Khởi chạy 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 lớp trừu tượng phần cứng AIDL của cảm biến, 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 HAL (Lớp trừu tượng phần cứng) của cảm biến khởi động lại. 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 khoảng thời gian
một thiết bị khởi động, ngay cả khi HAL (Lớp trừu tượng phần cứng) của Cảm biến khởi động lại. Điều này cho phép
khung thiết lập lại các kết nối cảm biến nếu máy chủ hệ thống
sẽ 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ì đợi poll()
được gọi, trong lớp trừu tượng phần cứng (HAL) của Cảm biến
HAL phải chủ động ghi sự kiện cảm biến vào FMQ của sự kiện bất cứ khi nào sự kiện cảm biến
có sẵn. HAL cũng chịu trách nhiệm ghi đúng bit vào
EventFlag
để khiến FMQ đọc trong khung này.
Sự kiện WAKE_UP
Trong Cảm biến HAL 1.0, HAL có thể mở khóa chế độ thức cho bất kỳ WAKE_UP
nào
sự kiện trên bất kỳ lệnh gọi nào tiếp theo tới poll()
sau khi WAKE_UP
được đăng lên
poll()
vì điều này cho biết rằng khung đã xử lý mọi cảm biến
và đã có khoá chế độ thức, nếu cần thiết. Bởi vì, trong AIDL Cảm biến
HAL, HAL không còn được thông báo khi khung đã xử lý sự kiện
được ghi vào FMQ, FMQ của Wake Lock cho phép khung giao tiếp với
HAL (Lớp trừu tượng phần cứng) khi đã xử lý các sự kiện WAKE_UP
.
Trong AIDL HAL của Cảm biến, khoá chế độ thức được bảo vệ bằng HAL Cảm biến cho WAKE_UP
sự kiện 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.
AIDL HAL của cảm biến yêu cầu onDynamicSensorsConnected
và
onDynamicSensorsDisconnected
trong ISensorsCallback
sẽ được gọi bất cứ khi nào động
kết nối cảm biến 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
Phải hỗ trợ chế độ DATA_INJECTION
cho WAKE_UP
cảm biến.
Hỗ trợ nhiều HAL
Cảm biến AIDL HAL hỗ trợ nhiều HAL bằng cách sử dụng Khung nhiều lớp cảm biến (multi-HAL). Để chi tiết triển khai, xem Chuyển dữ liệu từ cảm biến HAL 2.1.