Linux驱动工程师成长之路(2)

以前我在学习Linux驱动的时候就特别想知道,那些正在做linux驱动工作的人到底一天都在做什么呢?如果有谁能描述一下,那让我们这些初学者更清楚的知道工作需要些什么,那我们就更好的去学习,现在我就来记录一下,我的这个菜鸟之路。

1-实验环境:

我相信每个学习驱动的人都要做两件事:一个是理论的学习,另一个是做实验;理论的学习算是比较的轻松,驱动相关书籍(我用的是《LDD3》和华清的那本《Linux设备驱动开发详解》),Linux设备驱动开发详解PDF 宋宝华版下载见 还有网上的很多资源;学习完一个驱动的理论之后,我们就要做实验,效果出来之后,我们才会感觉,真的学习了驱动。比如学习LCD驱动,先看相关理论知识,然后就得让LCD真正显示出东西来。在以前学习C语言或者应用程序的编写时,这个实验的环境很容易的搭建起来,只要一台电脑,装个开发软件就ok了,而现在这个嵌入式,是要与具体的硬件打交道,光有电脑不行,还得有板子,有了板子还得搭建这个驱动开发的环境。我的驱动学习环境是这样的:虚拟机里装RedHat5,板子里面有烧写好的bootloader,bootloader能够和PC机进行网络通信,可以通过网络下载PC机上的内核到板子上,然后让内核跑起来。内核起来之后就通过NFS挂载根文件系统,NFS根文件系统的好处就在于,我们可以在PC机上去写程序,然后在板子上挂载的NFS根文件系统的运行,效果就会在板子上显示出来(如果不了解NFS根文件系统上网查一下),不过后期我调驱动的时候都是将驱动编进内核,然后把内核下载到板子上跑。我当时为搭建这个驱动调试环境费了很大的劲,不知道搭了多少遍,主要问题出在那个bootloader不能和PC机通信,就不能用网络下载内核了,内核搞不进去就没法调了。来到公司,领到电脑后第一个任务就是搭建开发环境,公司有专门的人负责这个开发环境的搭建,装什么软件,出了什么问题都会有专门人来给你解决,我相信其它公司也一样,你去工作不会让你在搭建环境上费劲的,除非你是重头做起。所以我在这儿和初学者说一下:不要花太多的时间去搭建那个环境,工作当中公司肯定会给你做好的。拿到开发板后按照他的手册,尽快把环境搭建好进入驱动的学习。

2-驱动调试

先说一下,我感觉驱动组的人都在做什么;他们好像都是在调试bug。从我们整个公司的研发结构来讲:有做硬件的(原理图的设计,画PCB,调试硬件),我们驱动组(专门负责驱动),应用程序组,测试组。测试组的人相当于用户,整天都在那儿测试,如果发现有bug他们就提交上来,这些bug很多都是我们驱动的事。比如声音有POP音,POP音什么意思呢,就是你手机开音乐时,最先出来一个特别高的音,这个bug是带我那个人在调,他已经调出来了,他说是因为codec和另外一个模块的上电顺序不对。找这种bug难吗?如果经验不多,最开始估计还得靠靠运气,有些bug真难调。以前我多少认为做驱动,就是写驱动,现在看来不是,有些驱动芯片厂家会给的,但也不是一拿来就好用。写程序,不难,难的是调试程序。带我那个人以前是做应用的,我问他是做应用难还是做驱动难,我记得他说:驱动就是会出一些莫名其妙的问题,估计得做到5年以上才会轻松点(他现在做了快一年了),看来驱动还真是有点难度。以前我特别想做硬件,感觉做硬件很牛啊!我们旁边就是坐着两个做硬件的,感觉他们特别的轻松,整天笑容满面,有说有笑的,边听音乐边画PCB,而且很少加班;再看这边我们做驱动的,从最上面的驱动总监,驱动经理,再到我,每个人都愁眉苦脸,哎声叹气的,抓脑袋啊!而且每个人基本都是晚上8点后才走,我们三个实习的菜鸟都是近9点才走。测试部的美女(测试部大部分都是女的)走就走光了。看来我们以后的重点任务,就是调试驱动了。

3-第一个任务:LCD驱动分析

前面说了以后我们的大部分工作就是调试驱动,要调试一个驱动,如果你不懂这个硬件工作原理,不熟读datasheet,不懂驱动的框架,不懂数据流的传递过程;你是基本没法去调试的。所以头儿给让我先分析LCD驱动(我的头是负责多媒体这块的驱动,包括LCD,camera,audio)最后还要自己写一个驱动分析的总结,给我了一些文档,还有指定了内核下对应的LCD驱动的源码。文档当然都是英文的所以学好英文还是很重要的。于是我就开始看datasheet和源代码,LCD驱动相对来说还比较简单,而且以前我也看过s32440上的LCD驱动,所以分析这个驱动还算顺利,大致驱动框架还是知道的。三天也就分析得差不多了,头儿的头儿见我分析得差不多了,就给来了个任务,说现在有版手机的屏,手机上的屏是好的,但是通过Androidscreencast抓屏到PC机上却是花屏,usb这条通路肯定是好的,我拿过来down了内核进去发现还真是花的,好像是像素错位了。当时我是一点思路都没有。这太奇怪了,手机上的屏是好的,居然抓出来的屏是花的,这跟驱动有关系吗?头的头儿说:framebuffer里面的数据不对,好像是32字节对其的问题。行我什么都不用想看看吧。我的想法是,既然手机本身的屏没有问题,那说明LCD驱动的写的这一路没有问题,但抓屏这一路,应该是去读取framebuffer里面的数据,说明是读的这一路的问题,我把fbmem.c中的fb_fops结构体的的.read函数设为空,抓出来的屏就没有显示,说明它是通过读取这个数据去显示的。但我分析了一下读的这个函数根本没有任何的问题,因为这是LCD驱动比较靠上层的函数,所有的LCD驱动,它基本都是一样的。那接着就瞎改LCD参数吧,无意之中我把屏信息的xres从原来的240改成了320就能正常显示了,最后我又改成256也能正常显示,说明这个数必须是32的整数倍就好用了。当然我不能改这个xres来解决问题,这样的话那手机上的屏肯定就不能显示正确了。得根据这个去找原理,最后在程序中某处发现像一行的像素个数必须是32的整数倍,至于为什么是32的整数倍我现在还搞懂,这得再仔细看芯片手册看能不能找到答案,如果行像素个数不是32的整数倍的话,在计算分配的缓冲区长度的时候,就是会将行像素个数凑成32的整数倍,如果是240的话那就用256来算。一个像素用16bits(2bytes),那一行就多出来(256-240)*2=32个bytes.如果androidscreencast在抓屏时多抓了32个字节,而显示一行又只显240个像素,那么这剩下的32bytes==16个像素就移到下一行,这样整个图像就错位了,这只是我的分析。为了验证我的想法,我在fbmem.c的read函数中如果是读到240*2个字节的时候我就直接跳过接下的的32个字节。改了之后还是没有效果。这时我问了一个做这个驱动的同事,他说这个bug他已经解决了,给了我一个framebuffer_service.c说把system目录下面的.../../adb/framebuffer_service.c替换就好了,我实验了一下还真是好了,分析了一些他的改动和原版,大概意思和我分析的原因差不多,就是多出来的那32个字节的处理。不过这里的程序已经算是应用程序了,真是令我郁闷,我以前看的都是kernel下面的代码,而从来没有去分析过system下面的代码,因为这部分已经感觉像是应用的东西了,不过还是让我开了一下眼界。第一个任务就这样结束了。

4-驱动分析总结文档

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwfpxp.html