android sensors
前段时间在调试Android的时候,涉及到sensors的移植,在Android中 Sensors子系统架构如下:其中Sensor HAL以上都已由android实现的,在具体Android Sensors移植中,需要用户实现的sensor Hal及以下,下面我们来分析一下sensors HAL的具体实现 Sensors的硬件抽像层中,有几个关键的结构体需要用户处理,它的定义位于libhardware/include/hardware/sensors.h文件中,sensors_module_t结构体用来定义sensor模块,sensor_t结构体用来定义一个sensors设备,sensors_event_t用来定义sensor数据,sensors_poll_device_t用来定义sensor的控制 |
sensors.c主要实现sensors_module_t和sensor_t结构体,定义了sensors模块的主要功能 |
#include #include #include #include #include #include #include #include #include #include #include #include "SensorsControl.h" #ifdef LOG_TAG #undef LOG_TAG #endif #define LOG_TAG "yamaha_sensors" #define YLOGD(...) LOGD(__VA_ARGS__) #define YLOGI(...) LOGI(__VA_ARGS__) #define YLOGE(...) LOGE(__VA_ARGS__) #define YLOGW(...) LOGW(__VA_ARGS__) //-------------------------------------------------------------------------------------------------------- #define POLLTIMEOUT (-1) #define MAX_DEVICE_NAME (32) #define MAX_CLASS_PATH (256) //-------------------------------------------------------------------------------------------------------- static const struct sensor_t sSupportedSensors[NUM_SENSORS] = { #if defined(SENSOR_SUPPORT_ACCELEROMETER) { .name = "BMA150 3-axis Accelerometer", .vendor = "Bosh", .version = 120, .handle = ID_ACCELEROMETER, .type = SENSOR_TYPE_ACCELEROMETER, .maxRange = 4.0f * 9.81f, .resolution = (4.0f * 9.81f)/256.0f, .power = 2.0f, .reserved = {0}, }, #endif #if defined(SENSOR_SUPPORT_MAGNETIC_FIELD) { .name = "MS-3C Magnetic Sensor", .vendor = "Yamaha Corporation", .version = 120, .handle = ID_MAGNETIC_FIELD, .type = SENSOR_TYPE_MAGNETIC_FIELD, .maxRange = 2000.0f, .resolution = 1.0f/16.0f, .power = 4.0f, /* typ 4mA (Normal), typ 1uA (Standby) */ .reserved = {0}, }, #endif #if defined(SENSOR_SUPPORT_ORIENTATION) { .name = "MS-3C Orientation Sensor", .vendor = "Yamaha Corporation", .version = 120, .handle = ID_ORIENTATION, .type = SENSOR_TYPE_ORIENTATION, .maxRange = 360.0f, .resolution = 1.0f, .power = 1.0f, .reserved = {0}, }, #endif }; //-------------------------------------------------------------------------------------------------------- static int sensors_list(struct sensors_module_t *module, struct sensor_t const**sensor) { *sensor = sSupportedSensors; return NUM_SENSORS; } //-------------------------------------------------------------------------------------------------------- static int open_sensors(const struct hw_module_t* module, const char* name,struct hw_device_t** device) { YLOGD("open_sensors"); return init_sensors_control(module, device); } //-------------------------------------------------------------------------------------------------------- static struct hw_module_methods_t sensors_module_methods = { .open = open_sensors, }; //-------------------------------------------------------------------------------------------------------- const struct sensors_module_t HAL_MODULE_INFO_SYM = { .common = { .tag = HARDWARE_MODULE_TAG, .version_major = 1, .version_minor = 2, .id = SENSORS_HARDWARE_MODULE_ID, .name = "Yamaha Sensors module", .author = "Yamaha Corporation", .methods = &sensors_module_methods, }, .get_sensors_list = sensors_list, }; |
SensorBace.cpp:为各sensors实现的基类,openDataFd会返回sensors EVENT设备文件的句柄 |
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //-------------------------------------------------------------------------------------------------------- #include "SensorBase.h" //-------------------------------------------------------------------------------------------------------- #ifdef LOG_TAG #undef LOG_TAG #endif #define LOG_TAG "SensorBase" #define YLOGD(...) LOGD(__VA_ARGS__) #define YLOGI(...) LOGI(__VA_ARGS__) #define YLOGE(...) LOGE(__VA_ARGS__) #define YLOGW(...) LOGW(__VA_ARGS__) //-------------------------------------------------------------------------------------------------------- SensorBase::SensorBase(const char* name) : name(name), data_fd(-1),mHasPendingEvent(false), mEnabled(0) { data_fd = openDataFd(name); if (getInputClasspath(name) < 0) YLOGE("getInputClasspath failed [%s]\n", name); if (data_fd >= 0) close(data_fd); int SensorBase::getFd() const { int SensorBase::setDelay(int32_t handle, int64_t ns) { int msDelay = (int)(ns / 1000000LL); // convert to ms if (setInputAttr("delay", msDelay) < 0) { YLOGE("setInputAttr failed -> delay : [%s]\n", name); err = -1; int SensorBase::enable(int32_t handle, int enabled) { YLOGD("SensorBase::enable : [Name : %s, Handle : %d, enabled : %d]\n",name, handle, enabled); // class path -> set enable, set wake if (setInputAttr("enable", enabled) < 0) { YLOGE("setInputAttr failed -> enable : [%s]\n", name); err = -1; if (setInputAttr("wake", enabled) < 0) { YLOGE("setInputAttr failed -> wake : [%s]\n", name); err = -1; mEnabled = enabled; mHasPendingEvent = true; int SensorBase::getInitialValues(sensors_vec_t* sensor, float divf) { char buf[sizeof("-2147483647") * 3 + 1]; /* including spaces, LF and '\0' */ if (getInputAttr("data", buf, sizeof(buf)) < 0) { for (i = 0; i < 3; i++) sensor->v[i] = 0; if (i == 0) p = strtok(buf, space); if (p == NULL) sensor->v[i] = 0; else sensor->v[i] = atoi(p) / divf; YLOGD("initial value[%s] [%.3f]\n", name, sensor->v[i]); int SensorBase::getInitialStatus(sensors_vec_t* sensor) { if (getInputAttr("status", &status) < 0) sensor->status = 0; else sensor->status =(int8_t)status; YLOGD("SensorBase::getInitialStatus : [Name : %s, status : %d]\n", name,status); bool SensorBase::hasPendingEvents() const { int64_t SensorBase::getTimestamp() { clock_gettime(CLOCK_MONOTONIC, &t); return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec; int SensorBase::getInputClasspath(const char *inputName) { const char *dirname = "/sys/class/input"; int fd = -1, nread, found = 0; if (name == NULL || classpath == NULL) return -EINVAL; if((dir = opendir(dirname)) == NULL) return -errno; if (strncmp(de->d_name, "input", strlen("input")) != 0) continue; memset(classpath, 0x00, sizeof(classpath)); snprintf(classpath, PATH_MAX, "%s/%s/", dirname, de->d_name); snprintf(buf, sizeof(buf), "%s/name", classpath); if((fd = open(buf, O_RDONLY)) < 0) continue; if ((nread = read(fd, buf, sizeof(buf))) < 0) { if (strcmp(buf, inputName) == 0) { close(fd); closedir(dir); return 0; // Classpath found!! closedir(dir); *classpath = '\0'; return -EINVAL; // Classpath not found int SensorBase::getInputAttr(const char *attr, char *value, int len) { memset(fname, 0x00, sizeof(fname)); snprintf(fname, sizeof(fname), "%s/%s", classpath, attr); fname[sizeof(fname) - 1] = '\0'; if((fd = open(fname, O_RDONLY)) < 0) return -errno; if ((nread = read(fd, value, len)) < 0) { int SensorBase::getInputAttr(const char *attr, int *value) { char buf[sizeof("-2147483647")]; if (value == NULL) return -EINVAL; if ((rt = getInputAttr(attr, buf, sizeof(buf))) < 0) return rt; int SensorBase::setInputAttr(const char *attr, char *value, int len) { memset(fname, 0x00, sizeof(fname)); snprintf(fname, sizeof(fname), "%s/%s", classpath, attr); fname[sizeof(fname) - 1] = '\0'; if((fd = open(fname, O_WRONLY)) < 0) return -errno; if (write(fd, value, len) < 0) { int SensorBase::setInputAttr(const char *attr, int value) { char buf[sizeof("-2147483647")]; memset(buf, 0x00, sizeof(buf)); return setInputAttr(attr, buf, sizeof(buf)); int SensorBase::openDataFd(const char *inputName) { const char *dirname = "/dev/input"; char *filename, devname[PATH_MAX]; if((dir = opendir(dirname)) == NULL) return -1; memset(devname, 0x00, sizeof(devname)); strcpy(devname, dirname); filename = devname + strlen(devname); *filename++ = '/'; if((fd = open(devname, O_RDONLY)) >= 0) { if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) name[0]= '\0'; if (!strcmp(name, inputName)) break; LOGE_IF(fd < 0, "couldn't find '%s' input device", inputName); |
InputEventReader.cpp文件的主要功能会读取sensors的输入事件 |
#include #include #include #include #include #include #include #include #include "InputEventReader.h" /*****************************************************************************/ struct input_event; InputEventCircularReader::InputEventCircularReader(size_t numEvents) : mBuffer(new input_event[numEvents * 2]), mBufferEnd(mBuffer + numEvents), mHead(mBuffer), mCurr(mBuffer), mFreeSpace(numEvents) { } InputEventCircularReader::~InputEventCircularReader() { delete [] mBuffer; } ssize_t InputEventCircularReader::fill(int fd) { size_t numEventsRead = 0; if (mFreeSpace) { const ssize_t nread = read(fd, mHead, mFreeSpace * sizeof(input_event)); if (nread<0 || nread % sizeof(input_event)) { // we got a partial event!! return nread<0 ? -errno : -EINVAL; } numEventsRead = nread / sizeof(input_event); if (numEventsRead) { mHead += numEventsRead; mFreeSpace -= numEventsRead; if (mHead > mBufferEnd) { size_t s = mHead - mBufferEnd; memcpy(mBuffer, mBufferEnd, s * sizeof(input_event)); mHead = mBuffer + s; } } } return numEventsRead; } ssize_t InputEventCircularReader::readEvent(input_event const** events) { *events = mCurr; ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace; return available ? 1 : 0; } void InputEventCircularReader::next() { mCurr++; mFreeSpace++; if (mCurr >= mBufferEnd) { mCurr = mBuffer; } } |
SensorsControl.cpp文件为sensors的控制文件,实现sensors_poll_device_t结构体,在init_sensors_control函数中写义了sensors_poll_context_t类的对像,在sensors_poll_context_t类的构造函数中, 定义了具体sensors类的对像,init_sensors_control函数是在sensors模块被打开时调用的 |
//------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include #include //------------------------------------------------------------------- #include "SensorsControl.h" #include "AccelerometerSensor.h" #include "GeomagneticSensor.h" #include "OrientationSensor.h" //------------------------------------------------------------------- #ifdef LOG_TAG #undef LOG_TAG #endif #define LOG_TAG "SensorsControl" #define YLOGD(...) //#define YLOGD(...) LOGD(__VA_ARGS__) #define YLOGI(...) LOGI(__VA_ARGS__) #define YLOGE(...) LOGE(__VA_ARGS__) #define YLOGW(...) LOGW(__VA_ARGS__) //------------------------------------------------------------------- struct sensors_poll_context_t { struct sensors_poll_device_t device; // must be first sensors_poll_context_t (); ~sensors_poll_context_t (); int activate (int handle, int enabled); int setDelay (int handle, int64_t ns); int pollEvents (sensors_event_t* data, int count); private: enum { Accelerometer = 0, Geomagnetic = 1, Orientation = 2, numSensorDrivers, numFds, }; static const size_t wake = numFds - 1; static const char WAKE_MESSAGE = 'W'; struct pollfd mPollFds[numFds]; int mWritePipeFd; SensorBase* mSensors[numSensorDrivers]; int handleToDriver(int handle) const { if(handle < numSensorDrivers) return handle; return -EINVAL; } }; //------------------------------------------------------------------- sensors_poll_context_t::sensors_poll_context_t() { mSensors[Accelerometer] = new AccelerometerSensor(); mPollFds[Accelerometer].fd = mSensors[Accelerometer]->getFd(); mPollFds[Accelerometer].events = POLLIN; mPollFds[Accelerometer].revents = 0; mSensors[Geomagnetic] = new GeomagneticSensor(); mPollFds[Geomagnetic].fd = mSensors[Geomagnetic]->getFd(); mPollFds[Geomagnetic].events = POLLIN; mPollFds[Geomagnetic].revents = 0; mSensors[Orientation] = new OrientationSensor(); mPollFds[Orientation].fd = mSensors[Orientation]->getFd(); mPollFds[Orientation].events = POLLIN; mPollFds[Orientation].revents = 0; int wakeFds[2]; int result = pipe(wakeFds); LOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno)); fcntl(wakeFds[0], F_SETFL, O_NONBLOCK); fcntl(wakeFds[1], F_SETFL, O_NONBLOCK); mWritePipeFd = wakeFds[1]; mPollFds[wake].fd = wakeFds[0]; mPollFds[wake].events = POLLIN; mPollFds[wake].revents = 0; } //-------------------------------------------------------------------------------------------------------- sensors_poll_context_t::~sensors_poll_context_t() { for (int i=0 ; i<numSensorDrivers ; i++) { delete mSensors[i]; } close(mPollFds[wake].fd); close(mWritePipeFd); } //-------------------------------------------------------------------------------------------------------- int sensors_poll_context_t::activate(int handle, int enabled) { YLOGD("sensors_poll_context_t::activate : [Handle : %d, enabled : %d]\n",handle, enabled); int index = handleToDriver(handle); if (index < 0) return index; int err = mSensors[index]->enable(handle, enabled); if (enabled && !err) { const char wakeMessage(WAKE_MESSAGE); int result = write(mWritePipeFd, &wakeMessage, 1); LOGE_IF(result<0, "error sending wake message (%s)", strerror(errno)); } return err; } //------------------------------------------------------------------- int sensors_poll_context_t::setDelay(int handle, int64_t ns) { int index = handleToDriver(handle); if (index < 0) return index; return mSensors[index]->setDelay(handle, ns); } //------------------------------------------------------------------- int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count) { int nbEvents = 0; int n = 0; YLOGD("IN ----> sensors_poll_context_t::pollEvents : [count : %d]\n",count); do { // see if we have some leftover from the last poll() for (int i=0 ; count && i<numSensorDrivers ; i++) { SensorBase* const sensor(mSensors[i]); if ((mPollFds[i].revents & POLLIN) || (sensor->hasPendingEvents())){ int nb = sensor->readEvents(data, count); if (nb < count) { // no more data for this sensor mPollFds[i].revents = 0; } count -= nb; nbEvents += nb; data += nb; } } if (count) { YLOGD("sensors_poll_context_t :: %d\n", count); // we still have some room, so try to see if we can get // some events immediately or just wait if we don't have // anything to return n = poll(mPollFds, numFds, nbEvents ? 0 : -1); if (n<0) { LOGE("poll() failed (%s)", strerror(errno)); return -errno; } if (mPollFds[wake].revents & POLLIN) { char msg; int result = read(mPollFds[wake].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)); mPollFds[wake].revents = 0; } } // if we have events and space, go read them } while (n && count); YLOGD("OUT ----> sensors_poll_context_t::pollEvents : [count : %d, nbEvents]\n", count, nbEvents); return nbEvents; } //------------------------------------------------------------------- static int poll__close(struct hw_device_t *dev) { sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; if (ctx) { delete ctx; } return 0; } //------------------------------------------------------------------- static int poll__activate(struct sensors_poll_device_t *dev, int handle, int enabled) { sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; return ctx->activate(handle, enabled); } //------------------------------------------------------------------- static int poll__setDelay(struct sensors_poll_device_t *dev, int handle, int64_t ns) { sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; return ctx->setDelay(handle, ns); } //------------------------------------------------------------------- static int poll__poll(struct sensors_poll_device_t *dev, sensors_event_t* data, int count) { sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; return ctx->pollEvents(data, count); } //------------------------------------------------------------------- int init_sensors_control(hw_module_t const* module, hw_device_t** device) { int status = -EINVAL; sensors_poll_context_t *dev = new sensors_poll_context_t(); memset(&dev->device, 0, sizeof(sensors_poll_device_t)); dev->device.common.tag = HARDWARE_DEVICE_TAG; dev->device.common.version = 0; dev->device.common.module = const_cast<hw_module_t*>(module); dev->device.common.close = poll__close; dev->device.activate = poll__activate; dev->device.setDelay = poll__setDelay; dev->device.poll = poll__poll; *device = &dev->device.common; status = 0; return status; } |
AccelerometerSensor.cpp文件为具体重力加速度传感器的实现 |
//-------------------------------------------------------------------#include #include #include #include #include #include #include #include //------------------------------------------------------------------- #include "AccelerometerSensor.h" //------------------------------------------------------------------- #ifdef LOG_TAG #undef LOG_TAG #endif #define LOG_TAG "AccelerometerSensor" #define YLOGD(...) LOGD(__VA_ARGS__) #define YLOGI(...) LOGI(__VA_ARGS__) #define YLOGE(...) LOGE(__VA_ARGS__) #define YLOGW(...) LOGW(__VA_ARGS__) //------------------------------------------------------------------- AccelerometerSensor::AccelerometerSensor() : SensorBase(INPUT_CLASSNAME_ACCELEROMETER), mfdiv(1000000), mInputReader(4) { memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); mPendingEvent.version = sizeof(sensors_event_t); mPendingEvent.sensor = ID_ACCELEROMETER; mPendingEvent.type = SENSOR_TYPE_ACCELEROMETER; // Initialize AccelerometerSensor getInitialStatus(&mPendingEvent.acceleration); getInitialValues(&mPendingEvent.acceleration, mfdiv); } //------------------------------------------------------------------- AccelerometerSensor::~AccelerometerSensor() { } //-------------------------------------------------------------------intAccelerometerSensor::readEvents(sensors_event_t* data, int count) { if (count < 1) return -EINVAL; if (mHasPendingEvent) { mHasPendingEvent = false; mPendingEvent.timestamp = getTimestamp(); *data = mPendingEvent; return mEnabled ? 1 : 0; } ssize_t n = mInputReader.fill(data_fd); if (n < 0) return n; int numEventReceived = 0, breaked = 0; input_event const* event; while (count && mInputReader.readEvent(&event)) { switch(event->type) { case EV_ABS: switch(event->code) { case ABS_X: mPendingEvent.acceleration.x = event->value / mfdiv; break; case ABS_Y: mPendingEvent.acceleration.y = event->value / mfdiv; break; case ABS_Z: mPendingEvent.acceleration.z = event->value / mfdiv; break; case ABS_STATUS: mPendingEvent.acceleration.status =event->value; break; case ABS_WAKE: breaked =1; break; default : break; } break; case EV_SYN: mPendingEvent.timestamp = timevalToNano(event->time); if (mEnabled) { *data++ = mPendingEvent; count--; numEventReceived++; } break; default : YLOGE("unknown event (type=%d, code=%d)", event->type, event->code); break; } mInputReader.next(); } if(breaked) { YLOGE("ABS_WAKE event (type=%d, code=%d) : break!!", event->type,event->code); return 0; } return numEventReceived; } |
android sensors相关推荐
- Android Sensors (2) 传感器API的使用
识别传感器和传感器能力 Android sensor framework提供了一些方法,使得你在运行时可以方便地查看设备上都有哪些传感器. API也提供了一些让你获取每个传感器性能的方法. 首先,你需 ...
- android 移植 距离感应,Android sensors移植文档
1 硬件工作原理 1.1 G-sensor主要管脚定义 上图是LIS3DHTR在TD_100中的原理图 l 电压:VDD:sensor的供电电源. VDD_IO:sensor的IO电源. l 中断: ...
- Android Sensors (3) 传感器坐标系统
传感器坐标系统 通常,sensor framework使用一个标准的三轴坐标系统来表达数值. 对于大多数传感器来说,坐标系统是相对于设备屏幕来说的. 当一个设备被放在其默认的方向上时,X轴是水平指向右 ...
- Android: android sensors, HAL范例
从源码找到的一个例子,写的很优雅,不知道HAL怎么写的同学可以好好学习一下: view plaincopy to clipboardprint? /* * Copyright (C) 2008 The ...
- android sensors 总结(一)
Agenda: 1 sensor 介绍 2 sensor架构 3 sensor driver 4 sensor hal 5 sensor校准 1 sensor 介绍 Sensors是将环境中物理指标经 ...
- 关于Android 传感器坐标与读数的进一步讨论
关于Android 传感器坐标与读数的进一步讨论 之前一些相关的讨论见: Android Sensors (3) 传感器坐标系统 Android Sensors (5) 运动传感器 Motion Se ...
- android传感器_Android传感器
android传感器 In this tutorial, we'll be digging deep into the world of Android Sensors. Our smartphone ...
- Android Sendor框架介绍
1 Sensors介绍 1.1 Android Sensors 简介 每一部搭载Android智能操作系统的设备都具有一系列传感器,用于测量运动,方向,和各种环境条件.如果你想要监测装 ...
- Android自动接听和挂断电话实现原理
转自:http://bbs.51cto.com/thread-1078059-1.html 一 前言 这两天要研究类似白名单黑名单以及手势自动接听的一些功能,所以呢,自然而然的涉及到怎么自动接听/挂 ...
最新文章
- Python staticmethod() 函数
- 信息检索顶会SIGIR 2021大奖出炉!山东大学荣获最佳学生论文
- 5G将如何推动未来十年智能城市的发展
- [转载]读塔莎奶奶的美好生活
- Python爬虫(十)_XPath与lxml类库
- (转载)浏览器兼容性问题大汇总
- mysql集群经常无法truncate_失败的mysql cluster配置-无法顺利转换已有数据
- C++ using的三种使用策略以及具体的用法
- entity framework不查数据库修改或排除指定字段集合通用方法
- PowerDesigner建立与数据库的连接,以便生成数据库和从数据库生成到PD中
- 数据库创建联合主键(MySql)
- 域控制器诊断工具 (dcdiag.exe)
- Docker学习总结(31)——使用Maven插件构建docker镜像
- Mysql支持中文全文检索的插件mysqlcft-应用中的问题
- linux下client命令,Linux系统smbclient命令的使用方法
- 2022年3月份报告合集(共353份)
- 汽车软件行业工程师详细介绍?(上)
- 关于H.265/HEVC视频压缩标准相较H.264/AVC节省50%左右的带宽方案的推荐
- JavaScript不清不楚之Array.isArray
- MySQL索引创建、删除及事务控制
热门文章
- Linux属于单用户单任务,()是一种单用户,单任务的微机操作系统。AUNIXBDOSCWinDowsDLinux...
- Python基础学习(1)
- vs下载问题:请检查网络连接
- c#动态生成控件,并为控件注册事件
- 公交/地铁出行的场景,需要考虑哪些测试点
- 汤唯遭“封杀”被证实 广电总局:对事不对人
- Android的Button属性使用
- Python:pandas groupby实现类似excel中averageifs函数的功能
- DIV怎么自动添加滚动条?并给滚动条添加样式
- ‘latin-1‘ codec can‘t encode characters in position 103-115: Body (‘一串中文‘) is not valid Latin-1