Android6.0 Sensor架构和问题分析

Android: sensor 时间戳从sensor子系统到AP android层的变化 因为_offset_ns的存在,两个时间体系的转换没有那么简单,不知offset是不是个常量,还是每次开机都会变化?开机也有可能变化? void har::handle_sns_client_event(const sns_client_event_msg_sns_client_event& pb_event) { if (pb_event.msg_id() == SNS_HAR_MSGID_SNS_DATA) { sns_std_sensor_event pb_stream... 阅读详情

转载自:http://blog.youkuaiyun.com/cgx090902

本文在借鉴网友的资料后再重新梳理了一遍,都是站在前人的基础、巨人的肩膀上再次总结分析出来的,仅供大家参考!

本文主要描述了在Android 6.0系统、MTK6755平台上sensor相关软硬件的体系架构的分析理解。
一、系统架构(Architecture)
1.1 Android体系架构图
 
图1.1
图1.1是Android系统的典型五层体系架构图,分别为Applications、Framework、Native、HAL和Kernel五大层次。我们接下来分析的sensor子系统也基本按照这五个层次分别进行分析。
1.2  Sensor子系统架构图
 
图1.2
1、黄色部分表示硬件,它要挂在I2C总线上(目前大部分sensor基本都通过I2C进行通信和控制)。
2、红色部分表示驱动,驱动中会申请Input设备,注册到Kernel的Input Subsystem上,然后通过Event Device把Sensor数据传到HAL层,准确说是HAL从Event读。
    在MTK6755平台中,这里的驱动driver实际上分成了两层,一层为虚拟逻辑Hub层,用来管理兼容不同类型的所有的sensor,如有可能有两家厂商的不同g-sensor,则可以通过这个虚拟逻辑出来的Hub进行统一管理;另一层为每款具体sensor的真正驱动,通过注册挂载到Hub中。如图1.3:
 
图1.3
从图1.3可以看出,MTK平台对虚拟逻辑Hub层使用了两种实现方式,一种是以前平台一直使用的hwmsen虚拟逻辑Hub,由它统一管理所有类型所有厂商的sensor,目前我司没有使用这种方式,因此在后面就不对它进行分析了;另一种是分别为每一种类型的sensor实现了一个虚拟逻辑Hub,如accel负责管理所有G-sensor。

3、图1.2绿色部分表示动态库,它封装了整个Sensor的IPC机制,如SensorManager是客户端,SensorService是服务端,而HAL部分是封装了服务端对Kernel的直接访问。在MTK平台的HAL层里,也同样为对接下层的两种虚拟逻辑Hub实现了不同的HAL层代码。

4、蓝色部分就是我们的Framework和Application了,JNI负责访问Sensor的客户端,而Application就是具体的应用程序,用来接收Sensor返回的数据,并处理实现对应的UI效果,如屏幕旋转,打电话时灭屏,自动调节背光等。
二、应用(Applications)
2.1 传感器介绍
    Android 6.0 系统sensors.h文件中定义了26种传感器类型,其中主要的8种传感器类型分别是:加速度传感器(accelerometer)、磁力传感器(magnetic field)、方向传感器(orientation)、陀螺仪(gyroscope)、环境光照传感器(light)、压力传感器(pressure)、温度传感器(temperature)和距离传感器(proximity)。其他的几种传感器基本都可以由上述的传感器进行算法实现,如动作探测传感器(significant motion)、步行探测传感器(step detector)、计步传感器(step counter)、心率计传感器(heart rate)等。
2.2 应用开发
    Android定义的API接口给应用层提供了几种方法,可以很容易让你在运行时确定设备上有哪些sensor。API还提供了让你确定每个sensor信息和功能的接口,比如sensor名字、类型、厂商、数据值的范围、数据精度等。
    Android开发者官网上给出的典型的应用开发代码如下:
 
图2.1
在构造函数中,获取SystemSensorManager,并获取到加速传感器的Sensor;在onResume方法中调用SystemSensorManager.registerListener注册监听器;
Activity同时实现了SensorEventListener接口。当Sensor数据有改变的时候将会调用onSensorChanged方法。
 
图2.2
三、框架(Framework)
3.1 Sensor总体调用关系图
 
图3.1
sensor框架分为三个层次,客户端、服务端、HAL层,服务端负责从HAL读取数据,并将数据写到管道中,客户端通过管道读取服务端数据。
客户端主要类
SensorManager.java
    从android4.1开始,把SensorManager定义为一个抽象类,定义了一些主要的方法,该类主要是应用层直接使用的类,提供给应用层的接口
SystemSensorManager.java
    继承于SensorManager,客户端消息处理的实体,应用程序通过获取其实例,并注册监听接口,获取sensor数据。
SensorEventListener接口
    用于注册监听的接口
Looper
    用申请注册的线程Looper或系统初始化线程的Looper,来负责读取sensor数据
android_hardware_SensorManager.cpp
    负责与java层通信的JNI接口
SensorManager.cpp
    sensor在Native层的客户端,负责与服务端SensorService.cpp的通信
SenorEventQueue.cpp
    消息队列
服务端主要类
SensorService.cpp
    服务端数据处理中心
SensorEventConnection
    从BnSensorEventConnection继承来,实现接口ISensorEventConnection的一些方法,ISensorEventConnection在SensorEventQueue会保存一个指针,指向调用服务接口创建的SensorEventConnection对象
BitTube.cpp
    在这个类中创建了管道,用于服务端与客户端读写数据
SensorDevice
    负责与HAL读取数据
HAL层
  sensor.h是google为Sensor定义的Hal接口,单独提出去

3.2客户端实现
调用时序图
 
图3.2
初始化SystemSensorManager
 
图3.3
系统开机启动的时候,会创建SystemSensorManager的实例,在其构造函数中,主要做了三件事情:
1、初始化Sensor列表:调用JNI函数nativeCreate,对sensor模块进行初始化。创建了native层SensorManager的实例。
2、初始化JNI:调用JNI函数nativeClassInit()进行初始化
3、获取Sensor列表:调用JNI函数nativeGetSensorAtIndex获取sensor,并存在mFullSensorsList和mHandleToSensor列表中
实现注册监听器
 
图3.4
当有应用程序调用registerListenerImpl()方法注册监听的时候,会用注册线程的Looper或系统初始化线程的Looper来循环等待SensorEvent事件并读取来自服务端的数据。
    接着实例化内部类SensorEventQueue,通过调用JNI函数nativeBaseEventQueue()来创建消息队列,JNI最终调用Native SensorManager来完成真正的创建消息队列。
    然后通过实例化的SensorEventQueue添加需监听的sensor并对其使能和设置采样事件等。
3.3 服务端实现
调用时序图
 
图3.5
启动SensorService服务
    在SystemServer进程中调用native 方法startSensorService()函数,通过JNI调用,在JNI函数中调用SensorService::instantiate()实例化SensorService对象。
SensorService初始化
SensorService创建完之后,将会调用SensorService::onFirstRef()方法,在该方法中完成初始化工作。
首先获取SensorDevice实例,在其构造函数中,完成了对Sensor模块HAL的初始化:
 
图3.6
这里主要做了三个工作:
1、调用HAL层的hw_get_modele()方法,加载Sensor模块so文件
2、调用sensor.h的sensors_open_1()方法打开设备
3、调用sensors_poll_device_1_t->activate()对Sensor模块使能
再看看SensorService::onFirstRef()方法:
 
图3.7
在这个方法的前面部分中,主要做了3件事情:
1、创建SensorDevice实例
2、调用SensorDevice.getSensorList(),获取Sensor模块所有传感器列表
3、为每个传感器注册监听器,Android还同时注册实现了6个虚拟传感器
 
图3.8
注意!:如果O-sensor需要使用厂商自己的算法,需如上图添加宏控制过滤,不然会默认使用Android自带的算法计算O-sensor的值,这样有可能会导致数据不准确。
在新的线程中读取HAL层数据
SensorService实现了Thread类,当在onFirstRef中最后调用run方法,将在新的线程中调用SensorService::threadLoop()方法。在该方法while循环中一直poll读取HAL层数据,再调用SensorEventConnection->sendEvents将数据写到管道中。

3.4 客户端与服务端通信
 
图3.9
客户端服务端线程
    在图中可以看到有两个线程:
        1、一个是服务端的一个线程,这个线程负责源源不断的从HAL读取数据。
        2、另一个是客户端的一个线程,客户端线程负责从消息队列中读数据。
创建消息队列
    客户端可以创建多个消息队列,一个消息队列对应有一个与服务器通信的连接接口
创建连接接口
    服务端与客户端沟通的桥梁,服务端读取到HAL层数据后,会扫面有多少个与客户端连接的接口,然后往每个接口的管道中写数据
创建管道
    每一个连接接口都有对应的一个管道。
那么数据的形式是怎么从HAL层传到JAVA层的呢?
    其实数据是以一个结构体sensors_event_t的形式从HAL层传到JNI层。看HAL的结构体:
 
图3.10
在JNI层有一个ASensorEvent结构体与sensors_event_t向对应,
 
图3.11
    经过前面的介绍,现在知道了客户端实现的方式及服务端的实现,但是没有具体讲到它们是如何进行通信的,现在看看客户端与服务端之间的通信。
  主要涉及的是进程间通信,有IBind和管道通信。
  客户端通过IBind通信获取到服务端的远程调用,然后通过管道进行sensor数据的传输。
服务端
  native层实现了sensor服务的核心实现,Sensor服务的主要流程的实现在sensorservice类中,下面重点分析下这个类的流程。
 
图3.12
看看sensorService继承的类:继承BinderService<SensorService>这个模板类添加到系统服务,用于Ibinder进程间通信。
 
图3.13
SensorService服务的实例是在JNI函数中调用SensorService::instantiate()创建的,即调用了上面的instantiate()方法,接着调用了publish().在该方法中,我们看到了new SensorService的实例,并且调用了defaultServiceManager::addService()将Sensor服务添加到了系统服务管理中,客户端可以通过defaultServiceManager:getService()获取到Sensor服务的实例。
    继承BnSensorServer这个是sensor服务抽象接口类提供给客户端调用:
 
图3.14
ISensorServer接口提供了两个抽象方法给客户端调用,关键在于createSensorEventConnection()方法,该在服务端被实现,在客户端被调用,并返回一个SensorEventConnection的实例,创建连接,客户端拿到SensorEventConnection实例之后,可以对sensor进行通信操作,仅仅作为通信的接口而已,它并没有用来传送Sensor数据,因为Sensor数据量比较大,IBind实现比较困难。真正实现Sensor数据传送的是管道,在创建SensorEventConnection实例中,创建了BitTube对象,里面创建了管道,用于客户端与服务端的通信。
客户端
    客户端主要在SensorManager.cpp中创建消息队列
 
图3.15
SensorEventQueue类作为消息队列,作用非常重要,在创建其实例的时候,传入了SensorEventConnection的实例,SensorEventConnection继承于ISensorEventConnection。
  SensorEventConnection其实是客户端调用SensorService的createSensorEventConnection()方法创建的,它是客户端与服务端沟通的桥梁,通过这个桥梁,可以完成一下任务:
1.    获取管道的句柄
2.    往管道读写数据
3.    通知服务端对Sensor使能
3.5 流程解析
交互调用时序图
 
图3.16
客户端获取SensorService服务实例
  客户端初始化的时候,即SystemSensorManager的构造函数中,通过JNI调用,创建native层SensorManager的实例,然后调用SensorManager::assertStateLocked()方法做一些初始化的动作。
 
图3.17
前面我们讲到过,SensorService的创建的时候调用了defaultServiceManager:getService()将服务添加到了系统服务管理中。
  现在我们又调用defaultServiceManager::geService()获取到SensorService服务的实例。
  在通过IBind通信,就可以获取到Sensor列表,所以在客户端初始化的时候,做了两件事情:
    1. 获取SensorService实例引用
    2. 获取Sensor传感器列表
创建消息队列
    当客户端第一次注册监听器的时候,就需要创建一个消息队列,也就是说,android在目前的实现中,一个监听器对应一个消息队列,一个消息队列中有一个管道,用于服务端与客户端传送Sensor数据。
  在SensorManager.cpp中的createEventQueue方法创建消息队列:
 
图3.18
客户端与服务端创建一个SensorEventConnection连接接口,而一个消息队列中包含一个连接接口。
创建连接接口:
 
 
图3.19
关键在于BitTube,在构造函数中创建了管道:
 
 
图3.20
其中:sockets[0]就是对应的mReceiveFd,是管道的读端,sensor数据的读取端,对应的是客户端进程访问的。
  sockets[1]就是对应mSendFd,是管道的写端,sensor数据写入端,是sensor的服务进程访问的一端。
  通过socketpair()创建管道,通过fcntl来设置操作管道的方式,设置通道两端的操作方式为O_NONBLOCK,非阻塞IO方式,read或write调用返回-1和EAGAIN错误。
总结下消息队列
  客户端第一次注册监听器的时候,就需要创建一个消息队列,客户端通过Looper从消息队列里面读取数据。
  SensorEventQueue中有一个SensorEventConnection实例的引用,SensorEventConnection中有一个BitTube实例的引用。
使能Sensor
  客户端创建了连接接口SensorEventConnection后,可以调用其方法使能Sensor传感器:
 
图3.21
服务端往管道写数据
前面介绍过,在SensorService中,创建了一个线程不断从HAL层读取Sensor数据,就是在threadLoop方法中。关键在于下面的一个for循环,其实是扫描有多少个客户端连接接口,然后就往每个连接的管道中写数据。
 
 
图3.22
调用了SensorEventQueue消息队列的write()方法
 
图3.23
调用该连接接口的BitTube::sendObjects()和BitTube::write():
 
 
图3.24
到此,服务端就完成了往管道的写端写入数据。
客户端读管道数据
服务端写完数据后,客户端的Looper收到有数据可读事件后,调用JNI中的回调函数从消息队列读取数据。
 
图3.25
然后调用到了BitTube::read():
 
 
图3.26
读取到sensor数据后,通过JNI调回JAVA层的SystemSensorManager类dispatchSensorEvent()方法:
 
 
图3.27
到此,客户端就完成了从管道的读端读入数据,并把数据发给对应监听器的应用。

四、硬件抽象层(HAL)
4.1 基本框架图
 
图4.1
    MTK平台的HAL层和Kernel层,跟高通平台的很不一样。之前说过,MTK平台使用两套机制来实现与sensor的管理和通信。一种是通过hwmsen来管理控制所有sensor,并通过ioctl接口来操作底层sensor和获取数据;另一种是通过为每一种类型的sensor分配一个对象来管理各自类型的sensor,并通过/sys节点来操作底层sensor,通过Input子系统和Event设备来获取sensor数据。我司使用的是第二种方式,因此暂不对第一种方式进行分析。

4.2 基本定义
    在linux操作系统中,应用同硬件之间的交互都是通过设备驱动来实现,Android系统为了降低应用开发人员开发难度,屏蔽硬件差异,定义出硬件抽象层,为开发人员提供获取各种设备相关的信息的接口。
    Google为Sensor提供了统一的HAL接口,不同的硬件厂商需要根据该接口来实现并完成具体的硬件抽象层。Android中Sensor的HAL接口定义在:hardware/libhardware/include/hardware/sensors.h
Android6.0定义了26中传感器类型:
 
图4.2
传感器模块的定义结构体如下:
 
图4.3
对任意一个sensor设备都会有一个sensor_t结构体,其定义如下:
 
图4.4
每个传感器的数据由sensors_event_t结构体表示,定义如下:
 
图4.5
其中,sensor为传感器的标志符,而不同的传感器则采用union方式来表示。
sensors_vec_t结构体用来表示不同传感器的数据:
 
图4.6
Sensor设备结构体sensors_poll_device_1_t,对标准硬件设备hw_device_t结构体的扩展,主要完成读取底层数据,并将数据存储在struct sensors_poll_device_t结构体中;
poll函数用来获取底层数据,调用时将被阻塞。定义如下:
 
图4.7
其中batch()、flush()、inject_sensor_data()等方法,一般在外挂sensorhub或带有MCU、memory的器件上时才使用,因我司没有使用这些器件,因此本文讨论的sensor架构都不涉及该相关实现。
控制设备打开/关闭结构体定义如下:
 
图4.8
4.2 Sensor HAL实现
Native和HAL交互调用时序图
 
图4.9
SensorDevice属于JNI层,是与HAL进行通信的接口;在JNI层调用了HAL层的open_sensors()方法打开设备模块,再调用poll__activate()对设备使能,然后调用poll__poll读取数据。
创建SensorDevice
在SensorDevice的构造函数中,首先加载sensor设备模块:
 
图4.10
这句代码的意思是JNI加载HAL的库文件,并创建SensorModle的对象,Sensor的库文件通常是sensor.default.so
上图接下来是sensors_open_1(),这个函数并没有在SensorDevice中实现,而是调用的HAL层的函数。
 
 
图4.11
我们先看new sensors_poll_device_t();
 
图4.12
这部分代码就创建HAL和Kernel Event通信的类,还有Sensor数据读写管道的创建。
返回open_sensors再看剩下的代码,就是创建sensors_poll_device_t对象并把sensor控制的相关函数指针赋值给它。
SensorDevice 调用get_sensors_list
这个方法还是调用到了HAL中,而HAL中的这个函数也就是返回以下数组:
 
图4.13
我们需要特别关组的是第4,5个参数,第4参数handle是对kernel而言的,如激活,读写event;而第五个参数是相对于上层代码而言。
SensorDevice的activate方法
在该方法中,会先调用HAL的activate方法,在调用HAL的setDelay方法。
 
图4.14
传进来的就是我们上面说的第4个参数handle,handleToDriver()函数返回的是对应的和kernel交互的类的数组下标(Sensors[acc])。从上图可以看出MTK平台就是这样兼容操作底层sensor的两种实现方式的。
最终通过读写/sys节点来操作底层的sensor设备。
 
图4.15
SensorDevice的poll方法
这个方法同样调用到了HAL中poll__poll()函数,该函数再调用到pollEvents()函数来轮询获取所有sensor数据。
 
图4.16
可以看到,最终会通过对应sensor和kernel交互的类来获取底层的数据,并把数据以sensors_event_t的格式存储在上层传递下来的内存区里,然后返回数量值。
 
图4.17
HAL和kernel通过Input子系统和Event设备来完成数据的传送。

至此,HAL层的部分就分析到这里。Kernel的部分就不再进行详细分析,具体可以阅读MTK文档sensor_all_in_one.pdf来了解MTK平台底层的sensor模块架构和实现。


MPU6050 加速度计和陀螺仪传感器与 Arduino 的接口 虽然该模型并不能准确代表现实世界中加速度计传感器的构建方式,但它通常有助于理解为什么加速度计的输出信号通常以 ±g 为单位指定,或者为什么加速度计在静止时在 z 轴上的读数为 1g,或者在不同方向上您可以期望得到什么样的加速度计读数。该模块的核心是低功耗、低成本的 6 轴运动跟踪芯片 MPU6050,它将 3 轴陀螺仪、3 轴加速度计和数字运动处理器 (DMP) 集成到一个 4mm x 4mm 的微型芯片中。小时候,科学博览会上的陀螺仪总是让我们感到惊讶,因为它们以奇怪的方式移动,甚至似乎违背了重力。 阅读详情

相关推荐

[Android][sensor]高通SEE架构下adsp平台的sensor低功耗原理

高通SEE架构下adsp平台的sensor低功耗原理

csdn_liqian的博客 7623

Sensor Framework原理

1 总体调用关系图 Sensor 框架分为三个层次,客户度、服务端、HAL层,服务端负责从HAL读取数据,并将数据写到管道中,客户端通过管道读取服务端数据。下面简单解释类的功能 1.1客户端主要类 n         SensorManager.java 从android4.1开始,把SensorManager定义为一个抽象类,定义了一些主要的方法,类主要是应用

fe学习之旅 2430

Android Sensor Native 源码分析_aosp源码解读

找到一套好的视频资料,紧跟大牛梳理好的知识框架进行学习。多练。(视频优势是互动感强,容易集中注意力)你不需要是天才,也不需要具备强悍的天赋,只要做到这两点,短期内成功的概率是非常高的。对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。以上就是总结的关于在面试的一些总结,希望对大家能有些帮助,除了这些面试中需要注意的问题,当然最重要的就是刷题了,这里放上我之前整理的一份超全的面试专题PDF还有。

2401_84520457的博客 1130

【Android】Sensor框架Framework层解读

Sensor整体架构    整体架构说明 黄色部分表示硬件,它要挂在I2C总线上 红色部分表示驱动,驱动注册到Kernel的Input Subsystem上,然后通过Event Device把Sensor数据传到HAL层,准确说是HAL从Event读 绿色部分表示动态库,它封装了整个Sensor的IPC机制,如SensorManager是客户端,SensorService是服务端,而...

weixin_34233856的博客 856

android sensor 是怎样获得sensorlist的

从java层到SEE层看怎样得到sesorlist的 frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper()...

u011279649的专栏 5086

从补码原理到实践:RISC-V中addi指令的符号扩展机制详解

本文深入解析了RISC-V架构中addi指令的符号扩展机制。从补码的数学原理出发,详细阐述了12位立即数在指令编码中如何通过符号位进行扩展,并结合lui指令,揭示了加载任意32位立即数的正确方法与实践陷阱,帮助开发者编写高效可靠的底层代码。

weixin_29161719的博客 139

Android Camera稳定性排查实战指南(Qcom Camx)

90%的稳定性问题都能在前4步定位到。如果前4步都没找到根因,大概率是第三方算法的问题——这时候需要找算法厂商一起分析。

699

STC8单片机高精度EV1527解码实战:定时器捕获+状态机抗干扰方案

EV1527是一种广泛应用于433MHz无线遥控的曼彻斯特编码协议,其核心在于对脉宽时序(如同步头、逻辑0/1)的微秒级精确识别。传统外部中断+延时判别方式受MCU中断延迟、编译优化及环境噪声影响,极易导致误码;而基于硬件定时器输入捕获的解码方案,将时间测量交由硬件完成,显著提升时序鲁棒性与温度/电压适应性。该技术适用于STC8等无专用无线解码外设的8位单片机,在智能开关、晾衣架、车库门控等IoT终端中实现低至0.003%的稳定误码率。本文聚焦STC8H系列利用T1定时器下降沿捕获与有限状态机协同解码EV1

weixin_29188997的博客 181

Android Sensor架构和原理分析

https://blog.csdn.net/u010164190/article/details/51908477 本文主要描述了在android2.3平台G-sensor相关软硬件的体系架构和实现原理,按照Applications、Framework、HAL、Driver和Hardware五大层次分别介绍。 1.系统架构 (Architecture) 1.1 Android体系架构图 ...

haigand的专栏 5186

手把手教你用PLECS仿真BUCK数字电源(含DSP代码实现)

本文详细介绍了如何利用PLECS仿真软件与Visual Studio 2022搭建高保真数字电源开发环境,手把手指导从BUCK电路建模、编写硬件感知的C控制算法到参数调优的全过程。重点阐述了通过DLL接口实现软件在环仿真,模拟DSP的ADC/PWM时序,并将验证后的代码无缝迁移至TI C2000系列DSP,构建从仿真到固件的完整数字电源开发闭环,显著提升开发效率与一次成功率。

oo7890的博客 396

写给小白的“具身智能”入门科普

智能”,大家都懂,也就是AI。那么,什么是“具身”?“具身”是一个很小众的名词,通常都出现在哲学、认知科学领域。它的英文叫Embodied,是embody的过去式和过去分词。em-表示“进入,使……”,-body表示“身体”。组合起来,就是“使……进入身体”。Embodied Intelligence(具身智能),顾名思义,就是“使智能进入身体”、“给智能一个身体”的意思。那么,具身智能,是不是就是“AI+身体”呢?这样说并不准确。

欢迎来到我的博客 1822

Android Sensor 理解及架构

Android 6.0 系统支持的传感器多达26种:加速度传感器 (accelerometer)、磁力传感器(magnetic field)、方向传感器(orientation)、陀螺仪(gyroscope)、环境光照传感器(light)、压力传感器(pressure)、温度传感器(temperature)和距离传感器(proximity)等等, Sensor.java 中有相关定义 源码...

博客 4290

用KalmanNet搞定非线性状态估计:当卡尔曼滤波遇上神经网络

本文深入探讨了KalmanNet如何将神经网络与卡尔曼滤波结合,以解决非线性状态估计中的模型失配和噪声不确定性问题。通过保留经典滤波框架并用RNN学习卡尔曼增益,该方法在无人机导航、机器人定位等场景中实现了模型驱动与数据驱动的优势互补,提升了估计的鲁棒性和灵活性。

mango的博客 312

MTK Android P Sensor架构(一)

本来如果只是给传感器写个驱动并提供能读取温湿度数据的节点,是一件比较轻松的事情,但是最近上层应用的同事要求我们按照安卓标准的流程来,这样他们就能通过注册一个服务直接读取传感器事件数据了。这样做的好处就是第三方的应用也能正常读取温湿度的数据并展示。

sdkdlwk的博客 4万+

[VCS]VCS dump fsdb的精细化控制

本文介绍了VCS FSDB波形dump的精细化控制方法。主要内容包括:1)基本dump方式;2)通过$fsdbDumpoff排除特定层次;3)使用$fsdbDumpvars选择性dump指定模块;4)运行时动态控制dump开关;5)通过文件管理排除列表($fsdbDumpoffFile或自定义读取);6)层次控制策略(剪除整棵树或仅当前层)。这些方法可有效控制波形文件大小,提高仿真效率。

元直的博客 1033

【RT-DETR有效改进】为什么YOLO版本的RT-DETR训练模型不收敛精度差的问题

本文的内容同样为本专栏的前期预热文章,文章主要解释一下为什么有的人跑ultralytics仓库的RT-DETR精度很差,模型不收敛,mAP异常的情况。为了验证这一情况我也是跑了多个实验,从多个数据集出发,100-500的数据集我跑了大概5个数据集,1000的我跑了二个,2000的我跑了一个,4000的跑了一个,同时其中一些版本我也用了不同的batch_size来出发验证精度异常的情况。

Snu77的博客 9763

安卓9.0Sensor框架

前言本来如果只是给传感器写个驱动并提供能读取温湿度数据的节点,是一件比较轻松的事情,但是最近上层应用的同事要求我们按照安卓标准的流程来,这样他们就能通过注册一个服务直接读取传感器事件数据...

嵌入式Linux 2853

FPGA发展趋势:异构计算、AI加速、可重构计算

FPGA技术正朝着异构计算、AI加速和可重构计算三大方向发展。作为高效能计算平台,FPGA在异构架构中与CPU/GPU协同工作,发挥低延迟、高能效优势;在AI领域通过定制化架构实现边缘推理加速;其硬件可重构特性支持动态适应多样化计算需求。最新进展包括部分可重构技术、智能网卡和边缘AI应用。未来,FPGA将在自适应计算、量子接口和软件定义硬件等领域持续突破,成为异构计算架构的核心组件,推动硬件与软件的深度融合。性能对比显示FPGA在能效比(5-20TOPS/W)和灵活性方面具有显著优势。

2301_79143213的博客 969

android sensor 框架分析---sensor native分析

6,sensor native分析 获取sensor数据除了android上层进行开发之外,还可以直接进行native开发。 6.1 开发说明 初始化, sensorManager = ASensorManager_getInstance(); //获取AsensorManager对象 //设置加速度的值 accelerometer = ASensorManager_getDefault

Jack的博客 4916

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

4 Android Sensor分析

1 Android Sensor系统框架 Android Sensor系统框架如下: 图1 Android Sensor系统框架图 (1)SystemServer创建SensorService服务。 (2)之后将SensorService服务添加到ServiceManager里。 注意:ServiceManager管理的是SensorService服务不是SensorManager! (3)Android app通过SensorManager获取SensorService服务,SensorMana.

u012906122的专栏 5971

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Android Sensor 架构深入剖析

1、Android sensor架构 Android4.0系统内置对传感器的支持达13种,它们分别是:加速度传感器(accelerometer)、磁力传感器(magnetic field)、方向传感器(orientation)、陀螺仪(gyroscope)、环境光照传感器(light)、压力传感器(pressure)、温度传感器(temperature)和距离传感器(proximity)等。

GangsterPan的专栏 2637

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

上一篇: 关于迭代器作为模板函数的形参的问题
下一篇: Service与Activity之间的数据传递
沉默的过客
博客等级 码龄13年 60粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值