Giao diện Sensors HAL (Lớp trừu tượng phần cứng cảm biến) được khai báo trong sensors.h, đại diện cho giao diện giữa khung Android và phần mềm dành riêng cho phần cứng. Một quy trình triển khai HAL phải xác định từng hàm được khai báo trong sensors.h. Các hàm chính là:
get_sensors_list
– Trả về danh sách tất cả các cảm biến.activate
– Bắt đầu hoặc dừng một cảm biến.batch
– Đặt các thông số của cảm biến, chẳng hạn như tần suất lấy mẫu và độ trễ báo cáo tối đa.setDelay
– Chỉ dùng trong HAL phiên bản 1.0. Đặt tần suất lấy mẫu cho một cảm biến nhất định.flush
– Xoá FIFO của cảm biến đã chỉ định và báo cáo sự kiện xoá hoàn tất khi quá trình này hoàn tất.poll
– Trả về các sự kiện cảm biến hiện có.
Quá trình triển khai phải an toàn cho luồng và cho phép gọi các hàm này từ nhiều luồng.
Giao diện này cũng xác định một số loại được dùng bởi các hàm đó. Các loại chính là:
sensors_module_t
sensors_poll_device_t
sensor_t
sensors_event_t
Ngoài các phần dưới đây, hãy xem sensors.h để biết thêm thông tin về các loại này.
get_sensors_list(list)
int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t const** list);
Cung cấp danh sách các cảm biến do HAL triển khai. Hãy xem sensor_t để biết thông tin chi tiết về cách xác định các cảm biến.
Thứ tự xuất hiện của các cảm biến trong danh sách là thứ tự mà các cảm biến sẽ được báo cáo cho các ứng dụng. Thông thường, các cảm biến cơ bản sẽ xuất hiện trước, sau đó là các cảm biến tổng hợp.
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". Đây là giá trị do getDefaultSensor(int sensorType, bool wakeUp)
trả về.
Hàm này trả về số lượng cảm biến trong danh sách.
activate(sensor, true/false)
int (*activate)(struct sensors_poll_device_t *dev, int sensor_handle, int enabled);
Kích hoạt hoặc huỷ kích hoạt một cảm biến.
sensor_handle
là tay cầm của cảm biến để kích hoạt/huỷ kích hoạt. Cấu trúc sensor_t của trường handle
xác định giá trị nhận dạng của cảm biến.
enabled
được đặt thành 1 để bật hoặc 0 để tắt cảm biến.
Các cảm biến một lần sẽ tự động huỷ kích hoạt khi nhận được một sự kiện và chúng vẫn phải chấp nhận bị huỷ kích hoạt thông qua lệnh gọi đến activate(...,
enabled=0)
.
Các cảm biến không đánh thức không bao giờ ngăn SoC chuyển sang chế độ tạm ngưng; tức là HAL sẽ không giữ khoá đánh thức một phần thay cho các ứng dụng.
Khi liên tục truyền các sự kiện, các cảm biến đánh thức có thể ngăn SoC chuyển sang chế độ tạm ngưng, nhưng nếu không cần truyền sự kiện nào, thì phải giải phóng khoá đánh thức một phần.
Nếu enabled
là 1 và cảm biến đã được kích hoạt, thì hàm này sẽ không hoạt động và thành công.
Nếu enabled
là 0 và cảm biến đã bị huỷ kích hoạt, thì hàm này sẽ không hoạt động và thành công.
Hàm này trả về 0 khi thành công và một số lỗi âm nếu không.
batch(sensor, flags, sampling period, maximum report latency)
int (*batch)( struct sensors_poll_device_1* dev, int sensor_handle, int flags, int64_t sampling_period_ns, int64_t max_report_latency_ns);
Đặt các thông số của cảm biến, bao gồm tần suất lấy mẫu và độ trễ tối đa của báo cáo. Bạn có thể gọi hàm này trong khi cảm biến đang hoạt động. Trong trường hợp đó, hàm này không được làm mất bất kỳ phép đo cảm biến nào: Việc chuyển đổi từ tốc độ lấy mẫu này sang tốc độ lấy mẫu khác không được làm mất các sự kiện, cũng như việc chuyển đổi từ độ trễ báo cáo tối đa cao sang độ trễ báo cáo tối đa thấp.
sensor_handle
là tay cầm của cảm biến cần định cấu hình.
flags
hiện không được sử dụng.
sampling_period_ns
là khoảng thời gian lấy mẫu mà cảm biến sẽ chạy, tính bằng nano giây. Hãy xem sampling_period_ns để biết thêm thông tin chi tiết.
max_report_latency_ns
là thời gian tối đa mà các sự kiện có thể bị trễ trước khi được báo cáo thông qua HAL, tính bằng nano giây. Hãy xem đoạn max_report_latency_ns để biết thêm thông tin.
Hàm này trả về 0 khi thành công và một số lỗi âm nếu không.
setDelay(sensor, sampling period)
int (*setDelay)( struct sensors_poll_device_t *dev, int sensor_handle, int64_t sampling_period_ns);
Sau HAL phiên bản 1.0, hàm này không còn được dùng nữa và không bao giờ được gọi.
Thay vào đó, hàm batch
sẽ được gọi để đặt tham số sampling_period_ns
.
Trong HAL phiên bản 1.0, setDelay được dùng thay vì batch để đặt sampling_period_ns.
flush(sensor)
int (*flush)(struct sensors_poll_device_1* dev, int sensor_handle);
Thêm một sự kiện hoàn tất việc xoá vào cuối FIFO phần cứng cho cảm biến đã chỉ định và xoá FIFO; những sự kiện đó được gửi như bình thường (tức là: như thể độ trễ báo cáo tối đa đã hết hạn) và bị xoá khỏi FIFO.
Thao tác xoá xảy 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 được 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 tại 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, trừ cảm biến một lần.
Khi flush
được gọi, ngay cả khi sự kiện xoá đã có trong FIFO cho cảm biến đó, bạn phải tạo thêm một sự kiện và thêm vào cuối FIFO, đồng thời phải xoá FIFO. Số lượng lệnh gọi flush
phải bằng số lượng sự kiện hoàn tất lệnh xoá đã được tạo.
flush
không áp dụng cho các cảm biến một lần; nếu sensor_handle
đề cập đến một cảm biến một lần, thì flush
phải trả về -EINVAL
và không tạo bất kỳ sự kiện siêu dữ liệu hoàn tất nào.
Hàm này trả về 0 khi thành công, -EINVAL
nếu cảm biến được chỉ định là cảm biến một lần hoặc chưa được bật và trả về số lỗi âm trong trường hợp khác.
poll()
int (*poll)(struct sensors_poll_device_t *dev, sensors_event_t* data, int
count);
Trả về một mảng dữ liệu cảm biến bằng cách điền đối số data
. Hàm này phải chặn cho đến khi có sự kiện. Hàm này sẽ trả về số lượng sự kiện đã đọc khi thành công hoặc một số lỗi âm trong trường hợp xảy ra lỗi.
Số lượng sự kiện được trả về trong data
phải nhỏ hơn hoặc bằng đối số count
. Hàm này sẽ không bao giờ trả về 0 (không có sự kiện).
Trình tự các cuộc gọi
Khi thiết bị khởi động, get_sensors_list
sẽ được gọi.
Khi một cảm biến được kích hoạt, hàm batch
sẽ được gọi bằng các tham số được yêu cầu, sau đó là activate(..., enable=1)
.
Xin lưu ý rằng trong HAL phiên bản 1_0, thứ tự ngược lại: activate
được gọi trước, sau đó là set_delay
.
Khi các đặc điểm được yêu cầu của một cảm biến đang thay đổi trong khi cảm biến đó được kích hoạt, hàm batch
sẽ được gọi.
flush
có thể được gọi bất cứ lúc nào, ngay cả trên các cảm biến không được kích hoạt (trong trường hợp đó, nó phải trả về -EINVAL
)
Khi một cảm biến bị vô hiệu hoá, activate(..., enable=0)
sẽ được gọi.
Song song với các lệnh gọi đó, hàm poll
sẽ được gọi nhiều lần để yêu cầu dữ liệu. Bạn có thể gọi poll
ngay cả khi không có cảm biến nào được kích hoạt.
sensors_module_t
sensors_module_t
là loại dùng để tạo mô-đun phần cứng Android cho các cảm biến. Việc triển khai HAL phải xác định một đối tượng HAL_MODULE_INFO_SYM
thuộc loại này để hiển thị hàm get_sensors_list. Hãy xem định nghĩa về sensors_module_t
trong sensors.h và định nghĩa về hw_module_t
để biết thêm thông tin.
sensors_poll_device_t / sensors_poll_device_1_t
sensors_poll_device_1_t
chứa các phương thức còn lại được xác định ở trên: activate
, batch
, flush
và poll
. Trường common
(thuộc loại hw_device_t) xác định số phiên bản của HAL.
sensor_t
sensor_t
đại diện cho một cảm biến Android. Sau đây là một số trường quan trọng của đối tượng này:
name: Một chuỗi mà người dùng nhìn thấy, đại diện cho cảm biến. Chuỗi này thường chứa tên bộ phận của cảm biến cơ bản, loại cảm biến và liệu đó có phải là cảm biến đánh thức hay không. Ví dụ: "LIS2HH12 Accelerometer", "MAX21000 Uncalibrated Gyroscope", "BMP280 Wake-up Barometer", "MPU6515 Game Rotation Vector"
handle: Số nguyên dùng để tham chiếu đến cảm biến khi đăng ký hoặc tạo sự kiện từ cảm biến đó.
type: Loại cảm biến. Hãy xem phần giải thích về loại cảm biến trong bài viết Cảm biến Android là gì? để biết thêm thông tin chi tiết và xem Các loại cảm biến để biết các loại cảm biến chính thức. Đối với các loại cảm biến không chính thức, type
phải bắt đầu bằng SENSOR_TYPE_DEVICE_PRIVATE_BASE
stringType: Loại cảm biến dưới dạng chuỗi. Khi cảm biến có một loại chính thức, hãy đặt thành SENSOR_STRING_TYPE_*
. Khi cảm biến có một loại cụ thể của nhà sản xuất, stringType
phải bắt đầu bằng tên miền đảo ngược của nhà sản xuất. Ví dụ: một cảm biến (chẳng hạn như một bộ phát hiện kỳ lân) do nhóm Cool-product tại Fictional-Company xác định có thể sử dụng stringType=”com.fictional_company.cool_product.unicorn_detector”
.
stringType
được dùng để xác định riêng biệt các loại cảm biến không chính thức. Hãy xem sensors.h để biết thêm thông tin về các loại và loại chuỗi.
requiredPermission: Một chuỗi đại diện cho quyền mà các ứng dụng phải có để xem cảm biến, đăng ký với cảm biến và nhận dữ liệu của cảm biến. Một chuỗi trống có nghĩa là các ứng dụng không cần có bất kỳ quyền nào để truy cập vào cảm biến này. Một số loại cảm biến như máy đo nhịp tim có requiredPermission
bắt buộc. Tất cả các cảm biến cung cấp thông tin nhạy cảm về người dùng (chẳng hạn như nhịp tim) đều phải được bảo vệ bằng một quyền.
flags: Cờ cho cảm biến này, xác định chế độ báo cáo của cảm biến và liệu cảm biến có phải là cảm biến đánh thức hay không. Ví dụ: cảm biến đánh thức một lần sẽ có flags = SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP
. Các bit của cờ không được dùng trong phiên bản HAL hiện tại phải được giữ nguyên bằng 0.
maxRange: Giá trị tối đa mà cảm biến có thể báo cáo, theo cùng đơn vị với các giá trị được báo cáo. Cảm biến phải có khả năng báo cáo các giá trị mà không bị bão hoà trong vòng [-maxRange; maxRange]
. Xin lưu ý rằng điều này có nghĩa là tổng phạm vi của cảm biến theo nghĩa chung là 2*maxRange
. Khi cảm biến báo cáo các giá trị trên nhiều trục, phạm vi sẽ áp dụng cho từng trục. Ví dụ: gia tốc kế "+/- 2g" sẽ báo cáo maxRange = 2*9.81 = 2g
.
độ phân giải: Mức chênh lệch nhỏ nhất về giá trị mà cảm biến có thể đo lường.
Thường được tính dựa trên maxRange
và số lượng bit trong phép đo.
power: Chi phí năng lượng khi bật cảm biến, tính bằng miliAmpe.
Mức tiêu thụ điện năng này gần như luôn cao hơn mức tiêu thụ điện năng được báo cáo trong bảng dữ liệu của cảm biến cơ bản. Hãy xem bài viết Cảm biến cơ bản != cảm biến vật lý để biết thêm thông tin chi tiết và xem bài viết Quy trình đo lường mức tiêu thụ điện để biết thông tin chi tiết về cách đo lường mức tiêu thụ điện của một cảm biến.
Nếu mức tiêu thụ điện của cảm biến phụ thuộc vào việc thiết bị có đang di chuyển hay không, thì mức tiêu thụ điện khi di chuyển là mức được báo cáo trong trường power
.
minDelay: Đối với các cảm biến liên tục, khoảng thời gian lấy mẫu (tính bằng micro giây) tương ứng với tốc độ nhanh nhất mà cảm biến hỗ trợ. Hãy xem sampling_period_ns để biết thông tin chi tiết về cách sử dụng giá trị này. Lưu ý rằng minDelay
được biểu thị bằng micro giây trong khi sampling_period_ns
được biểu thị bằng nano giây. Đối với các cảm biến ở chế độ báo cáo đặc biệt và khi có thay đổi, trừ phi có quy định khác, minDelay
phải bằng 0. Đối với cảm biến một lần, giá trị này phải là -1.
maxDelay: Đối với các cảm biến liên tục và cảm biến khi có thay đổi, khoảng thời gian lấy mẫu, tính bằng micro giây, tương ứng với tốc độ chậm nhất mà cảm biến hỗ trợ. Hãy xem sampling_period_ns để biết thông tin chi tiết về cách sử dụng giá trị này. Lưu ý rằng maxDelay
được biểu thị bằng micro giây trong khi sampling_period_ns
được biểu thị bằng nano giây. Đối với các cảm biến đặc biệt và cảm biến một lần, maxDelay
phải là 0.
fifoReservedEventCount: Số lượng sự kiện được dành riêng cho cảm biến này trong FIFO phần cứng. Nếu có một FIFO chuyên dụng cho cảm biến này, thì fifoReservedEventCount
là kích thước của FIFO chuyên dụng này. Nếu FIFO được chia sẻ với các cảm biến khác, thì fifoReservedEventCount
là kích thước của phần FIFO được dành riêng cho cảm biến đó. Trên hầu hết các hệ thống FIFO dùng chung và trên các hệ thống không có FIFO phần cứng, giá trị này là 0.
fifoMaxEventCount: Số lượng sự kiện tối đa có thể được lưu trữ trong FIFO cho cảm biến này. Giá trị này luôn lớn hơn hoặc bằng fifoReservedEventCount
. Giá trị này được dùng để ước tính tốc độ đầy của FIFO khi đăng ký với cảm biến ở một tốc độ cụ thể, giả sử không có cảm biến nào khác được kích hoạt. Trên các hệ thống không có FIFO phần cứng, fifoMaxEventCount
là 0. Hãy xem phần Xử lý theo lô để biết thêm thông tin.
Đối với các cảm biến có loại cảm biến chính thức, một số trường sẽ bị khung ghi đè. Ví dụ: các cảm biến gia tốc kế buộc phải có chế độ báo cáo liên tục và các máy đo nhịp tim buộc phải được bảo vệ bằng quyền SENSOR_PERMISSION_BODY_SENSORS
.
sensors_event_t
Các sự kiện cảm biến do cảm biến Android tạo và được báo cáo thông qua hàm poll thuộc type sensors_event_t
. Sau đây là một số trường quan trọng của sensors_event_t
:
version: Phải là sizeof(struct sensors_event_t)
sensor: Xử lý cảm biến đã tạo sự kiện, như được xác định bởi sensor_t.handle
.
type: Loại cảm biến của cảm biến đã tạo sự kiện, như được xác định bởi sensor_t.type
.
timestamp: Dấu thời gian của sự kiện (tính bằng nano giây). Đây là thời điểm sự kiện xảy ra (một bước đã được thực hiện hoặc một phép đo gia tốc kế đã được thực hiện), chứ không phải thời điểm sự kiện được báo cáo. timestamp
phải được đồng bộ hoá với đồng hồ elapsedRealtimeNano
và trong trường hợp các cảm biến liên tục, độ rung phải nhỏ. Đôi khi, bạn cần lọc dấu thời gian để đáp ứng các yêu cầu của CDD, vì chỉ sử dụng thời gian ngắt SoC để đặt dấu thời gian sẽ gây ra độ trễ quá cao và chỉ sử dụng thời gian của chip cảm biến để đặt dấu thời gian có thể gây ra tình trạng mất đồng bộ hoá từ đồng hồ elapsedRealtimeNano
, vì đồng hồ cảm biến bị trôi.
dữ liệu và các trường trùng lặp: Các giá trị do cảm biến đo được. Ý nghĩa và đơn vị của các trường đó dành riêng cho từng loại cảm biến. Hãy xem sensors.h và định nghĩa về các Loại cảm biến khác nhau để biết nội dung mô tả về các trường dữ liệu. Đối với một số cảm biến, độ chính xác của các chỉ số cũng được báo cáo trong dữ liệu, thông qua trường status
. Trường này chỉ được truyền qua cho những loại cảm biến được chọn, xuất hiện ở lớp SDK dưới dạng giá trị độ chính xác. Đối với những cảm biến đó, thực tế là bạn phải đặt trường trạng thái được đề cập trong định nghĩa loại cảm biến của chúng.
Sự kiện hoàn tất việc xoá siêu dữ liệu
Các sự kiện siêu dữ liệu có cùng loại với các sự kiện cảm biến thông thường: sensors_event_meta_data_t = sensors_event_t
. Chúng được trả về cùng với các sự kiện cảm biến khác thông qua quá trình thăm dò. Chúng có các trường sau:
version: Phải là META_DATA_VERSION
type: Phải là SENSOR_TYPE_META_DATA
sensor, reserved và timestamp: Phải là 0
meta_data.what: Chứa loại siêu dữ liệu cho sự kiện này. Hiện tại, chỉ có một loại siêu dữ liệu hợp lệ: META_DATA_FLUSH_COMPLETE
.
Các sự kiện META_DATA_FLUSH_COMPLETE
biểu thị việc hoàn tất quá trình xoá FIFO cảm biến. Khi meta_data.what=META_DATA_FLUSH_COMPLETE
, meta_data.sensor
phải được đặt thành giá trị nhận dạng của cảm biến đã được xoá. Chúng được tạo khi và chỉ khi flush
được gọi trên một cảm biến. Hãy xem phần về hàm flush để biết thêm thông tin.