高通HAL層之Sensor HAL
高通的HAL層其實分為兩種,一種是直接從kernel這邊報資料上來的,由sensor HAL層來監聽,另一種是走ADSP的模式,HAL層是通過qmi的形式進行監聽的;
走ADSP架構的可以看下面的部落格:http://blog.csdn.net/u011006622/article/details/54598426
而msm8909架構下的便是以HAL層來監聽資料的;
簡介:
Google為Sensor提供了統一的HAL介面,不同的硬體廠商需要根據該介面來實現並完成具體的硬體抽象層,Android中Sensor的HAL介面定義在:hardware/libhardware/include/hardware/sensors.h:
為了瞭解HAL層的sensor,我們必須理解幾個結構體:分別是sensor_type,sensor_t,sensors_module_t;
從下面可以看到此檔案定義了sensor的type以及string type;
1 /* 2 * SENSOR_TYPE_ACCELEROMETER 3 * reporting-mode: continuous 4 * 5 * All values are in SI units (m/s^2) and measure the acceleration of the 6 * device minus the force of gravity. 7 * 8 * Implement the non-wake-up version of this sensor and implement the wake-up 9 * version if the system possesses a wake up fifo. 10 */ 11 #define SENSOR_TYPE_ACCELEROMETER (1) 12 #define SENSOR_STRING_TYPE_ACCELEROMETER "android.sensor.accelerometer"
sensors_module_t結構體:
該結構體實際上是對標準硬體模組hw_module_t的一個擴充套件,增加一個get_sensor_list函式,用於獲取感測器的列表,以及set_operation_mode設定為相關的mode;
1 /** 2 * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM 3 * and the fields of this data structure must begin with hw_module_t 4 * followed by module specific information. 5 */ 6 struct sensors_module_t { 7 struct hw_module_t common; 8 9 /** 10 * Enumerate all available sensors. The list is returned in "list". 11 * @return number of sensors in the list 12 */ 13 int (*get_sensors_list)(struct sensors_module_t* module, 14 struct sensor_t const** list); 15 16 /** 17 * Place the module in a specific mode. The following modes are defined 18 * 19 * 0 - Normal operation. Default state of the module. 20 * 1 - Loopback mode. Data is injected for the supported 21 * sensors by the sensor service in this mode. 22 * @return 0 on success 23 * -EINVAL if requested mode is not supported 24 * -EPERM if operation is not allowed 25 */ 26 int (*set_operation_mode)(unsigned int mode); 27 };
sensor_t結構體:
1 struct sensor_t {
2
3 /* Name of this sensor.
4 * All sensors of the same "type" must have a different "name".
5 */
6 const char* name; //感測器名字
7
8 /* vendor of the hardware part */
9 const char* vendor; //生產廠家名字
10
11 /* version of the hardware part + driver. The value of this field
12 * must increase when the driver is updated in a way that changes the
13 * output of this sensor. This is important for fused sensors when the
14 * fusion algorithm is updated.
15 */
16 int version;
17
18 /* handle that identifies this sensors. This handle is used to reference
19 * this sensor throughout the HAL API.
20 */
21 int handle; //感測器handle控制代碼
22
23 /* this sensor's type. */
24 int type; //感測器型別
25
26 /* maximum range of this sensor's value in SI units */
27 float maxRange; //最大範圍
28
29 /* smallest difference between two values reported by this sensor */
30 float resolution; //解析度
31
32 /* rough estimate of this sensor's power consumption in mA */
33 float power;
34
35 /* this value depends on the reporting mode:
36 *
37 * continuous: minimum sample period allowed in microseconds
38 * on-change : 0
39 * one-shot :-1
40 * special : 0, unless otherwise noted
41 */
42 int32_t minDelay;
43
44 /* number of events reserved for this sensor in the batch mode FIFO.
45 * If there is a dedicated FIFO for this sensor, then this is the
46 * size of this FIFO. If the FIFO is shared with other sensors,
47 * this is the size reserved for that sensor and it can be zero.
48 */
49 uint32_t fifoReservedEventCount;
50
51 /* maximum number of events of this sensor that could be batched.
52 * This is especially relevant when the FIFO is shared between
53 * several sensors; this value is then set to the size of that FIFO.
54 */
55 uint32_t fifoMaxEventCount;
56
57 /* type of this sensor as a string. Set to corresponding
58 * SENSOR_STRING_TYPE_*.
59 * When defining an OEM specific sensor or sensor manufacturer specific
60 * sensor, use your reserve domain name as a prefix.
61 * ex: com.google.glass.onheaddetector
62 * For sensors of known type, the android framework might overwrite this
63 * string automatically.
64 */
65 const char* stringType;
66
67 /* permission required to see this sensor, register to it and receive data.
68 * Set to "" if no permission is required. Some sensor types like the
69 * heart rate monitor have a mandatory require_permission.
70 * For sensors that always require a specific permission, like the heart
71 * rate monitor, the android framework might overwrite this string
72 * automatically.
73 */
74 const char* requiredPermission;
75
76 /* This value is defined only for continuous mode and on-change sensors. It is the delay between
77 * two sensor events corresponding to the lowest frequency that this sensor supports. When lower
78 * frequencies are requested through batch()/setDelay() the events will be generated at this
79 * frequency instead. It can be used by the framework or applications to estimate when the batch
80 * FIFO may be full.
81 *
82 * NOTE: 1) period_ns is in nanoseconds where as maxDelay/minDelay are in microseconds.
83 * continuous, on-change: maximum sampling period allowed in microseconds.
84 * one-shot, special : 0
85 * 2) maxDelay should always fit within a 32 bit signed integer. It is declared as 64 bit
86 * on 64 bit architectures only for binary compatibility reasons.
87 * Availability: SENSORS_DEVICE_API_VERSION_1_3
88 */
89 #ifdef __LP64__
90 int64_t maxDelay;
91 #else
92 int32_t maxDelay;
93 #endif
94
95 /* Flags for sensor. See SENSOR_FLAG_* above. Only the least significant 32 bits are used here.
96 * It is declared as 64 bit on 64 bit architectures only for binary compatibility reasons.
97 * Availability: SENSORS_DEVICE_API_VERSION_1_3
98 */
99 #ifdef __LP64__
100 uint64_t flags;
101 #else
102 uint32_t flags;
103 #endif
104
105 /* reserved fields, must be zero */
106 void* reserved[2];
107 };
高通HAL:
現在回到高通定製的sensor HAL層來:(程式碼位於hardwareqcomsensors:)
Sensor HAL:
首先sensor這個模組這個id的定義,主要實現了sensors_module_t結構:
1 struct sensors_module_t HAL_MODULE_INFO_SYM = {
2 common: {
3 tag: HARDWARE_MODULE_TAG,
4 version_major: 1,
5 version_minor: 0,
6 id: SENSORS_HARDWARE_MODULE_ID,
7 name: "Quic Sensor module",
8 author: "Quic",
9 methods: &sensors_module_methods,
10 dso: NULL,
11 reserved: {0},
12 },
13 get_sensors_list: sensors__get_sensors_list,
14 };
sensors__get_sensors_list函式返回這個平臺的所有sensor:
1 static int sensors__get_sensors_list(struct sensors_module_t*,
2 struct sensor_t const** list)
3 {
4 NativeSensorManager& sm(NativeSensorManager::getInstance());
5
6 return sm.getSensorList(list);
7 }
裡面使用了NativeSensorManager,sensors__get_sensors_list函式中呼叫單例模式建立了一個例項,然後再呼叫相應的成員函式獲取感測器列表,並返回,返回值對應的sensor_t結構體;
NativeSensorManager統一管理著所有的感測器、物理和虛擬感測器。它的軟體框架如下:
我們繼續看sensors_module_methods:
1 static struct hw_module_methods_t sensors_module_methods = {
2 open: open_sensors
3 };
1 /*****************************************************************************/
2
3 /** Open a new instance of a sensor device using name */
4 static int open_sensors(const struct hw_module_t* module, const char*,
5 struct hw_device_t** device)
6 {
7 int status = -EINVAL;
8 sensors_poll_context_t *dev = new sensors_poll_context_t();
9 NativeSensorManager& sm(NativeSensorManager::getInstance());
10
11 memset(&dev->device, 0, sizeof(sensors_poll_device_1_ext_t));
12
13 dev->device.common.tag = HARDWARE_DEVICE_TAG;
14 #if defined(SENSORS_DEVICE_API_VERSION_1_3)
15 ALOGI("Sensors device API version 1.3 supportedn");
16 dev->device.common.version = SENSORS_DEVICE_API_VERSION_1_3;
17 #else
18 dev->device.common.version = SENSORS_DEVICE_API_VERSION_0_1;
19 #endif
20 dev->device.common.module = const_cast<hw_module_t*>(module);
21 dev->device.common.close = poll__close;
22 dev->device.activate = poll__activate;
23 dev->device.setDelay = poll__setDelay;
24 dev->device.poll = poll__poll;
25 dev->device.calibrate = poll_calibrate;
26 #if defined(SENSORS_DEVICE_API_VERSION_1_3)
27 dev->device.batch = poll__batch;
28 dev->device.flush = poll__flush;
29 #endif
30
31 *device = &dev->device.common;
32 status = 0;
33
34 return status;
35 }
open_sensors用來開啟所有的sensor,並返回相應的狀態;首先new了一個sensors_poll_context_t ,然後設定device,並返回;
對應的new sensors_poll_context_t,我們來看一下其實現:
1 struct sensors_poll_context_t {
2 // extension for sensors_poll_device_1, must be first
3 struct sensors_poll_device_1_ext_t device;// must be first
4 sensors_poll_context_t();
5 ~sensors_poll_context_t();
6 int activate(int handle, int enabled);
7 int setDelay(int handle, int64_t ns);
8 int pollEvents(sensors_event_t* data, int count);
9 int calibrate(int handle, cal_cmd_t *para);
10 int batch(int handle, int sample_ns, int latency_ns);
11 int flush(int handle);
12
13 private:
14 static const size_t wake = MAX_SENSORS;
15 static const char WAKE_MESSAGE = 'W';
16 struct pollfd mPollFds[MAX_SENSORS+1];
17 int mWritePipeFd;
18 SensorBase* mSensors[MAX_SENSORS];
19 mutable Mutex mLock;
20 };
1 /*****************************************************************************/
2
3 sensors_poll_context_t::sensors_poll_context_t()
4 {
5 int number;
6 int i;
7 const struct sensor_t *slist;
8 const struct SensorContext *context;
9 NativeSensorManager& sm(NativeSensorManager::getInstance());
10 //獲取sensor列表
11 number = sm.getSensorList(&slist);
12
13 /* use the dynamic sensor list */
14 for (i = 0; i < number; i++) {
15 context = sm.getInfoByHandle(slist[i].handle);
16
17 mPollFds[i].fd = (context == NULL) ? -1 : context->data_fd;
18 mPollFds[i].events = POLLIN;
19 mPollFds[i].revents = 0;
20 }
21
22 ALOGI("The avaliable sensor handle number is %d",i);
23 int wakeFds[2];
24 int result = pipe(wakeFds);
25 ALOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno));
26 fcntl(wakeFds[0], F_SETFL, O_NONBLOCK);
27 fcntl(wakeFds[1], F_SETFL, O_NONBLOCK);
28 mWritePipeFd = wakeFds[1];
29
30 mPollFds[number].fd = wakeFds[0];
31 mPollFds[number].events = POLLIN;
32 mPollFds[number].revents = 0;
33 }
通過context = sm.getInfoByHandle(slist[i].handle); 維繫了一個handle對應的SensorContext物件指標的控制代碼;
(context是一個SensorContext結構體,SensorContext包含了一個SensorBase *driver指標;注意這個很重要!就是這個與具體的sensor產生相應的關聯;而mPollFds是一個pollfd的結構。context儲存著各個開啟的sensor,mPollFds用來監聽sensor的時候用的檔案描述符;)
然後繼續往下看,由上面程式碼可見:sensors_poll_device_t的activate、setDelay和poll的實現函式分別為:
(1) poll__activate
(2) poll__setDelay
(3) poll__poll
1 int sensors_poll_context_t::activate(int handle, int enabled) {
2 int err = -1;
3 NativeSensorManager& sm(NativeSensorManager::getInstance());
4 Mutex::Autolock _l(mLock);
5
6 err = sm.activate(handle, enabled);
7 if (enabled && !err) {
8 const char wakeMessage(WAKE_MESSAGE);
9 int result = write(mWritePipeFd, &wakeMessage, 1);
10 ALOGE_IF(result<0, "error sending wake message (%s)", strerror(errno));
11 }
12
13 return err;
14 }
1 int sensors_poll_context_t::setDelay(int handle, int64_t ns) {
2 int err = -1;
3 NativeSensorManager& sm(NativeSensorManager::getInstance());
4 Mutex::Autolock _l(mLock);
5
6 err = sm.setDelay(handle, ns);
7
8 return err;
9 }
1 int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count)
2 {
3 int nbEvents = 0;
4 int n = 0;
5 NativeSensorManager& sm(NativeSensorManager::getInstance());
6 const sensor_t *slist;
7 int number = sm.getSensorList(&slist);
8
9 do {
10 // see if we have some leftover from the last poll()
11 for (int i = 0 ; count && i < number ; i++) {
12 if ((mPollFds[i].revents & POLLIN) || (sm.hasPendingEvents(slist[i].handle))) {
13 Mutex::Autolock _l(mLock);
14 int nb = sm.readEvents(slist[i].handle, data, count);
15 if (nb < 0) {
16 ALOGE("readEvents failed.(%d)", errno);
17 return nb;
18 }
19 if (nb <= count) {
20 // no more data for this sensor
21 mPollFds[i].revents = 0;
22 }
23 count -= nb;
24 nbEvents += nb;
25 data += nb;
26 }
27 }
28
29 if (count) {
30 // we still have some room, so try to see if we can get
31 // some events immediately or just wait if we don't have
32 // anything to return
33 do {
34 n = poll(mPollFds, number + 1, nbEvents ? 0 : -1);
35 } while (n < 0 && errno == EINTR);
36 if (n<0) {
37 ALOGE("poll() failed (%s)", strerror(errno));
38 return -errno;
39 }
40 if (mPollFds[number].revents & POLLIN) {
41 char msg;
42 int result = read(mPollFds[number].fd, &msg, 1);
43 ALOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno));
44 ALOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg));
45 mPollFds[number].revents = 0;
46 }
47 }
48 // if we have events and space, go read them
49 } while (n && count);
50
51 return nbEvents;
52 }
1 static int poll__close(struct hw_device_t *dev)
2 {
3 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
4 if (ctx) {
5 delete ctx;
6 }
7 return 0;
8 }
1 static int poll__activate(struct sensors_poll_device_t *dev,
2 int handle, int enabled) {
3 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
4 return ctx->activate(handle, enabled);
5 }
1 static int poll__setDelay(struct sensors_poll_device_t *dev,
2 int handle, int64_t ns) {
3 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
4 return ctx->setDelay(handle, ns);
5 }
1 static int poll__poll(struct sensors_poll_device_t *dev,
2 sensors_event_t* data, int count) {
3 sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
4 return ctx->pollEvents(data, count);
5 }
以poll_poll為例,看看如何與具體的sensor建立連線的:
1 return ctx->pollEvents(data, count);
ctx->pollEvents函式又呼叫了NativeSensorManager::readEvents;
1 int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count)
2 {
3 int nbEvents = 0;
4 int n = 0;
5 NativeSensorManager& sm(NativeSensorManager::getInstance());
6 const sensor_t *slist;
7 int number = sm.getSensorList(&slist);
8
9 do {
10 // see if we have some leftover from the last poll()
11 for (int i = 0 ; count && i < number ; i++) {
12 if ((mPollFds[i].revents & POLLIN) || (sm.hasPendingEvents(slist[i].handle))) {
13 Mutex::Autolock _l(mLock);
14 int nb = sm.readEvents(slist[i].handle, data, count);
15 if (nb < 0) {
16 ALOGE("readEvents failed.(%d)", errno);
17 return nb;
18 }
19 if (nb <= count) {
20 // no more data for this sensor
21 mPollFds[i].revents = 0;
22 }
23 count -= nb;
24 nbEvents += nb;
25 data += nb;
26 }
27 }
28
29 if (count) {
30 // we still have some room, so try to see if we can get
31 // some events immediately or just wait if we don't have
32 // anything to return
33 do {
34 n = poll(mPollFds, number + 1, nbEvents ? 0 : -1);
35 } while (n < 0 && errno == EINTR);
36 if (n<0) {
37 ALOGE("poll() failed (%s)", strerror(errno));
38 return -errno;
39 }
40 if (mPollFds[number].revents & POLLIN) {
41 char msg;
42 int result = read(mPollFds[number].fd, &msg, 1);
43 ALOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno));
44 ALOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg));
45 mPollFds[number].revents = 0;
46 }
47 }
48 // if we have events and space, go read them
49 } while (n && count);
50
51 return nbEvents;
52 }
NativeSensorManager::readEvents中又呼叫了:
1 nb = list->driver->readEvents(data, count);
記得上面說過什麼?list->driver是一個SensorBase結構體,於是終於終於我們來到了SensorBase結構體的函式readEvents,接下來就是具體的sensor模組讀取的任務了!!
其主要框架如下圖所示:
下來繼續看具體sensor的處理過程:http://www.cnblogs.com/linhaostudy/p/8432741.html