本文介绍了编写驱动必备基础知识,编写驱动的难点之处。并从按键驱动到Sensor驱动简单介绍示范了驱动编写过程。并给出了驱动学习方法和评价驱动能力的技术指标!

驱动学习

•整个内核70%以上是各种驱动代码

•每一个你日常使用的小功能背后都有复杂的实现!

•Linux 驱动程序设计模式(40%) char,block,net,input,pci,usb,Platform(bus,device,driver),kset,kobject,proc,sysfs,ioctl,mmap,miscdevice, softirq,tasklet,workqueue, console,

•内核相关知识(30%):内核目录结构,内存访问,ipc,锁,内核数据结构,不通内核版本api,热拔插netlink,内核线程,中断处理(注册,共享),设备树,

•硬件相关知识(30%): 总线,协议(I2C,I2S,SPI,USB,PCI,sensor,bt1120,bt656,LCD),各种CPU、传感器(ADC,sensor,temperature etc)工作原理

Linux kernel map

前置基础知识

  • 模拟电路,数字电路

  • 硬件总线协议,各种RFC文档;

  • 了解硬件电路设计,能看懂电路图。示波器等工具的使用

  • 对C语言了如指掌,各种特殊宏的用法,对内核基本数据结构了解。

  • 熟悉C系统编程,应用层编程

  • 内核软件子系统,各种软件框架

上述知识你都有了一定了解之后,你才能开始尝试去开发驱动了!

学习曲线非常陡峭,必须一次性踏上台阶,否则后续又得重新攀爬。

编写驱动困难之处

  • 打怪升级困难。要有硬件项目才能给你升级涨经验!一个公司硬件项目周期极长,可能几年都做不了几个新硬件项目

  • 新手与熟手完成同样任务时间差异极大!强者越强,你有经验,有难度的活都给你,你没经验,练手的机会都不会给你

  • 一切都是以懵懂中开始的。内核代码量太大,你不可能都熟悉之后再开始动手修改。内核版本之间接口一直变动,没有稳定的软件方法。接口总线RFC文档太长,一般至少几千页的英文文档,你不可能都看完才开始动手。硬件设计可能有漏洞,不是官方设计出错,而是现实情况是当初设计RFC标准的人就没有考虑到这种异常情况

  • 不同总线接口调试方法和工具差异极大,和医院不同科室使用不同工具差不多,你会不会某种工具,可能使你的效率差异几十倍

  • 软件开发,你有一台电脑就足够了。硬件驱动开发,必须有对应的硬件开发板,调试工具Jtag,PC端调试工具一整套才能开始工作

写驱动好比挖隧道

  • 不知道隧道下面什么地质情况,什么岩层结构,是否好施工
  • 是否有地下水,多大的地下水没法确定
  • 是否能完工没法确定
  • 完工时间多久没法确定
  • 在你完工之前,你不知道还需要多长时间才能完工,是否能完工都不清楚
  • 等等

写驱动,就是给你一个垃圾场,要你组装出来一个能走动的钟表!

  • 不知道是否缺少零件,你要对整个软硬件构架了如指掌,比硬件更熟悉硬件
  • 零件是否损坏,有可能多个零件,这个损坏,哪个没有损坏,你换一个同样的零件,说不定可行,也可能不可行
  • 零件是否符合设计规范性能,有可能这个设计错误,根本就是不可能成功的
  • 这个零件的说明书和零件是否匹配,给错了没有?外行连给到手的资料判断是否正确资料的能力都没有
  • 由于你的上游一开始拿到的也是错误的资料,所以给你的也是错误资料
  • 由于商业,保密等各种原因,一开始就给你错误的资料,故意不给你正确资料的情况也有
  • 零件是否完好,是否工作正常
  • 在你组装好,能走动之前,你不知道能否组装好手表
  • 组成的钟表走时快慢是否正常,能够走动起来,说明零件大抵不差了,是驱动开发决定性进展
  • 钟表能走动了,后续就是走时准确的调整。性能优化,续航优化,软件框架优化,内存优化,稳定性优化,电磁兼容等等

从一堆垃圾零件,组装出来一个能走的钟表!从上图到下图的过程!

实现出来

组装好,把驱动跑起来是第一步

性能优化

对于访问外设emmc,不同时序参数访问性能差距很大。对跑分影响很大!

续航优化

不用外设时,可以关闭对应外设电源,或者根据负载动态调节

内存优化

内存占用,Zero Copy,指针传递

稳定性优化

稳定性,眼图,高速性能

电磁兼容

电磁兼容测试,各种标准

等等其它方面

驱动开发深入下去,是一座又一座高山需要攀爬,但基本的驱动开发还是不难的。

驱动案例

每一个外设都有复杂的物理,材料,结构,光学,工艺,版本等等各种复杂因素需要研究,考虑。当然不是每个外设都这么复杂,复杂的摄像头子系统涉及的知识技术几年就研究不完!

每一款芯片构架差异都很大,会有不同的内核软件构架,德州仪器TI一份完整的芯片手册就有3000多页,至少看完前四章(几百页英文文档)才能说对芯片有基本了解。

简单的按键

按键硬件设计方法常用的就有3、4种。每种硬件设计,内核就要好几种软件框架可以实现它。

学习驱动可以从它开始。万里长征第一步,后面慢慢学习I2C,SPI, NAND等外设驱动。

摄像头驱动介绍

可以说是整个手机最复杂的外设驱动!研究两年只能说刚入门。

3A算法是核心: AWB 启动白平衡,AE自动曝光,AF自动对焦

理论上就没有完善的解决方案,只有近似解决方案。技术理论发展很快,经常有新技术和方法出来。

感觉这个很复杂?很正常,整套软件系统自己搞定就需要几十人的团队,一般也就是需要修改整套系统种的某一部分。Sensor驱动,ISP tunning等。

下面简单图解ISP驱动相关知识

图像采集系统

定焦镜头结构

人眼三色光响应

Sensor RGB分量敏感曲线

某芯片ISP构架

ISP构架流程

涉及到Sensor专有知识点有

  • 黑电平与线性化
  • Green Imbalance
  • 坏点消除
  • Vignetting 与 Color shading
  • SNR 与 Raw Denoise
  • Dynamic Range 与 Tone Mapping
  • MTF 与 Demosaic
  • 色彩空间与色彩重建
  • Color Correction Matrix 与 3D LUT
  • Gamma与对比度增强
  • Sharpening
  • Color Space Conversion
  • 空域降噪
  • 时域降噪
  • Color Aberrance Corrention and Depurple
  • 闪光灯
  • HDR
  • Exif 与 DNG
  • 图像防抖
  • 编解码知识 H264 H265等

Sensor子系统涉及到的知识大概有如上,个人做过的最复杂的子系统就这个了。

会写简单驱动,到会写sensor驱动,到会写ISP系统,中间都隔了几年时间差距。

驱动的技术级别

要做好驱动,要熟悉硬件,总线协议,要会怀疑每一处地方,其它每个人给的信息都可能是错误的,如何定位这个错误就是驱动的工作。成功的路径只有一个,而失败的路径千千万万,驱动的的工作就是找到这条成功的路。

必备:入门水平

必备:入门水平,能在别人指导下完成一些简单驱动开发。在一些深入,系统学习后进入下一阶段。

  • 基本的数电模电基础。

  • 熟悉一些常用开发工具。

  • 熟悉linux 内核基本驱动框架。懂得基本内核原理。

  • 独立实现过char字符设备。

  • 调试过一些常见总线接口设备。比如常见的I2C,SPI设备。

中等水平

中等水平:能够按照指示完成任务,需要大量的时间和大量产品开发慢慢积累经验,完成本阶段进阶。

熟练使用各种开发工具。

对linux驱动绝大部分常用框架都有研究。

能够进行ip core外围器件级别的移植。

熟悉内核锁的使用,了解中断上下文。

能够分析定位解决时序问题。

用gpio模拟实现过I2C,SPI等总线驱动。

对oops定位分析,驱动调试熟悉。

对proc,sys,debugfs熟悉或者做过。

能够在现有驱动基础上修改,阅读datasheet对接新硬件。

在一些行业应用领域能够在fae帮助下完成外围设备驱动。

了解arm硬件构架,懂得基本arm汇编指令。基本c程序优化。

懂得基本pcb升级,打板贴片流程。

能够解决大部分硬件异常问题。

高手进阶

高手进阶:能够独当一面,带领团队。

工具什么的无所谓,有自己一套最高效的配置工具。

能够进行ip core级别的移植。

熟悉并懂得使用各种内核锁,能用内核线程实现一些复杂需求,中断上下文实现都有做过。

对应用层构架各种技术方法也都非常熟悉。

知道单核、多核同构、异构构架的内核、驱动、应用层设计差异及处理方法,优化方法。

熟悉arm构架,arm指令集。懂得怎么根据硬件构架,芯片指令集优化程序。

知道怎么使用汇编,cache优化。知道cache一致性原理及其实现。

深入研究过linux内核实现机制。

熟悉编译,汇编,链接原理。能够定位一些复杂问题,知道怎么通过编译器,链接器实现一些非标准的功能。

独立实现过绝大部分外围驱动。

能够独立从头开始实现一些复杂框架驱动。例如网络设备,视频设备等。

在一些具体应用业务上研究的非常深入,达到行业一流水平。

深入研究过绝大部分总线接口。比如音视频接口,编解码,usb,网络等业务。

画过pcb,或者至少了解pcb设计,绘制,打板过程中的各种问题。

能够熟练协助硬件定位解决各种问题。

超一流高手进阶

超一流高手进阶:技术方面基本没有什么可以难倒你的了。

自己去实现基本的uboot,内核。

能够自己设计实现全新的内核框架。

开始一些具体应用的结构,物理,数学,光学等方面深入研究。

一些问题能否解决,怎么解决,更多的从数学角度分析。

参与主线linux kernel开发。

对hdl,Verilog深入了解,自己设计芯片ip core。

以上都是个人见解,仅供参考!

参考

相关书籍

Linux内核完全注释

Linux设备驱动程序

Linux设备驱动开发详解

上面两本是介绍Linux kernel软件驱动框架的

Linux内核源代码情景分析(上册)

相关文章

如何编写Linux驱动
本文介绍了编写驱动必备基础知识,编写驱动的难点之处。并从按键驱动到Sensor驱动简单介绍示范了驱动编写过程。并给出了驱动学习方法和评价驱动能力的技术指标!
3G,4G,Wifi选型需求分析及技术简介
详细介绍了3G,4G,wifi技术类型,选型,移植,性能介绍全过程。写了好多年了,禁止转载,第一次公开发表。
海思MPP&UNF构架源代码级分析
行业中分析海思MPP内核构架,源码分析,多年经验总结积累结果。写了好多年了,禁止转载,第一次公开发表。
如何实现自己的操作系统
作为一个程序员,你肯定设想过创造属于自己的操作系统,这其中涉及非常多的知识。本文大概介绍了涉及的知识点,并给出了相关书籍和参考源代码仓库!
手把手教你构建 C 语言编译器
“手把手教你构建 C 语言编译器” 这一系列教程将带你从头编写一个 C 语言的编译器。希望通过这个系列,我们能对编译器的构建有一定的了解,同时,我们也将构建出一个能用的 C 语言编译器,尽管有许多语法并不支持。

系列教程

全部文章RSS订阅

系统编程系列


文章作者: 夜法之书
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 夜法之书 !
评论
 上一篇

阅读全文

管理故事锦集
管理故事锦集 管理故事锦集
几十个关于管理,经营的故事。寓教于乐,寓意深刻,在自己遗忘之前,记录保存下来。包括 扁鹊三兄弟,曲突徒薪,猎人与狗等等
2022-08-07
下一篇 

阅读全文

如何实现自己的操作系统
如何实现自己的操作系统 如何实现自己的操作系统
作为一个程序员,你肯定设想过创造属于自己的操作系统,这其中涉及非常多的知识。本文大概介绍了涉及的知识点,并给出了相关书籍和参考源代码仓库!
2022-07-27
  目录