感應器 HAL 介面 (在 sensors.h 中宣告) 代表 Android 架構和硬體專屬軟體之間的介面。HAL 實作必須定義 sensor.h 中宣告的每個函式。主要功能如下:
get_sensors_list
- 傳回所有感應器的清單。activate
:啟動或停止感應器。batch
:設定感應器的參數,例如取樣頻率和最大回報延遲時間。setDelay
- 僅用於 HAL 1.0 版。可設定特定感應器的取樣頻率。flush
- 刷新指定感應器的 FIFO,並在作業完成後回報清除完成的事件。poll
- 傳回可用的感應器事件。
實作項目必須是執行緒安全的,並允許從不同的執行緒呼叫這些函式。
介面也會定義這些函式使用的幾種類型。主要類型如下:
sensors_module_t
sensors_poll_device_t
sensor_t
sensors_event_t
除了下文所述的部分外,請參閱 sensors.h 進一步瞭解這些類型。
get_sensors_list(list)
int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t const** list);
提供 HAL 實作的感應器清單。如要進一步瞭解感應器的定義,請參閱 sensor_t。
感應器在清單中顯示的順序,就是感應器向應用程式回報的順序。通常會先顯示基礎感應器,接著顯示複合感應器。
如果多個感應器共用相同的感應器類型和喚醒屬性,清單中的第一個感應器就會稱為「預設」感應器。而是 getDefaultSensor(int sensorType, bool wakeUp)
傳回的值。
這個函式會傳回清單中的感應器數量。
enable(sensor, true/false)
int (*activate)(struct sensors_poll_device_t *dev, int sensor_handle, int enabled);
啟用或停用感應器。
sensor_handle
是要啟用/停用的感應器控點。感應器的句柄是由其 sensor_t 結構體的 handle
欄位定義。
將 enabled
設為 1 可啟用感應器,設為 0 則可停用感應器。
一次性感應器會在收到事件時自動停用,且仍必須透過呼叫 activate(...,
enabled=0)
接受停用。
非喚醒感應器絕不會阻止 SoC 進入休眠模式,也就是說,HAL 不得代表應用程式保留部分喚醒鎖定。
喚醒感應器在持續傳送事件時,可以防止 SoC 進入暫停模式,但如果不需要傳送事件,則必須釋放部分喚醒鎖定。
如果 enabled
為 1,且感應器已啟用,則此函式會執行無操作並成功。
如果 enabled
為 0,且感應器已停用,則此函式會執行無操作並成功。
這個函式在成功時會傳回 0,否則會傳回負數錯誤代碼。
batch(感應器, 旗標, 取樣期間, 報表延遲時間上限)
int (*batch)( struct sensors_poll_device_1* dev, int sensor_handle, int flags, int64_t sampling_period_ns, int64_t max_report_latency_ns);
設定感應器的參數,包括取樣頻率和最大回報延遲時間。這個函式可在感應器啟用時呼叫,但不得導致任何感應器測量資料遺失:從一個取樣率轉換至另一個取樣率時,不得導致事件遺失,也不能從較高的最大回報延遲轉換為較低的最大回報延遲。
sensor_handle
是所要設定的感應器的句柄。
flags
目前未使用。
sampling_period_ns
是感應器應執行的取樣週期,以奈秒為單位。詳情請參閱 sampling_period_ns。
max_report_latency_ns
是事件透過 HAL 回報前可延遲的最大時間,以奈秒為單位。詳情請參閱「max_report_latency_ns」段落。
這個函式在成功時會傳回 0,否則會傳回負數錯誤代碼。
setDelay(sensor, sampling period)
int (*setDelay)( struct sensors_poll_device_t *dev, int sensor_handle, int64_t sampling_period_ns);
在 HAL 1.0 版之後,這個函式已淘汰,且不會再呼叫。而是呼叫 batch
函式來設定 sampling_period_ns
參數。
在 HAL 1.0 版中,使用 setDelay 而非 batch 來設定 sampling_period_ns。
flush(sensor)
int (*flush)(struct sensors_poll_device_1* dev, int sensor_handle);
將清除完成事件新增至指定感應器的硬體 FIFO 結尾,並清除 FIFO;這些事件會照常傳送 (也就是說,如果回報延遲時間上限已到期),並從 FIFO 中移除。
清除以非同步方式進行,亦即這個函式必須立即傳回。如果實作項目針對多個感應器使用單一 FIFO,該 FIFO 就會清除,且只會針對指定的感應器新增清除完成事件。
如果指定的感應器沒有 FIFO (無法進行緩衝處理),或者 FIFO 呼叫時為空白,則 flush
仍必須成功,並為該感應器傳送清除完成事件。除了單一鏡頭感應器之外,所有感應器都適用這項做法。
呼叫 flush
時,即使該感應器的 FIFO 中已包含一個刷新事件,仍必須建立並新增另一個事件至 FIFO 的結尾,且必須刷新 FIFO。flush
呼叫次數必須等於建立的清除完成事件數量。
flush
不適用於一次性感應器;如果 sensor_handle
是指一次性感應器,flush
必須傳回 -EINVAL
,且不得產生任何清除完成中繼資料事件。
這個函式會在成功時傳回 0,如果指定的感應器是一次性感應器或未啟用,就會傳回 -EINVAL
,否則會傳回負錯誤數。
poll()
int (*poll)(struct sensors_poll_device_t *dev, sensors_event_t* data, int
count);
透過填入 data
引數以傳回感應器資料陣列。此函式必須封鎖,直到事件可用為止。它會傳回成功讀取的事件數,如果發生錯誤,則會傳回負錯誤數。
data
中傳回的事件數量必須小於或等於 count
引數。這個函式絕不會傳回 0 (無事件)。
呼叫順序
裝置啟動時,系統會呼叫 get_sensors_list
。
感應器啟用時,系統會以所要求的參數呼叫 batch
函式,接著呼叫 activate(..., enable=1)
。
請注意,在 HAL 1_0 版本中,順序是相反的:先呼叫 activate
,再呼叫 set_delay
。
當感應器在啟用期間變更所要求的特徵時,系統會呼叫 batch
函式。
flush
可隨時呼叫,即使是未啟用的感應器也一樣 (在這種情況下,它必須傳回 -EINVAL
)
感應器停用時,系統會呼叫 activate(..., enable=0)
。
與這些呼叫並行,系統會重複呼叫 poll
函式,以便要求資料。即使未啟用感應器,還是可以呼叫 poll
。
sensors_module_t
sensors_module_t
是用於建立感應器 Android 硬體模組的類型。HAL 的實作項目必須定義此類型的 HAL_MODULE_INFO_SYM
物件,才能公開 get_sensors_list 函式。詳情請參閱 sensors.h 中的 sensors_module_t
定義,以及 hw_module_t
的定義。
sensors_poll_device_t / sensors_poll_device_1_t
sensors_poll_device_1_t
包含上述定義的其他方法:activate
、batch
、flush
和 poll
。其 common
欄位 (類型為 hw_device_t) 定義 HAL 的版本號碼。
sensor_t
sensor_t
代表 Android 感應器。以下是其中一些重要欄位:
name:代表感應器的使用者可見字串。這個字串通常包含底層感應器的零件名稱、感應器類型,以及是否為喚醒感應器。例如「LIS2HH12 加速計」、「MAX21000 未校正陀螺儀」、「BMP280 起床溫度計」、「MPU6515 遊戲旋轉向量」
handle:在註冊或產生事件時,用於參照感應器的整數。
type:感應器類型。如要進一步瞭解感應器類型,請參閱「Android 感應器是什麼?」一文中的說明,並參閱「感應器類型」一文,瞭解官方感應器類型。如果是非官方感應器類型,type
必須以 SENSOR_TYPE_DEVICE_PRIVATE_BASE
開頭
stringType:感應器類型,以字串表示。如果感應器有官方類型,請設為 SENSOR_STRING_TYPE_*
。如果感應器有製造商專屬類型,stringType
的開頭必須是製造商反向網域名稱。舉例來說,Fictional-Company 的 Cool-product 團隊定義的傳感器 (例如獨角獸偵測器) 可以使用 stringType=”com.fictional_company.cool_product.unicorn_detector”
。stringType
用於識別非官方感應器類型。如要進一步瞭解類型和字串類型,請參閱 sensors.h。
requiredPermission:字串,代表應用程式必須具備的權限,才能查看感應器、註冊感應器並接收其資料。如果為空字串,表示應用程式不需要任何權限即可存取此感應器。心率監測器等某些感應器類型有必要的 requiredPermission
。所有提供機密使用者資訊 (例如心率) 的感應器都必須透過權限保護。
flags:此感應器的標記,定義感應器的回報模式,以及感應器是否為喚醒感應器。例如,一次性喚醒感應器的 flags = SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP
。目前 HAL 版本中未使用的標記位元必須等於 0。
maxRange:感應器可回報的最大值,單位與回報值相同。感應器必須能夠在 [-maxRange; maxRange]
內回報值,且不會飽和。請注意,這表示一般感測中感應器的總範圍為 2*maxRange
。當感應器回報多個軸的值時,範圍會套用至每個軸。舉例來說,「+/- 2g」加速計會回報 maxRange = 2*9.81 = 2g
。
解析度:感應器可測量值的最小差異。通常會根據 maxRange
和測量值中的位元數計算。
power:啟用感應器的耗電量 (以毫安培為單位)。這幾乎總是基礎感應器規格表中所報的耗電量。詳情請參閱「基本感應器 != 實體感應器」一文,並參閱「電源測量程序」一文,進一步瞭解如何測量感應器的耗電量。如果感應器的耗電量取決於裝置是否移動,則 power
欄位回報的耗電量即為移動時的耗電量。
minDelay:針對連續感應器,取樣週期以微秒為單位,對應感應器支援的最快速率。如要進一步瞭解這個值的使用方式,請參閱 sampling_period_ns。請注意,minDelay
是以微秒為單位,而 sampling_period_ns
是以奈秒為單位。如果感應器處於變更狀態和特殊報表模式,除非另有指定,否則 minDelay
必須為 0。對於一次性感應器,此值必須為 -1。
maxDelay:針對連續和變化感應器,取樣週期以微秒為單位,對應感應器支援的最慢速率。如要進一步瞭解這個值的使用方式,請參閱 sampling_period_ns。請注意,maxDelay
是以微秒為單位,而 sampling_period_ns
是以奈秒為單位。對於特殊和一次性感應器,maxDelay
必須為 0。
fifoReservedEventCount:硬體 FIFO 中為此感應器保留的事件數量。如果此感應器有專屬的 FIFO,則 fifoReservedEventCount
就是這個專屬 FIFO 的大小。如果 FIFO 與其他感應器共用,fifoReservedEventCount
就是 FIFO 為該感應器保留的部分大小。在大多數共用 FIFO 系統和沒有硬體 FIFO 的系統中,這個值為 0。
fifoMaxEventCount:可儲存在此感應器 FIFO 中的事件數量上限。這個值一律大於或等於 fifoReservedEventCount
。這個值用於預估以特定速率向感應器註冊時,FIFO 會充飽電的速度,不會啟用其他任何感應器。在沒有硬體 FIFO 的系統中,fifoMaxEventCount
為 0。詳情請參閱「批次處理」一節。
對於具有官方感應器類型的感應器,架構會覆寫部分欄位。舉例來說,加速計感應器會強制採用連續回報模式,而心率監測器則會強制使用 SENSOR_PERMISSION_BODY_SENSORS
權限進行保護。
sensors_event_t
由 Android 感應器產生,並透過 poll 函式回報的感應器事件,其類型為 type sensors_event_t
。以下是 sensors_event_t
的一些重要欄位:
version:必須為 sizeof(struct sensors_event_t)
sensor:產生事件的感應器句柄,如 sensor_t.handle
所定義。
type:產生事件的感應器類型,如 sensor_t.type
所定義。
timestamp:事件的時間戳記,以奈秒為單位。這是事件發生的時間 (步數或加速度計測量值),而非事件回報時間。timestamp
必須與 elapsedRealtimeNano
時鐘同步,如果是連續感應器,則時基誤差必須較小。有時必須進行時間戳記篩選,才能符合 CDD 規定,因為只使用 SoC 中斷時間設定時間戳記會導致抖動過高,而只使用感應器晶片時間設定時間戳記,可能會因感應器時鐘漂移而與 elapsedRealtimeNano
時鐘失去同步。
data and OverpingField. (資料與重疊欄位):感應器測量的值。這些欄位的含義和單位會因感應器類型而異。如需資料欄位的說明,請參閱 sensors.h 和不同感應器類型的定義。某些感應器的讀數準確度也會透過 status
欄位回報為資料的一部分。這個欄位只會傳送至所選感應器類型,並在 SDK 層級顯示為精確度值。對於這些感應器,其 sensor type 定義會提及必須設定狀態欄位。
中繼資料清除完成事件
中繼資料事件的類型與一般感應器事件相同:sensors_event_meta_data_t = sensors_event_t
。這些事件會透過輪詢與其他感應器事件一併傳回。這些記錄包含下列欄位:
版本:必須為 META_DATA_VERSION
type:必須是 SENSOR_TYPE_META_DATA
sensor、reserved 和 timestamp:必須為 0
meta_data.what:包含這個事件的中繼資料類型。目前有一個有效的中繼資料類型:META_DATA_FLUSH_COMPLETE
。
META_DATA_FLUSH_COMPLETE
事件代表感應器 FIFO 的清除作業已完成。當 meta_data.what=META_DATA_FLUSH_COMPLETE
時,meta_data.sensor
必須設為已清除的感應器手把。只有在感應器呼叫 flush
時才會產生。詳情請參閱「flush」函式相關章節。