Android从Hal到framework层添加自定义Sensor

来源:互联网 发布:荼靡电视剧大结局知乎 编辑:程序博客网 时间:2024/05/22 08:06

近来在android源码中添加了一套sensor,做如下分享:

软件版本:Android4.4

硬件平台:MTK


之前写过有关Sensor的博文,大家有兴趣可以看一下,在此不在讲具体sensor的工作机制,只分享从hardware到framework如何添加一款系统原本不支持的sensor type。

驱动层面不再赘述,本文大体分为三个大部分,第一部分为Hal层改动;第二部分为framework层修改;第三部分为简单的app获取该sensor的数据。


第一部分:Hal层。

MTK平台hardware层代码在mediatek/hardware/sensor/目录,

首先是将第三方的sensor hal层cpp和头文件等放置该目录,并修改Android.mk,添加相关的cpp,如果有相关的.a库的依赖关系,则需要LOCAL_WHOLE_STATIC_LIBRARIES := libpah8002motion_s这样去指定依赖关系,后边的文件就是.a文件的名称。

其次,修改nusensors.cpp文件

diff --git a/mediatek/hardware/sensor/nusensors.cpp b/mediatek/hardware/sensor/nusensors.cpp
index c894616..ba2dd03 100644
--- a/mediatek/hardware/sensor/nusensors.cpp
+++ b/mediatek/hardware/sensor/nusensors.cpp
@@ -33,6 +33,7 @@
#include "Hwmsen.h"
#include "Acceleration.h"
#include "Magnetic.h"
+#include "PPGSensor.h"


/*****************************************************************************/
@@ -55,6 +56,7 @@ private:
//light,
//proximity,
//pressure,
+ heartrate,
numSensorDrivers,
numFds,
};
@@ -72,6 +74,8 @@ private:
//return light;
case ID_GYROSCOPE:
//return gyro;
+ case ID_HEART_RATE:
+ return heartrate;

case ID_PRESSURE:
break;
//return pressure;
@@ -95,6 +99,11 @@ sensors_poll_context_t::sensors_poll_context_t()
mPollFds[hwmsen].events = POLLIN;
mPollFds[hwmsen].revents = 0;

+ mSensors[heartrate] = new PPGSensor();
+ mPollFds[heartrate].fd = ((PPGSensor *)mSensors[heartrate])->mdata_fd;
+ mPollFds[heartrate].events = POLLIN;
+ mPollFds[heartrate].revents = 0;
+

开始添加heartrate类型sensor。

然后修改sensorList,

diff --git a/mediatek/hardware/sensor/hwmsen_chip_info.c b/mediatek/hardware/sensor/hwmsen_chip_info.c
index f997c76..1a25610 100644
--- a/mediatek/hardware/sensor/hwmsen_chip_info.c
+++ b/mediatek/hardware/sensor/hwmsen_chip_info.c
@@ -144,6 +144,23 @@
#endif
#endif

+#ifdef CUSTOM_KERNEL_HEART
+ #ifndef HEART_RATE
+ #define HEART_RATE "HEART_RATE"
+ #define HEART_RATE_VENDER "MTK"
+ #endif
+ #ifndef HEART_RATE_RANGE
+ #define HEART_RATE_RANGE 500.0f
+ #endif
+ #ifndef HEART_RATE_RESOLUTION
+ #define HEART_RATE_RESOLUTION 0.1f
+ #endif
+ #ifndef HEART_RATE_POWER
+ #define HEART_RATE_POWER 0.5f
+ #endif
+#endif
+
+

struct sensor_t sSensorList[MAX_NUM_SENSOR] =
@@ -256,5 +273,24 @@ struct sensor_t sSensorList[MAX_NUM_SENSOR] =
},
#endif

+#ifdef CUSTOM_KERNEL_HEART
+ {
+ .name = HEART_RATE,
+ .vendor = HEART_RATE_VENDER,
+ .version = 1,
+ .handle = ID_HEART_RATE,
+ .type = SENSOR_TYPE_HEART_RATE,
+ .maxRange = HEART_RATE_RANGE,//600.0f,
+ .resolution = HEART_RATE_RESOLUTION,//0.0016667f,
+ .power = HEART_RATE_POWER,//0.25f,
+ .minDelay = 0,
+ .fifoReservedEventCount = 0,
+ .fifoMaxEventCount = 0,
+ .reserved = {}
+ },
+#endif
+

};

修改sensor数目联合体,

diff --git a/mediatek/hardware/sensor/hwmsen_chip_info.h b/mediatek/hardware/sensor/hwmsen_chip_info.h
index e566955..5408969 100644
--- a/mediatek/hardware/sensor/hwmsen_chip_info.h
+++ b/mediatek/hardware/sensor/hwmsen_chip_info.h
@@ -46,7 +46,11 @@ typedef enum SENSOR_NUM_DEF
#ifdef CUSTOM_KERNEL_TEMPURATURE
TEMPURATURE_NUM,
#endif
-
+
+ #ifdef CUSTOM_KERNEL_HEARTRATE
+ HEARTRATE_NUM,
+ #endif
+

SENSORS_NUM

}SENSOR_NUM_DEF;


修改hardware/libhardware/include/hardware/sensors.h

添加类型宏值:

#define SENSOR_TYPE_HEART_RATE (21)

sensors_event_t添加float heartrate数据。

注意此类型宏值和framework层相关类型的移位数一致,即framework的该类型sensor移位

diff --git a/mediatek/kernel/include/linux/hwmsensor.h b/mediatek/kernel/include/linux/hwmsenso
r.h
index 55ae7d0..264218e 100755
--- a/mediatek/kernel/include/linux/hwmsensor.h
+++ b/mediatek/kernel/include/linux/hwmsensor.h
@@ -36,6 +36,7 @@
#define SENSOR_TYPE_GRAVITY 9
#define SENSOR_TYPE_LINEAR_ACCELERATION 10
#define SENSOR_TYPE_ROTATION_VECTOR 11
+#define SENSOR_TYPE_HEART_RATE 21


/*---------------------------------------------------------------------------*/
@@ -51,6 +52,8 @@
#define ID_LIGHT (ID_BASE+SENSOR_TYPE_LIGHT-1)
#define ID_PRESSURE (ID_BASE+SENSOR_TYPE_PRESSURE-1)
#define ID_TEMPRERATURE (ID_BASE+SENSOR_TYPE_TEMPERATURE-1)
+/* kongbo add */
+#define ID_HEART_RATE (ID_BASE+SENSOR_TYPE_HEART_RATE-1)

#define ID_SENSOR_MAX_HANDLE (ID_BASE+10)
#define ID_NONE (ID_BASE+16)

@@ -68,6 +71,8 @@
#define SENSOR_GRAVITY (1 << ID_GRAVITY)
#define SENSOR_LINEAR_ACCELERATION (1 << ID_LINEAR_ACCELERATION)
#define SENSOR_ROTATION_VECTOR (1 << ID_ROTATION_VECTOR)
+/* kongbo add */
+#define SENSOR_HEARTRATE (1 << ID_HEART_RATE)

/*----------------------------------------------------------------------------*/
#define HWM_INPUTDEV_NAME "hwmdata"
此处注意,ID_HEART_RATE即为上层SensorManager相关类型的位移值。


第二部分,framework层sensor的相关改动。

diff --git a/frameworks/base/api/current.txt b/frameworks/base/api/current.txt
index c9c697e..bd9be4c 100644
--- a/frameworks/base/api/current.txt
+++ b/frameworks/base/api/current.txt
@@ -10723,6 +10723,7 @@ package android.hardware {
method public java.lang.String getVendor();
method public int getVersion();
field public static final int TYPE_ACCELEROMETER = 1; // 0x1
+ field public static final int TYPE_HEARTRATE = 21;
field public static final int TYPE_ALL = -1; // 0xffffffff
field public static final int TYPE_AMBIENT_TEMPERATURE = 13; // 0xd
field public static final int TYPE_GAME_ROTATION_VECTOR = 15; // 0xf
@@ -10830,6 +10831,7 @@ package android.hardware {
field public static final deprecated int RAW_DATA_Z = 5; // 0x5
field public static final deprecated int SENSOR_ACCELEROMETER = 2; // 0x2
field public static final deprecated int SENSOR_ALL = 127; // 0x7f
+ field public static final deprecated int SENSOR_HEARTRATE =1048576;

field public static final int SENSOR_DELAY_FASTEST = 0; // 0x0
field public static final int SENSOR_DELAY_GAME = 1; // 0x1
field public static final int SENSOR_DELAY_NORMAL = 3; // 0x3
diff --git a/frameworks/base/core/java/android/hardware/LegacySensorManager.java b/frameworks/base/core/java/android/hardware/LegacySensorManager.java
index f959093..c55841c 100644
--- a/frameworks/base/core/java/android/hardware/LegacySensorManager.java
+++ b/frameworks/base/core/java/android/hardware/LegacySensorManager.java
@@ -74,6 +74,9 @@ final class LegacySensorManager {
case Sensor.TYPE_ACCELEROMETER:
result |= SensorManager.SENSOR_ACCELEROMETER;
break;
+ case Sensor.TYPE_HEARTRATE:
+ result |= SensorManager.SENSOR_HEARTRATE;
+ break;

case Sensor.TYPE_MAGNETIC_FIELD:
result |= SensorManager.SENSOR_MAGNETIC_FIELD;
break;
@@ -101,6 +104,8 @@ final class LegacySensorManager {
Sensor.TYPE_ORIENTATION, listener, sensors, rate) || result;
result = registerLegacyListener(SensorManager.SENSOR_TEMPERATURE,
Sensor.TYPE_TEMPERATURE, listener, sensors, rate) || result;
+ result = registerLegacyListener(SensorManager.SENSOR_HEARTRATE,
+ Sensor.TYPE_HEARTRATE, listener, sensors, rate) || result;
return result;
}

@@ -155,6 +160,8 @@ final class LegacySensorManager {
listener, sensors);
unregisterLegacyListener(SensorManager.SENSOR_TEMPERATURE, Sensor.TYPE_TEMPERATURE,
listener, sensors);
+ unregisterLegacyListener(SensorManager.SENSOR_HEARTRATE, Sensor.TYPE_HEARTRATE,
+ listener, sensors);

}

private void unregisterLegacyListener(int legacyType, int type,
diff --git a/frameworks/base/core/java/android/hardware/Sensor.java b/frameworks/base/core/java/android/hardware/Sensor.java
index 89a5819..931c1d6 100644
--- a/frameworks/base/core/java/android/hardware/Sensor.java
+++ b/frameworks/base/core/java/android/hardware/Sensor.java
@@ -222,6 +222,11 @@ public final class Sensor {
public static final int TYPE_GEOMAGNETIC_ROTATION_VECTOR = 20;

/**
+ * kongbo add for heartrate sensor
+ */
+ public static final int TYPE_HEARTRATE = 21;
+
+ /**

* A constant describing all sensor types.
*/
public static final int TYPE_ALL = -1;
diff --git a/frameworks/base/core/java/android/hardware/SensorManager.java b/frameworks/base/core/java/android/hardware/SensorManager.java
index b931313..28c34a2 100644
--- a/frameworks/base/core/java/android/hardware/SensorManager.java
+++ b/frameworks/base/core/java/android/hardware/SensorManager.java
@@ -163,6 +163,9 @@ public abstract class SensorManager {
@Deprecated
public static final int SENSOR_ORIENTATION_RAW = 1 << 7;

+ @Deprecated
+ public static final int SENSOR_HEARTRATE = 1 << 20; //此处移位数要与前文ha层定义的保持一致
+

/**
* A constant that includes all sensors
*
diff --git a/frameworks/native/include/android/sensor.h b/frameworks/native/include/android/sensor.h
index 129ea3e..5146946 100644
--- a/frameworks/native/include/android/sensor.h
+++ b/frameworks/native/include/android/sensor.h
@@ -59,7 +59,8 @@ enum {
ASENSOR_TYPE_MAGNETIC_FIELD = 2,
ASENSOR_TYPE_GYROSCOPE = 4,
ASENSOR_TYPE_LIGHT = 5,
+ ASENSOR_TYPE_HEART_RATE = 21    //此处也要跟hal层定义的类型值一致
};

/*
@@ -147,6 +148,7 @@ typedef struct ASensorEvent {
float distance;
float light;
float pressure;
+ float heartrate;
float relative_humidity;
AUncalibratedEvent uncalibrated_gyro;
AUncalibratedEvent uncalibrated_magnetic;
diff --git a/frameworks/native/include/gui/Sensor.h b/frameworks/native/include/gui/Sensor.h
index 0c81426..a704093 100644
--- a/frameworks/native/include/gui/Sensor.h
+++ b/frameworks/native/include/gui/Sensor.h
@@ -49,7 +49,8 @@ public:
TYPE_MAGNETIC_FIELD = ASENSOR_TYPE_MAGNETIC_FIELD,
TYPE_GYROSCOPE = ASENSOR_TYPE_GYROSCOPE,
TYPE_LIGHT = ASENSOR_TYPE_LIGHT,
+ TYPE_HEARTRATE = ASENSOR_TYPE_HEART_RATE
};

第三部分,application获取所添加类型sensor的数据。

package com.example.kaka.heartrate;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;import android.hardware.SensorManager;import android.widget.TextView;import android.widget.Button;import android.view.View;public class MainActivity extends Activity implements View.OnClickListener {    private SensorManager sm;    private Sensor heartSensor;    private TextView heartRate;  private Button back;    private final String TAG = "XINGSHI";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        heartRate = (TextView)findViewById(R.id.heartrate);    back = (Button)findViewById(R.id.back);        back.setOnClickListener(this);        sm = (SensorManager) getSystemService(SENSOR_SERVICE);        heartSensor = sm.getDefaultSensor(Sensor.TYPE_HEARTRATE);        //heartSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);        sm.registerListener(new MySensorListener(), heartSensor, SensorManager.SENSOR_DELAY_NORMAL);    }    @Override      public void onClick(View v) {          switch (v.getId()) {          case R.id.back:       this.finish();           break;          default:             break;          }      }    public class MySensorListener implements SensorEventListener {        public void onAccuracyChanged(Sensor sensor, int accuracy) {        }        public void onSensorChanged(SensorEvent event) {            float heart = event.values[0];            Log.e(TAG,"======= get heartrate data: " + String.valueOf(heart) + " =======");            heartRate.setText(String.valueOf(heart));        }    }}



大功告成!!!

























0 1