宏观上看,做嵌入式的公司可以分为2两种:芯片原厂和方案公司。

芯片原厂:顾名思义,芯片是自家的,自己设计芯片,然后把芯片卖给别人。

方案公司:买别人的芯片,做方案,也就是做产品。

身为一名驱动开发人员,在芯片原厂做驱动,和在方案公司做驱动,差别还是很大的。

哪些东西只有芯片原厂能做,而方案公司做不了呢?

真驱动 vs “假”驱动

驱动方面,方案公司能做的驱动开发其实主要是一些外设,例如写一个spi从设备驱动,读写一个传感器的数据。如果你在方案公司能真正地去写一个驱动出来,也算是名正言顺的驱动开发人员了。

但绝大多数情况是,你只需要做适配,稍微改一改。例如改一下设备树,改一下Makefile。工作中需要用到你的场景可能是:要添加一个设备,但你不知道怎么添加,也不知道怎么跟它通信,这时可能要稍微翻一下驱动源码,看懂后改一改完事。

而在芯片原厂,所有驱动开发都是要先看芯片手册的,并且很多都是从新建一个.c文件开始。

换句话说,在方案公司写一个外设的从设备驱动,终归还只是调用Linux的通用接口。而原厂是要操作寄存器,看懂芯片手册后,开始定义各个寄存器偏移,各个比特位,然后实现对上层的接口。

例如,在驱动里调用msleep函数进行延时,如果你对驱动了解不够的话,可能会觉得这是软件行为,实际上它依赖于timer驱动。

真正的系统移植

系统移植大家应该听过,在各大嵌入式的教程里也多少听过到,例如uboot移植、内核移植。

对方案公司来说,所谓的uboot移植、内核移植,其实还是适配。

例如,uboot里有很多defconfig配置文件,移植一个支持norflash或者支持T卡功能的uboot,你的工作其实就是换一个defconfig文件,然后跑起来就行。

但我就问一句,如果没有这个defconfig呢?

对芯片原厂来说,系统移植是真正意义上的移植。

什么叫真正意义上的移植?假如现在有一个全新的芯片,我从官网上拉一个uboot和kernel的源码,现在uboot和kernel中没有任何关于这颗芯片的代码,我要从新建一个文件夹开始,一步一步直到能够在芯片上跑起来,这就是真正的系统移植,把Linux在一颗全新的芯片上跑起来。

而这过程有哪些驱动需要完成呢?首先就是要让串口有打印,有打印才能调其它的模块。但只调串口也不行,因为需要时钟,你就得先完成clock驱动,有时钟了还不行,因为需要复用引脚,你就得先完成pinctrl驱动。Linux的正常运行,还需要有一个timer作为系统timer,你就得先完成timer驱动,timer需要产生中断,你就得写一下中断控制器的驱动。

最终Linux正常跑起来,系统相关的驱动clock/reset、pinctrl/gpio、timer、watchdog、pwm、rtc、uart等都是已经写好的,然后在此基础上继续开发其他驱动,例如完成I2C控制器驱动、SPI控制器驱动、网口驱动等等。

当然,前期为了让串口有打印,可以偷懒直接配寄存器,只不过开发其他驱动的人就不能调用接口了。

另外,也不是所有在原厂的人都能有这样的机会做这种从零开始的系统移植,一般是芯片架构做了大调整,或者更换了Linux版本才需要。

内核优化

内核优化其实在方案公司的需求就更少了。

在原厂,内核优化主要是系统启动速度、内核裁剪以及内存优化。

系统启动速度好理解,做快启一般思路就是把一些没必要的初始化给它去掉,然后就是提高数据传输速率。

内核裁剪主要是应对一些flash容量比较小的场景,主要也是把一些内核功能去掉,只留下必要的。

内存优化就比较复杂,例如有段内存空闲,内核没使用,怎么利用起来。某个程序消耗内存太多,也需要优化。