


版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Android2.3.4 陀螺仪移植(可以参考 )一 背景1.需求陀螺仪硬件并非接在android cpu 上,所以不存在陀螺仪驱动,而陀螺仪数据是通过用户空间的一个c 程序传过来。2.思路修改陀螺仪hal 层,在 hal 层构建 socket 客户端,在数据源的c 程序上构建socket 服务端。一旦有数据,c 程序通过socket发送数据到陀螺仪hal层,并上报。二步骤1.把 device/samsung/crespo/libsensors 目录拷贝到hardware/libhardware/modules 目录下2.修改 sensors.cpp 文件下的传感器数组定义。因只用到陀螺仪传感
2、器,把其他传感器定义删掉 cpp view plaincopystatic const struct sensor_t sSensorList = /* "KR3DM 3-axis Accelerometer","STMicroelectronics",1,SENSORS_ACCELERATION_HANDLE,SENSOR_TYPE_ACCELEROMETER, RANGE_A,CONVERT_A, 0.23f, 20000, , "AK8973 3-axisMagnetic field sensor","Asahi Ka
3、seiMicrodevices",1,SENSORS_MAGNETIC_FIELD_HANDLE,SENSOR_TYPE_MAGNETIC_FIELD, 2000.0f,CONVERT_M, 6.8f, 16667, , "AK8973 Orientation sensor", "Asahi Kasei Microdevices",1, SENSORS_ORIENTATION_HANDLE,16667, , "GP2A Light sensor","Sharp",1, SENSORS_LIGHT_HAND
4、LE,SENSOR_TYPE_LIGHT, 3000.0f, 1.0f, 0.75f, 0, , "GP2A Proximity sensor","Sharp",1, SENSORS_PROXIMITY_HANDLE,SENSOR_TYPE_PROXIMITY, 5.0f, 5.0f, 0.75f, 0, , */ "K3G Gyroscope sensor","STMicroelectronics",1, SENSORS_GYROSCOPE_HANDLE,SENSOR_TYPE_GYROSCOPE, RANGE_
5、GYRO,CONVERT_GYRO, 6.1f, 1190, ,;3.修改 sensors.cpp的 sensors_poll_context_t 结构体,删除其他的传感器定义 cppview plaincopystruct sensors_poll_context_t structsensors_poll_device_t device; / must be firstsensors_poll_context_t();sensors_poll_context_t();int activate(int handle, int enabled);int setDelay(inthandle, i
6、nt64_t ns);int pollEvents(sensors_event_t* data,int count);private:enum /light= 0,/proximity= 1,/akm= 2,/gyro= 3,gyro= 0,numSensorDrivers,numFds,;static const size_t wake = numFds -1; /wake = 1static const char WAKE_MESSAGE = 'W'struct pollfd mPollFdsnumFds;/2int mWritePipeFd;SensorBase* mSe
7、nsorsnumSensorDrivers;/ 2inthandleToDriver(int handle) const switch (handle)/*case ID_A:case ID_M:case ID_O:return akm;case ID_P:return proximity;case ID_L:return light;*/case ID_GY:return gyro;return-EINV AL; 包括构造函数: cpp viewplaincopysensors_poll_context_t:sensors_poll_context_t() /*mSensorslight =
8、 new LightSensor();mPollFdslight.fd = mSensorslight->getFd();mPollFdslight.events = POLLIN;mPollFdslight.revents = 0;mSensorsproximity = newProximitySensor();mPollFdsproximity.fd =mSensorsproximity->getFd();mPollFdsproximity.events = POLLIN;mPollFdsproximity.revents = 0;mSensorsakm = n
9、ewAkmSensor();mPollFdsakm.fd =mSensorsakm->getFd();mPollFdsakm.events =POLLIN;mPollFdsakm.revents = 0;*/LOGD("sensors_poll_context_t");mSensorsgyro =new GyroSensor();mPollFdsgyro.fd =mSensorsgyro->getFd();mPollFdsgyro.events =POLLIN;mPollFdsgyro.revents = 0;intwakeFds2;int re
10、sult = pipe(wakeFds);LOGE_IF(result<0, "error creating wake pipe (%s)",strerror(errno);fcntl(wakeFds0, F_SETFL,O_NONBLOCK);fcntl(wakeFds1, F_SETFL,O_NONBLOCK);mWritePipeFd = wakeFds1;/wake equals 1mPollFdswake.fd = wakeFds0;/storethe reading fd of the pipemPollFdswake.events =POLLIN
11、;mPollFdswake.revents = 0; 3.修改GyroSensor.cpp 的 getFd()函数,把原来的返回gyro 设备驱动的文件描述符,改为返回socket的文件描述符。cpp viewplaincopy int GyroSensor:getFd()if(mSocketFd =-1)socket_connect();returnmSocketFd; 其中 ,mSocketFd 是在 GyroSensor.h 中新定义的 socket 文件描述符, socket_connect()函数实现连接 socket服务端。我们回过头看sensors.cpp 文件的sensors_
12、poll_context_t 构造函数: cpp viewplaincopymSensorsgyro = new GyroSensor();mPollFdsgyro.fd = mSensorsgyro->getFd();mPollFdsgyro.events = POLLIN;mPollFdsgyro.revents = 0;这里初始化gyro类后,通过getFd()获取socket文件描述符,然后就可以通过poll函数对文件描述符进行读取数据,poll的读取在sensors_poll_context_t:pollEvents 函数中,代码都不用改变,像这样: cpp view
13、plaincopyintsensors_poll_context_t:pollEvents(sensors_event_t* data, intcount)/what does parameter count mean ? fuckint nbEvents = 0;int n = 0;/LOGD("sensors_poll_context_t:pollEvents");/LOGD("count=%d",count);do / see ifwe have some leftover from the last poll()for (inti=0 ; cou
14、nt && i<numSensorDrivers ; i+)SensorBase* const sensor(mSensorsi);if (mPollFdsi.revents & POLLIN) |(sensor->hasPendingEvents() int nb= sensor->readEvents(data, count);if(nb < count) / no more data forthis sensormPollFdsi.revents =0;count -= nb;nbEv
15、ents += nb;data +=nb;if (count)/ we still have some room, so try to see if wecan get/ some events immediately or just waitif we don't have/ anything to returnn = poll(mPollFds, numFds, nbEvents ? 0 : -1);if (n<0) LOGE("poll() failed (%s)",strerror(errno);return-errno;/read data
16、from pipeif (mPollFdswake.revents & POLLIN)char msg;int result= read(mPollFdswake.fd, &msg, 1);LOGE_IF(result<0, "error reading from wake pipe (%s)",strerror(errno);LOGE_IF(msg !=WAKE_MESSAGE, "unknown message on wake queue(0x%02x)", int(msg);mPollFdswake.r
17、events = 0;/ if we have events and space, go read them while (n&& count);return nbEvents;4.修改 gyro 类的构造函数, 把与设备驱动相关的那一段代码删除: cpp view plaincopyGyroSensor:GyroSensor():SensorBase(NULL, "gyro"),mEnabled(0),mInputReader(4),mHasPendingEvent(false),mEnabledTime(0),mSocketFd(-1)/
18、LOGD("GyroSensor:GyroSensor");mPendingEvent.version = sizeof(sensors_event_t);mPendingEvent.sensor = ID_GY;mPendingEvent.type =SENSOR_TYPE_GYROSCOPE;memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data);/*if (data_fd) strcpy(input_sysfs_path,"/sys/class/input/");strcat(input_s
19、ysfs_path,input_name);strcat(input_sysfs_path, "/device/");input_sysfs_path_len = strlen(input_sysfs_path);enable(0, 1);*/ 5.修改 gyro 类的其他成员函数,包括 setDelay,enable,setInitialState 等函数里面的代码去全部删除:cpp view plaincopyintGyroSensor:setInitialState() /*structinput_absinfo absinfo_x;struct input_absi
20、nfo absinfo_y;struct input_absinfo absinfo_z;float value;if(!ioctl(data_fd, EVIOCGABS(EVENT_TYPE_GYRO_X),&absinfo_x) && !ioctl(data_fd, EVIOCGABS(EVENT_TYPE_GYRO_X), &absinfo_y) && !ioctl(data_fd,EVIOCGABS(EVENT_TYPE_GYRO_X), &absinfo_z)value =
21、 absinfo_x.value;mPendingEvent.data0 = value * CONVERT_GYRO_X;value = absinfo_x.value;mPendingEvent.data1 =value * CONVERT_GYRO_Y;value =absinfo_x.value;mPendingEvent.data2 = value *CONVERT_GYRO_Z;mHasPendingEvent =true;*/LOGD("GyroSensor:setInitialState");return 0; cpp view plaincopyint G
22、yroSensor:enable(int32_t, int en)/*int flags = en ? 1 : 0;if (flags !=mEnabled) int fd;strcpy(&input_sysfs_pathinput_sysfs_path_len,"enable");fd = open(input_sysfs_path, O_RDWR);if (fd >=0) char buf2;int err;buf1 = 0;if (flags) buf0= '1'mEnabledTime = getTimestamp()
23、+IGNORE_EVENT_TIME; elsebuf0 = '0'err = write(fd, buf, sizeof(buf); close(fd); mEnabled = flags; setInitialState(); return 0; return -1; */ /LOGD("GyroSensor:enable"); return 0; cppview plaincopyint GyroSensor:setDelay(int32_t handle, int64_tdelay_ns)/*int fd;strcpy(&input_
24、sysfs_pathinput_sysfs_path_len,"poll_delay");fd = open(input_sysfs_path, O_RDWR);if (fd >= 0) char buf80;sprintf(buf,"%lld", delay_ns);write(fd, buf, strlen(buf)+1);close(fd);return 0;return -1; */LOGD("GyroSensor:setDelay");return 0;6.修改 gyro 类的 readEvents 函数,这个
25、函数是最重要的函数,要从 socket 中读取 gyro 数据: cpp view plaincopyfloat value= 0;char buf2;int nread = 0;nread =read(mSocketFd, buf, 2);if(nread <=0)LOGE("GyroSensor:readEvents read error.");return 0;float value = (float)(buf0<< 8) + buf1);/LOGD("gyro_msg_handle,value=%f",v
26、alue);value *= CONVERT_GYRO_X;mPendingEvent.data0 = value;mPendingEvent.data1= value;mPendingEvent.data2 = value;*data= *mPendingEvent;return 1;sokcet服务端每次发送 2 个字节数据,因是单轴陀螺仪,所以只有1 个数据,把mPendingEvent 的 data 数据 3 个字节都填充同一数据,然后赋值给 *data,最后返回 1,表述读到 1 个数据。7.修改 libsensors 下的 Android.mk 文件的: cpp viewplain
27、copyLOCAL_MODULE := sensors.default8.编译后, 生成 sensors.default.so 文件到 lib/hw 目录,把 hw 目录下其他有sensors文字的 so 文件删除, 只留 sensors.default.so 文件,然后就可以在模拟器或设备上进行测试了,App层的Java 测试程序如下: java view plaincopypackagecom.hase.ng102.sensors;import android.R.string;importandroid.app.Activity;import android.content.Contex
28、t;import android.hardware.Sensor;importandroid.hardware.SensorEvent;importandroid.hardware.SensorEventListener;importandroid.hardware.SensorManager;import android.os.Bundle;import android.util.Log; import android.widget.TextView; public class SensorDemoActivity extends Activity /设置 LOG 标签private sta
29、tic final String TAG = "sensors"privateSensorManager sm;private TextView tv1;/* Called when the activity is first created. */Overridepublic void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); tv1 = (TextView)this.findViewById(R.id.tv1
30、); sm =(SensorManager)getSystemService(Context.SENSOR_SERVICE); Log.d(String.format("getSystemService %s", sm = null ? "sucess":"fail"), TAG); int sensorType = Sensor.TYPE_GYROSCOPE;sm.registerListener(myAccelerometerListener,sm.getDefaultSen sor(sensorType),SensorManager.
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 建筑工程价格调整合同条款1-@-1
- 卫生间吊顶木龙骨施工方案
- 网架拆除施工方案
- 石墙施工方案
- DB3709T 037-2025泰山茶 茶叶鲜叶采摘分级技术规范
- 博罗县钢板支护桩施工方案
- 海岛燕屋年产2500吨高端滋补预制菜加工项目环境影响报告表环评报告表
- 配线架施工施工方案
- 水泥板拉木纹板施工方案
- 2025北京大兴高一(上)期末生物(教师版)
- 管道支架安装规范要求及安装间距
- 16G362 钢筋混凝土结构预埋件
- 对外汉语量词
- 朗诵朗读技巧大全ppt
- C语言PPT课件完整版
- 广东省中考物理近四年考点分布
- 中国故事英文版年英文二篇
- 2023年苏州工业职业技术学院高职单招(数学)试题库含答案解析
- 第5章液压传动控制元件02-换向阀
- 乙酸含量>80%安全技术说明书MSDS
- GB 25936.1-2012橡胶塑料粉碎机械第1部分:刀片式破碎机安全要求
评论
0/150
提交评论