近来在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));
}
}
}
大功告成!!!