bma250源碼
⑴ 有沒有人用過ST的LIS3DH這個感測器
深圳市德賽威科技有限公司經營ST,BOSCH感測器陀螺儀,LSM6DS3TR,LSM6DS33TR,LIS3DHTR,LIS2DH12,BMA223,BMA250EF.
⑵ android sensor怎樣注冊input
一, 驅動層
在驅動層,內核需要增加和修改的部分包括:
1,相應硬體模塊驅動代碼,包括兩個文件,這里是kionix_accel.h, kionix_accel.c,分別將kionix_accel.h放到kernel/common/customer/include/linux/中,將kionix_accel.c放到kernel/customer/drivers/misc/中;
2,編譯目錄(kernel/customer/drivers/misc/)下的Makefie 和KConfig,在KConfig中增加:
config SENSORS_KXTJ2
tristate "KXTJ2 accelerometer sensor driver"
depends on I2C
help
Say yes here to support Kionix's KXTJ2 accelerometer sensor
在MakeFile 下增加:obj-$(CONFIG_SENSORS_KXTJ2) += kionix_accel.o
3, 在平台編譯配置文件中(也就是make menuconfig生成的),增加:CONFIG_SENSORS_KXTJ2=y------->指定編譯到內核中,如果是m則編譯成ko;
4,在平台模塊代碼文件中(kernel/customer/boards/board-m6g17-t069.c),在相應的i2c配置中,增加此模塊:
static struct i2c_board_info __initdata aml_i2c_bus_info_b[] = {
........
#ifdef CONFIG_SENSORS_KXTJ2
{
I2C_BOARD_INFO("kionix_accel", KIONIX_ACCEL_I2C_ADDR),
//.irq = INT_GPIO_1,
.platform_data = (void *) &kionix_accel_pdata,
},
#endif
}
經過以上幾步操作以後,就可以將此模塊驅動編譯到內核中。
G-sensor driver工作的大致流程:系統開機後,內核會先載入i2c匯流排驅動,然後再載入設備驅動,在設備驅動中的init函數中通過調用i2c_add_driver(&kionix_accel_driver)注冊i2c_driver;此函數將driver注冊到i2c_bus_type的匯流排上,此匯流排的匹配規則是利用i2c_client的名稱和i2c_driver中id_table中的名稱作匹配。其中i2c_client是系統自動創建的,board-m6g17-t069.c文件中的結構變數static struct i2c_board_info __initdata aml_i2c_bus_info_b中需要添加G-sensor的設備信息。
當匹配成功時,i2c_driver中的probe()函數開始執行。
mole_init(kionix_accel_init)---->i2c_add_driver(&kionix_accel_driver)----->static struct i2c_driver kionix_accel_driver = {
.driver = {
.name = KIONIX_ACCEL_NAME,
.owner = THIS_MODULE,
},
.probe = kionix_accel_probe,
.remove = __devexit_p(kionix_accel_remove),
.id_table = kionix_accel_id,
};
Probe()函數kionix_accel_probe()主要完成以下功能:
1.從i2c_client結構中得到初始化信息
2.創建G-sensor的工作隊列
2.注冊input_device設備
3.讀取Chip ID
4.設置寄存器,使能G-sensor
5.設置並啟動中斷
當G-sensor上報數據的時候會觸發中斷,然後在中斷處理函數中提交一個報值的任務到隊列中並禁止中斷。
在工作隊列中讀數G-sensor的數據並上報到input子系統中,最後使能中斷。
系統啟動後,驅動會在/sys/class/input/inputX下生成相應的設備文件,裡面name節點包含有相應的模塊名;
shell@
capabilities
device
event4
id
modalias
name
phys
power
properties
subsystem
uevent
uniq
同時會在/dev/input/裡面也會生成inputX的節點,它是用來實際讀取數據的。
驅動在工作的時候,主要分兩部分:數據的採集及上報、設備的控制;
1,數據的採集主要是指通過I2C從硬體設備讀取相關的數據並把數據上報,讀取數據有兩種方式,一種是通過中斷,當有數據時,設備會發出中斷信號給驅動,驅動去採集,另一種就是採用定時器不斷的去定時採集數據;由於sensor也屬於輸入設備(還有TouchScreen,Keyboard,Mouse,Sensor等),所以上報的時候,也要報到linux kernel的輸入子系統裡面,上層通過相應的子系統設備節點讀取數據。
上報數據的過程:static void report_abs(void)
{
short x,y,z,tilt;
if(read_data(&x,&y,&z,&tilt) != 0) {
/* report the absulate sensor data to input device */
input_report_abs(idev, ABS_X, y);
input_report_abs(idev, ABS_Y, x);
input_report_abs(idev, ABS_Z, z);
input_sync(idev);
}
2,設備的控制包括打開、關閉、設置參數和使能等,一般上層會通過ioctl方式來交互
二, HAL層
android的HAL層,相當於它的應用層中的驅動,HAL與內核硬體驅動密切相關,由於硬體模塊的差別性,HAL代碼的編寫也各有差別,特別是關於sensor的HAL代碼基本上都要自己去實現,但基本架構是一樣的。
sensor的HAL結構基本分兩部分,一部分是控制操作,一部分是數據操作;
1,首先在android\hardware\libhardware\include\hardware目錄下,有sensors.h文件,定義了struct sensors_mole_t(sensor模塊對象結構,如get_list), struct sensor_t(具體sensor設備對象結構,如名字,類型), struct sensors_poll_device_t(每個設備操作數據結構,如激活、設置參數、poll等), typedef struct sensors_event_t(sensor的事件結構,如類型、數據), 同時也定義了所有感測器的類型:
/**
* Sensor types
*/
#define SENSOR_TYPE_ACCELEROMETER 1
#define SENSOR_TYPE_MAGNETIC_FIELD 2
#define SENSOR_TYPE_ORIENTATION 3
#define SENSOR_TYPE_GYROSCOPE 4
#define SENSOR_TYPE_LIGHT 5
#define SENSOR_TYPE_PRESSURE 6
#define SENSOR_TYPE_TEMPERATURE 7 // deprecated
#define SENSOR_TYPE_PROXIMITY 8
#define SENSOR_TYPE_GRAVITY 9
#define SENSOR_TYPE_LINEAR_ACCELERATION 10
#define SENSOR_TYPE_ROTATION_VECTOR 11
#define SENSOR_TYPE_RELATIVE_HUMIDITY 12
#define SENSOR_TYPE_AMBIENT_TEMPERATURE 13
在android/hardware/amlogic/sendsors/aml_gsensor目錄是特定平台實際HAL的代碼存放的位置,當然也有的平台只會給一個so的文件,不給源碼。
在sensor_aml.cpp中,首先要定義HAL_MODULE_INFO_SYM,這個是每個HAL模塊必須的,
struct sensors_mole_t HAL_MODULE_INFO_SYM = {
common: {
tag: HARDWARE_MODULE_TAG,
version_major: 1,
version_minor: 0,
id: SENSORS_HARDWARE_MODULE_ID,
name: "Sensors mole",
author: "Amlogic",
methods: &sensors_mole_methods,
},
get_sensors_list: sensors__get_sensors_list,
};
static int sensors__get_sensors_list(struct sensors_mole_t* mole,
struct sensor_t const** list)
{
*list = sSensorList;
return ARRAY_SIZE(sSensorList);
}
/* The SENSORS Mole */
static const struct sensor_t sSensorList[] = {
{ "BMA250 3-axis Accelerometer",
"Bosch",
1, SENSORS_ACCELERATION_HANDLE,
SENSOR_TYPE_ACCELEROMETER,
4.0f*9.81f,
(4.0f*9.81f)/1024.0f,
0.2f,
0,
{ }
},
#ifdef ENABLE_LIGHT_SENSOR
{ "Light sensor",
"(none)",
1, SENSORS_LIGHT_HANDLE,
SENSOR_TYPE_LIGHT, 5000.0f, 1.0f, 1.0f, 20000,{ } },
#endif
};
可以看出在事先定義當前支持的sensor模塊,android通過mole->get_sensors_list獲取。
獲取mole後,利用open_sensors();得到hw_device_t ==sensors_poll_device_t==sensors_poll_context_t->device mSensor結構對象,這個結構對象在初始化時會創建相應的sensor對象,且它們都是以SensorBase為基礎類,
sensors_poll_context_t::sensors_poll_context_t()
{
mSensors[aml_accel] = new GSensor();
mPollFds[aml_accel].fd = mSensors[aml_accel]->getFd();
mPollFds[aml_accel].events = POLLIN;
mPollFds[aml_accel].revents = 0;
#ifdef ENABLE_LIGHT_SENSOR
mSensors[aml_light] = new LightSensor();
mPollFds[aml_light].fd = mSensors[aml_light]->getFd();
mPollFds[aml_light].events = POLLIN;
mPollFds[aml_light].revents = 0;
#endif
}
通過mSensor對象就可以調用 activate、setDelay、poll進行激活讀取數據處理了。
mSensors[aml_accel] = new GSensor();
在創建GSensor對象時會對/sys/class/input/inputX目錄下的name讀取,通過對比名稱判斷當前sensor到底是在哪個目錄並記錄下path,在後面對設備進行設置,也就是控制部分會用到這個目錄下的結點;
同時由於GSensor 是繼承sensorBase的,所以在構造sendsorBase的時候會找到相應的/dev下的inputX設備open得到設備fd,用於後面讀取數據,也就是數據部分。
HAL層准備好後,最後會編譯成一個庫,這里為sensor.amlogic.so
三, Framework層
對於每一個模塊,framework層是最復雜的,它涉及到java部分和C++部分,且根據功能,又可分為service部分和manager部分,它們之間是通過binder進行通信的。
frameworks/base/libs/gui/ISensorServer.cpp
class ISensorServer : public IInterface
{
public:
DECLARE_META_INTERFACE(SensorServer);
virtual Vector<Sensor> getSensorList() = 0;
virtual sp<ISensorEventConnection> createSensorEventConnection() = 0;
};
在Android中,和Sensor相關的幾個類是:
SensorManager : 通過它實現系統對Sensor的相關調用。
SensorEvent :對各個Sensor數據的封裝,具體可以參考Android的開發文檔。
SensorEventListener :對Sensor數據的監視,一旦有數據,就會調相應的函數。
Sensor : 對Sensor的封裝。
對於service部分: 它是負責與HAL層建立聯系並處理實際數據的服務。
frameworks/base/services/sensorservice/sensorService.cpp , 它繼承了public BnSensorServer
系統啟動時會執行systemProcess,同時會載入sensorService.java進程,在sensorService.java的構造函數中調用JNI方法_sensor_control_init()。
sensorService.cpp中SensorService::onFirstRef()會被執行,會創建SensorDevice& dev(SensorDevice::getInstance())對象,通過SensorService::threadLoop()里就對各個sensor進行poll並將數據發送到對應的申請connection中connection->sendEvents(buffer, count, scratch);
SensorDevice是一個單一對象類,故SensorDevice::getInstance()會在同一進程中只保留一個對象,SensorDevice::SensorDevice()通過hardware.c中讀取HAL層生成的sensor.amlogic.so庫。
對於manager部分:它是負責給應用程序提供介面的,與sensorserivce通過binder進行交互數據與控制。
frameworks/base/core/java/android/hardware/SensorManager.java
frameworks/base/core/jni/android_hardware_SensorManager.cpp
frameworks/base/libs/gui/sensorManager.cpp
android_hardware_SensorManager.cpp:
static JNINativeMethod gMethods[] = {
{"nativeClassInit", "()V", (void*)nativeClassInit },
{"sensors_mole_init","()I", (void*)sensors_mole_init },
{"sensors_mole_get_next_sensor","(Landroid/hardware/Sensor;I)I", (void*)sensors_mole_get_next_sensor },
{"sensors_create_queue", "()I", (void*)sensors_create_queue },
{"sensors_destroy_queue", "(I)V", (void*)sensors_destroy_queue },
{"sensors_enable_sensor", "(ILjava/lang/String;II)Z", (void*)sensors_enable_sensor },
{"sensors_data_poll", "(I[F[I[J)I", (void*)sensors_data_poll },
};
sensors_mole_init()---->SensorManager::getInstance();由於SensorManager也是單一對象類,這里生成實體對象;
sensors_create_queue()----->SensorManager& mgr.createEventQueue():
sp<SensorEventQueue> SensorManager::createEventQueue()
{
sp<SensorEventQueue> queue;
Mutex::Autolock _l(mLock);
while (assertStateLocked() == NO_ERROR) {
sp<ISensorEventConnection> connection =
mSensorServer->createSensorEventConnection();
if (connection == NULL) {
// SensorService just died.
LOGE("createEventQueue: connection is NULL. SensorService died.");
continue;
}
queue = new SensorEventQueue(connection);
break;
}
return queue;
}
通過創建一個connection來建立queuece,其實就是利用connection中與sensorService建立的channel:
mSensorChannel = mSensorEventConnection->getSensorChannel();
通過循環獲取sensor list中的各個對象的屬性:
sensors_mole_get_next_sensor()------>sensorManager::getSensorList()----->SensorManager::assertStateLocked()---->mSensorServer->getSensorList()通過binder從sensorService獲取sensorlist;
使能某一sensor對象:
sensors_enable_sensor()---->queue->enableSensor(sensor, delay)---->mSensorEventConnection->setEventRate(handle, us2ns(us))-----> 通過ISensorEventConnection對象與sensorService:SensorEventConnection進行交互-------->SensorService::SensorEventConnection::enableDisable(int handle, bool enabled)---> SensorService::enable()---->mActiveConnections.add(connection)只是將connection加入到激活數組中,而並非直接使能或關閉硬體;
循環監聽事件:
sensorChannel用一對pipe來sensorService到sensorEventQueue的事件信息。
sensors_data_poll()------->queue->read(&event, 1)---->mSensorChannel->read()----->通過pipe<------ SensorChannel::write()<---------mChannel->write() <----------SensorService::SensorEventConnection::sendEvents() <-------activeConnections[i]->sendEvents(buffer, count, scratch)<---------SensorService::threadLoop()
四, 應用層