生活随笔
收集整理的這篇文章主要介紹了
HAL
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
分析hardware/akm/AK8975_FS
大致有4類文件,有著不同的分工
1:hardware\akm\ak8975_fs\libsensors\Sensors.cpp
hal中一般支持多類設備,起框架作用,主要關注poll方法
2:AkmSensor.cpp
具體sensor的驅動代碼
3:SensorBase.cpp
sensor的共有方法,比如open /dev/input/eventx...
4:InputEventReader.cpp
讀取數據等方法
- hardware\akm\ak8975_fs\libsensors\Sensors.cpp
起總領作用
static int open_sensors(const struct hw_module_t* module, const char* id,struct hw_device_t** device)
{sensors_poll_context_t *dev = new sensors_poll_context_t();// sensors_poll_context_t::sensors_poll_context_tmSensors[akm] = new AkmSensor();mPollFds[akm].fd = mSensors[akm]->getFd();// 填充回調函數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;
}
static struct hw_module_methods_t sensors_module_methods = {.open = open_sensors
};
// HAL入口
struct sensors_module_t HAL_MODULE_INFO_SYM = {.common = {.id = SENSORS_HARDWARE_MODULE_ID,.methods = &sensors_module_methods,},.get_sensors_list = sensors__get_sensors_list,
};
重點分析一下poll方法:對每個sensor使用sensor->readEvents讀取數據
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); // sensors_poll_context_t::pollEventsdo {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); // 多態機制,讀取數據count -= nb;nbEvents += nb;data += nb;}}} while (n && count);
}
- hardware\akm\ak8975_fs\libsensors\AkmSensor.cpp
具體sensor驅動
// 得到指定設備的fd
AkmSensor::AkmSensor()
: SensorBase(NULL, "compass"), // 對/dev/input/eventx進行ioctl(EVIOCGNAME)得到name,如果是"compass",則能使用該HAL code
{mPendingEvents[MagneticField].version = sizeof(sensors_event_t);mPendingEvents[MagneticField].sensor = ID_M;mPendingEvents[MagneticField].type = SENSOR_TYPE_MAGNETIC_FIELD; // 上報的數據類型mPendingEvents[MagneticField].magnetic.status = SENSOR_STATUS_ACCURACY_HIGH;
}
再看數據讀取函數,對接上Sensors.cpp
int AkmSensor::readEvents(sensors_event_t* data, int count)// 讀取數據ssize_t n = mInputReader.fill(data_fd); // // 處理數據while (count && mInputReader.readEvent(&event)) {int type = event->type;if (type == EV_ABS) {processEvent(event->code, event->value); // 稍加處理case EVENT_TYPE_MAGV_X:mPendingMask |= 1<<MagneticField;mPendingEvents[MagneticField].magnetic.x = value * CONVERT_M;break;mInputReader.next();}}
- hardware\akm\ak8975_fs\libsensors\SensorBase.cpp
sensor的共有部分抽象
// 遍歷"/dev/input"下的所有節點,使用ioctl(EVIOCGNAME)得到name,看能否匹配上,匹配上則記錄fd
SensorBase::SensorBase(const char* dev_name,const char* data_name): dev_name(dev_name), data_name(data_name),dev_fd(-1), data_fd(-1)data_fd = openInput(data_name);const char *dirname = "/dev/input";dir = opendir(dirname);strcpy(devname, dirname);filename = devname + strlen(devname);*filename++ = '/';while((de = readdir(dir))) {strcpy(filename, de->d_name);fd = open(devname, O_RDONLY);if (fd>=0) {char name[80];if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {name[0] = '\0';}if (!strcmp(name, inputName)) {strcpy(input_name, filename);break;}}}closedir(dir);return fd;
- hardware\akm\ak8975_fs\libsensors\InputEventReader.cpp
維護sensor數據
// 讀取"/dev/input/eventx"數據
ssize_t InputEventCircularReader::fill(int fd)
{// read name為compass的"/dev/input/eventx"const ssize_t nread = read(fd, mHead, mFreeSpace * sizeof(input_event));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;
}
void InputEventCircularReader::next()
{mCurr++;
}
轉載于:https://www.cnblogs.com/zzss-feature/p/8342610.html
總結
以上是生活随笔為你收集整理的HAL的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。