1. 程式人生 > >高通sensor架構例項分析之三(adsp上報資料詳解、校準流程詳解)

高通sensor架構例項分析之三(adsp上報資料詳解、校準流程詳解)

本系列導航:


從adsp獲取資料的方法分為同步、非同步兩種方式,但一般在實際使用中使用非同步方式,因為同步獲取資料會因外設匯流排速率低的問題阻塞smgr,降低效率,增加功耗。

Sensor上報資料的方式分為如下幾種

sync          同步資料上報,(每次上報一個數據)

async        非同步資料上報,每次請求之後不阻塞,定時檢視狀態,(收到一個數據即上報)

self-scheduling         非同步資料上報,每次請求之後不阻塞,等待中斷或定時檢視狀態,(收到一個數據即上報)

FIFO          非同步資料上報,每次請求一組資料,當感測器資料累積設定水位,由水位中斷觸發一組資料上報。

S4S(Synchronization for Sensors)              用來同步時鐘,避免資料遺漏或同一資料被取兩次

在實際使用中歸納起來分成3種方式:

1,  (Polling)0x00同步方式[sync]:smgr向感測器請求資料,阻塞等待資料到來再返回;非同步方式[async]:呼叫一次get_data後啟動timer,等timer中斷到達後呼叫sns_ddf_driver_if_s中指定的handle_timer()函式上報一組感測器資料。handle_timer()中一般採用ddf提供的sns_ddf_smgr_notify_data()函式上報資料。

2,  (DRI)0x80又稱作[self-scheduling]

呼叫enable_sched_data()啟用DRI(DataReadyInterrupt,資料完成中斷),等待資料完成中斷或啟動timer按照set_cycle_time指定的ODR(Output Data Rate,資料輸出速率)進行資料採集,採集完成後呼叫sns_ddf_driver_if_s中指定的handle_irq()函式上報感測器資料。

3,  (FIFO)0xD0呼叫trigger_fifo_data()函式啟動FIFO模式,當資料量到達指定的閾值,觸發sns_ddf_smgr_data_notify()函式上報一批資料。

(handle_irq->report_data->sns_ddf_smgr_notify_data  上報資料)

 一般加速度、陀螺儀等資料量較大的使用FIFO模式,光線、距離等有資料有變化才需要上報的感測器使用DRI模式。

下面以g-sensor bmi160為例具體分析一下:

  1. sns_ddf_driver_if_s SNS_DD_IF_BMI160 =  
  2. {  
  3.     .init                 = &sns_dd_bmi160_init,  
  4.     .get_data             = &sns_dd_bmi160_get_data,  
  5.     .set_attrib           = &sns_dd_bmi160_set_attr,  
  6.     .get_attrib           = &sns_dd_bmi160_get_attr,  
  7.     .handle_timer         = &sns_dd_bmi160_handle_timer,  
  8.     .handle_irq           = &sns_dd_bmi160_interrupt_handler,  
  9.     .reset                = &sns_dd_bmi160_reset,  
  10.     .run_test             = &sns_dd_bmi160_self_test,  
  11.     .enable_sched_data    = &sns_dd_bmi160_enable_sched_data,  
  12.     .probe                = &sns_dd_bmi160_probe,  
  13.     .trigger_fifo_data    = &sns_dd_bmi160_trigger_fifo_data  
  14. };  

這個結構體是實現高通adsp下sensor驅動的關鍵,驅動程式只需要實現相應的函式,然後將結構體指標填到smgr_sensor_fn_ptr_map表中就會被系統註冊了。

仔細觀察上述結構體中的函式發現有的函式在sns_dd_xxxx.c檔案中如sns_dd_bmi160_init,有的則在sns_dd_xxxx_uimg.c檔案中中如&sns_dd_bmi160_get_data,其實這是一種高通adsp側程式碼特有的架構,即帶有uimg標識的程式碼執行在快取中,其中程式碼一般是做資料上報相關工作的,執行期間可以將外部ddr關閉以實現最低功耗的感測器執行;不帶有umig標識的程式碼執行期間是需要ddr開啟的,其中程式碼一般做一些初始化相關的工作。

下面列出高通平臺上對感測器型別的編號,有一個整體認識。
  1. typedefenum
  2. {  
  3.   SNS_DDF_SENSOR__NONE, // 0
  4.   SNS_DDF_SENSOR_ACCEL, // 1
  5.   SNS_DDF_SENSOR_MAG, // 2
  6.   SNS_DDF_SENSOR_GYRO, // 3
  7.   SNS_DDF_SENSOR_TEMP, // 4
  8.   SNS_DDF_SENSOR_PROXIMITY, // 5
  9.   SNS_DDF_SENSOR_AMBIENT, // 6
  10.   SNS_DDF_SENSOR_PRESSURE, // 7
  11.   SNS_DDF_SENSOR_MAG_6D, // 8
  12.   SNS_DDF_SENSOR_GYRO_6D, // 9
  13.   SNS_DDF_SENSOR_DOUBLETAP, // 10
  14.   SNS_DDF_SENSOR_SINGLETAP, // 11
  15.   SNS_DDF_SENSOR_IR_GESTURE, //12
  16.   SNS_DDF_SENSOR_OEM_SENSOR_01// 13
  17.   SNS_DDF_SENSOR_OEM_SENSOR_02// 14
  18.   SNS_DDF_SENSOR_OEM_SENSOR_03// 15
  19.   SNS_DDF_SENSOR_OEM_SENSOR_04// 16
  20.   SNS_DDF_SENSOR_OEM_SENSOR_05// 17
  21.   SNS_DDF_SENSOR_OEM_SENSOR_06// 18
  22.   SNS_DDF_SENSOR_OEM_SENSOR_07// 19
  23.   SNS_DDF_SENSOR_OEM_SENSOR_08// 20
  24.   SNS_DDF_SENSOR_OEM_SENSOR_09// 21
  25.   SNS_DDF_SENSOR_OEM_SENSOR_10// 22
  26.   SNS_DDF_SENSOR_STEP_EVENT, // 23
  27.   SNS_DDF_SENSOR_STEP_COUNT, // 24
  28.   SNS_DDF_SENSOR_SMD, // 25
  29.   SNS_DDF_SENSOR_GAME_RV, // 26
  30.   SNS_DDF_SENSOR_HUMIDITY, // 27
  31.   SNS_DDF_SENSOR_RGB, // 28
  32.   SNS_DDF_SENSOR_CT_C, // 29
  33.   SNS_DDF_SENSOR_SAR, // 30
  34.   SNS_DDF_SENSOR_HALL_EFFECT, // 31 
  35.   SNS_DDF_SENSOR_AMBIENT_TEMP, // 32
  36.   SNS_DDF_SENSOR_ULTRA_VIOLET, // 33
  37.   SNS_DDF_SENSOR_HEART_RATE, //34
  38.   SNS_DDF_SENSOR_HEART_RATE_RAW, //35
  39.   SNS_DDF_SENSOR_OBJECT_TEMP, //36
  40.   SNS_DDF_SENSOR_TILT_EVENT,  //37
  41.   SNS_DDF_SENSOR_ORIENTATION_EVENT,   //38 
  42.   SNS_DDF_SENSOR__ALL,        /**< Addresses all sensors */
  43.   SNS_DDF_SENSOR_LAST  
  44. } sns_ddf_sensor_e;  

在具體看資料流程之前,先了解一下高通定義的各種用來配置感測器的屬性

  1. typedefenum
  2. {  
  3.     SNS_DDF_ATTRIB_POWER_INFO,//0
  4.     SNS_DDF_ATTRIB_POWER_STATE,//1
  5.     SNS_DDF_ATTRIB_DELAYS,//2
  6.     SNS_DDF_ATTRIB_RANGE,//3
  7.     SNS_DDF_ATTRIB_RESOLUTION_ADC,//4
  8.     SNS_DDF_ATTRIB_RESOLUTION,//5
  9.     SNS_DDF_ATTRIB_LOWPASS,//6
  10.     SNS_DDF_ATTRIB_MOTION_DETECT,//7
  11.     SNS_DDF_ATTRIB_DRIVER_INFO,//8
  12.     SNS_DDF_ATTRIB_DEVICE_INFO,//9
  13.     SNS_DDF_ATTRIB_THRESHOLD,//10
  14.     SNS_DDF_ATTRIB_ACCURACY,//11
  15.     SNS_DDF_ATTRIB_BIAS,//12
  16.     SNS_DDF_ATTRIB_ODR,//13
  17.     SNS_DDF_ATTRIB_SUPPORTED_ODR_LIST,//14
  18.     SNS_DDF_ATTRIB_REGISTRY_GROUP,//15
  19.     SNS_DDF_ATTRIB_IO_REGISTER,//16
  20.     SNS_DDF_ATTRIB_FIFO,//17
  21.     SNS_DDF_ATTRIB_ODR_TOLERANCE,//18
  22.     SNS_DDF_ATTRIB_FILTER_DELAY//19
  23. } sns_ddf_attribute_e;  

初始化流程

1,probe

2,init

3,get_attr

SNS_DDF_ATTRIB_RESOLUTION_ADC

SNS_DDF_ATTRIB_LOWPASS,

SNS_DDF_ATTRIB_ODR,

SNS_DDF_ATTRIB_SUPPORTED_ODR_LIST,

SNS_DDF_ATTRIB_FIFO,

SNS_DDF_ATTRIB_DEVICE_INFO,

SNS_DDF_ATTRIB_POWER_INFO,

SNS_DDF_ATTRIB_RESOLUTION,

SNS_DDF_ATTRIB_RANGE,

4,reset

FIFO模式時按power鍵流程

1,reset

2,set_attr 設定SNS_DDF_ATTRIB_POWER_INFO屬性

SNS_DDF_ATTRIB_RANGE,

SNS_DDF_ATTRIB_ODR,

SNS_DDF_ATTRIB_FILTER_DELAY

SNS_DDF_ATTRIB_FIFO

FIFO模式資料上報流程

enable_sched_data

reset

handle_timer

interrupt_handler

handle_irq_attach_temp

interrupt_handler

handle_irq_attach_temp

...

 DRI模式資料上報流程

reset

set_attr

enable_sched_data

reset

handle_timer

interrupt_handler

handle_irq_drdy

handle_irq_attach_temp

interrupt_handler

handle_irq_drdy

handle_irq_attach_temp

...

 

 POLLING模式資料上報流程

1,reset

2,get_data

3,handle_timer

4,get_data

5,get_data

...

 

校準流程

最後看一下感測器的校準流程,因為器件一致性差異等原因,每臺機器的在出廠前都需要進行校準。實現校準的具體流程如下:


1,校準app想ssc(高通感測器控制器縮寫)發出校準請求

2,ssc呼叫感測器驅動中sns_ddf_driver_if_s結構體中指定的run_test函式

3,run_test 函式中由多種校準模式其中SNS_DDF_TEST_OEM模式會計算當前機器的資料bias,並存儲下來。

  1. /** 
  2.  * Factory tests. 
  3.  */
  4. typedefenum
  5. {  
  6.     SNS_DDF_TEST_SELF,         /**< Self test. */
  7.     SNS_DDF_TEST_IRQ,          /**< Interrupt test. */
  8.     SNS_DDF_TEST_CONNECTIVITY, /**< Basic connectivity test. */
  9.     SNS_DDF_TEST_SELF_HW,      /**< Hardware self test. */
  10.     SNS_DDF_TEST_SELF_SW,      /**< Software self test. */
  11.     SNS_DDF_TEST_OEM           /**< OEM test. */
  12. } sns_ddf_test_e;  
4,隨後ssc會呼叫get_attr獲取SNS_DDF_ATTRIB_BIAS屬性,拿到這次的校準值,最後將校準資料存放在/persist/sensor/sns.reg中

5,之後每次SSC初始化都會從sns.reg檔案中讀取到當前感測器的bias值

6,我們每次對校準後的感測器進行資料讀取get_data 時,獲取到的原始資料都會與這個bias值進行運算,從而返回給上層校準後的資料。