linux驅動由淺入深系列:高通sensor架構實例分析之一

linux驅動由淺入深系列:高通sensor架構實例分析之一(整體概覽+AP側代碼分析)

linux驅動由淺入深系列:高通sensor架構實例分析之二(adsp驅動代碼結構)
Linux驅動由淺入深系列:高通sensor架構例分析之三(adsp上報數據詳解、校準流程詳解)

 

最初的時候芯片廠家對sensor的處理和對待其它外設一樣都是直接掛在processor上,sensor的驅動也和其他linux或android的驅動一樣,生成對應的設備節點給上層提供數據(關於此類linux基礎驅動的知識,可以參考本博客其他博文)。但後來這一切發生了變化,最主要的原因就是功耗。Sensor希望自己能夠一直處於工作狀態下,如計步器等應用場景。這樣如果sensor還掛在主processor上(這時候處理器就分多核啦)勢必影響待機功耗。因此各個芯片廠推出了各自的方案,如sensor-hub等等。高通在MSM8960之後就將sensor的處理塞到了一個單獨的音頻dsp中了(MSM8953中這個dsp叫作aDSP),這樣待機時主處理器休眠降低功耗,由這個aDSP在處理音頻數據的間隙捎帶着就能把sensor的數據處理了^^。下面以MSM8953爲例分析一下其結構。

 

高通sensor軟件架構

首先來看一下高通sensor處理的軟件框圖:

 

1,  框圖上半部分是應用處理器,下半部分是aDSP。

2,  aDSP中包含了log接口,電源管理,sensor算法庫,sensor校準,各個sensor的管理模塊。最後一個是直接掛載各個傳感器的(Prox、Press、Mag、Gyro、Acc),軟件中的主要部分叫作SMGR。[上圖文字怎麼亂了,補充一張^-^]

 

3,  在應用處理器中,軟件接口中不再有每個sensor的設備節點了。那有的是什麼呢,只有Sensor1 API Socket Remoting Layer層對應的API接口。這個接口是本文的重點,下文詳細解釋。

4,  那麼aDSP與應用處理器之間用什麼機制進行通信呢?圖中可以看到一個叫QMI的東西,就是它了,這個高通基於共享內存機制開發的多核間通信技術,在應用處理器側和aDSP側都有相應的庫已經完成了底層實現。之後有機會分析一下這種號稱最爲有效的多核間通信技術。

5,  應用處理器側還有些亂七八糟的藍色框,這部分是運行在應用處理器側的sensor算法、校準相關的東西。這是些只會在非待機模式運行的算法,就適合放在這個地方了。

 

android中sensor架構

在android中sensor的架構圖如下:

在Sensor1 API Socket Remoting Layer層的基礎上轉換成了android的Framwork層就可以被APP調用了,目前我們先以linux 應用程序的直接調用Sensor1 API Socket Remoting Layer層接口爲例進行演示。

 

高通sensor測試工具

高通爲sensor的測試提供了默認的工具,代碼位於:

vendor\qcom\proprietary\sensors\dsps\test\src\sns_dsps_tc0001.c

vendor\qcom\proprietary\sensors\dsps\test\src\sns_cm_test.cpp

編譯後生成對應的bin文件:

1,sns_dsps_tc0001用來查看當前系統掛載的sensor的相關信息:

 

 

2,sns_cm_test用來獲取對應sensor_id的傳感器數據:

 

 

Sensor的API接口:

1,

sensor1_error_e sensor1_open(sensor1_handle_s**hndl, sensor1_notify_data_cb_t data_cbf,  intptr_t cb_data );

hndl

Opaque handle used to identify this client

data_cbf

Pointer to the client’s callback function to process received data

cb_data

This data is set by the client and will be passed unmodified as a
parameter to the callback function

2,

typedef void (*sensor1_notify_data_cb_t) (uint32 cb_data, sensor1_msg_header_s* msg_hdr,  sensor1_msg_type_e msg_type, void *msg_ptr);

cb_data

Unmodified value passed in when the callback was registered in
sensor1_open()

msg_hdr

Message header defining the message

msg_type

Type of message

msg_ptr

Pointer to the QMI-based message; these messages are defined in their
respective service header files; client shall free this pointer via
sensor1_free_msg_buf()

3,

sensor1_error_e sensor1_close(sensor1_handle_s* hndl );

hndl

Opaque handle used to identify this client


4,

sensor1_error_e sensor1_write(sensor1_handle_s* hndl, sensor1_msg_header_s* msg_hdr, void *msg_ptr);

hndl

Opaque handle to identify this client

msg_hdr

Message header defining the message

msg_ptr

Pointer to the QMI-based request message; these messages are defined
in their respective service header files; memory pointed to shall be
allocated by sensor1_alloc_msg_buf()


5,

sensor1_error_e sensor1_writeable(sensor1_handle_s* hndl, sensor1_write_cb_t cbf, intptr_t cb_data, uint32_t service_number );

hndl

Opaque handle to identify this client

cbf

Pointer to the client’s callback function

cb_data

This data is set by the client and will be passed unmodified as a
parameter to the callback function

service_number

Client callback function will be called when it is possible that this
Service ID can accept new requests via sensor1_write


6,

typedef void (*sensor1_write_cb_t) (intptr_t cb_data, uint32_t service_number);

cb_data

Unmodified value passed in when the callback was registered in
sensor1_writable()

service_number

Service ID to which this callback refers


7,

sensor1_error_e sensor1_alloc_msg_buf(sensor1_handle_s* hndl,  uint16_t size,  void **buffer );

hndl

Opaque handle to identify this client

size

Size of the message structure

buffer

Address of a pointer to the memory address where the message should be
placed


8,

sensor1_error_e sensor1_free_msg_buf(sensor1_handle_s* hndl,  void* msg_buf );

hndl

Opaque handle to identify this client

msg_buf

Buffer to free


 

sns_cm_test.cpp代碼實例

有了上面的api接口介紹,來看一下sns_cm_test.cpp中對其使用就比較清晰了:

 

好吧,爲了避免麻煩,刪除了高通私有代碼演示,有代碼的去上面指出的文件分析即可。相信沒有代碼的也不會看這篇文章^^ 本文僅做學習交流目的,如有侵權請聯繫博主。


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章