最近刚看完freescale mma8451的驱动,并且一直了驱动,自己也没怎么改代码,不过读了一下代码,还是有点体会的,下面我就来分析一下。
首先看下代码结构,有兴趣的可以从一下方式获得代码,[email protected]:zhangjie201412/WorkSpace.git ,最好是先发mail给我,
jay@jay:~/mygit$ tree
.
└── kernel
├── arch
│ └── arm
│ └── mach-mx5
│ └── mx53_smd.c
├── drivers
│ └── hwmon
│ └── mma845x
│ ├── Makefile
│ ├── mma845x.c
│ ├── mma845x.h
│ ├── mma_char.c
│ ├── mma_core.c
│ ├── mma_input.c
│ ├── mma_regs.h
│ ├── mma_sysfs.c
│ └── mma_sysfs.h
└── include
└── linux
└── mma845x.h
其中一个头文件,然后是一个驱动包,里面内容蛮丰富的,还有就是要在板级文件里面注册platform的device端,我这里是基于iMX53的Android BSP
首先咱还是来找源头吧,找啊找,看名字就知道我们先要分析这个mma_core.c文件
然后是注册,
这里是由probe函数传进来的client参数来得到platform_data,就是我们在板级文件中填充的那些个结构体,我觉得Linux设计的这个platform架构的驱动很好,他可以很好的把驱动和设备隔离开来,虽然有的时候还是会联系到一起,但是对于可移植性更强了,因为,驱动只是对设备的统一管理,而platform device端只需要配置cpu的gpio跟deivce的连接情况,还有一些soc中继承的功能的配置以及注册。
还是先来看一下这个结构体吧,
release中的代码就不多说了,跟open函数正好相反。
然后是比较重要的ioctl和read function
我们也可以自己再这里加上对I2C的读操作来把这里的read函数挂到用户空间,我想这里的ioctl函数应该是来设置threshold的,应该是用在HAL层中来被设置的。
而这里的read函数也可以当做poll模式下来读取xyz的数据,大家可以看到在read中有作比较,当读回来的数据大于threshold时才把数据copy到用户空间。
OK,这个字符驱动暂时介绍到这边,下面我们接着看mma_core.c中的probe函数
下面是初始化文件系统
/sys/class/sensor # ls -l
lrwxrwxrwx 1 root root 0 Jan 2 01:10 mma -> ../../devices/virtual/sensor/mma
lrwxrwxrwx 1 root root 0 Jan 2 01:10 motion_detection0 -> ../../devices/virtual/sensor/mma/motion_detection0
lrwxrwxrwx 1 root root 0 Jan 2 01:10 orientation_detection0 -> ../../devices/virtual/sensor/mma/orientation_detection0
lrwxrwxrwx 1 root root 0 Jan 2 01:10 tap_detection0 -> ../../devices/virtual/sensor/mma/tap_detection0
lrwxrwxrwx 1 root root 0 Jan 2 01:10 transient_detection0 -> ../../devices/virtual/sensor/mma/transient_detection0
/sys/class/sensor #
然后是初始化信号量和定时器,这里就不多说了。
接下来是创建了一个线程并执行他,这个线程是一个死循环,也就是我们这里最关键的一个函数,之后再说。
porbe函数就先讲到这里,这里主要还是做了一些初始化的东西,下面来分析一下这个驱动是如何工作的,其实相关的就是这里最重要的2个东西,一个是定时器,还有一个是这个thread的处理,我们下面接着看
首先是一个do while来试图获取信号量,这里信号量被初始化为0,所以这边是得不到的,就会一直等在这边,前面我们看过定时器和中断函数中都做了对信号量的释放动作,联想到这边就是说,我们的线程不是一直在走的,只有当发生定时器时间到达和中断发生了,才会让我们这里的线程继续往下走,也就实现了这里的polling和interrupt 这2中模式。
这个线程下面的代码我们都能猜到,就是通过I2C读取芯片中的数据,然后利用input子系统push到用户空间,如果是polling mode的话就修改下次定时到达的时间,这里的设计还是满巧妙的,有待学习,特别是我觉得代码写的比较规范。
下面来一张图来分析这里的处理流程。
画的太丑了,见谅!!