如果给你这两份 offer,你会选哪个?
首先是 Linux 驱动工程师:
咱们看啊,内核裁剪、驱动开发、设备树、构建文件系统、串口、I2C、SPI 和 摄像头视频编解码适配这些东西。
然后是应用工程师:
主要做 Linux 应用开发,比如 TCP 网络通信、RTSP 推流、音视频的采集、存储、显示。
工作年限的要求和薪资范围也都差不多。
咱们就假设其他待遇条件都一样,那如果是你,你会选哪个?可以先拉到文章底部留言你的答案,再来看后面的内容。
这也是我当年面临的一个选择,我最后选了什么呢?先卖个关子,在这之前,咱们先对齐一下,仔细讨论一下驱动和应用到底有什么区别。
驱动工程师在干什么?
咱们先说驱动工程师,就以摄像头为例。
这是我一个朋友借我的4款摄像头设备。
第一个,用在马路上或者小区、停车场这些地方,它看得比较远,不能换角度。
第二个是门禁,可以做人脸识别,上班打卡开门。
第三、四个用在家里,可以手机实时监控、远程控制 360 度旋转。
由于是朋友借给我的啊,咱们就拆开看一下,这 4 款摄像头主要的核心部件和功能原理都差不多,我们就以一个家用摄像头为例。
一款摄像头最主要的元件有这么几个:
第一个,是镜头:
第二个,就是感光传感器:
摄像头的作用是把现实世界里四面八方到处散射的光,聚焦到一个感光传感器上。
感光传感器也叫 CMOS,它能够感受到光,把光信转换成电信号,我们常常说的 200 万像素、800 万像素,其实说的就是这个感光传感器上有多少个感光点,传感器会把所有的光转化成一个一个有颜色的像素点,形成一帧图像。
第三个,是主芯片 CPU:
它的作用是从感光传感器拿到图像,然后对图像进行一系列处理,做一些业务逻辑,比如把图像保存到本地,或者通过网络传出去。
这个 CPU 是怎么拿到感光传感器的图像呢?
它和感光传感器之间通过几根电线相连,通过这些电线的通电和断电,通电代表 1,不通电代表 0,就形成了数字信号,这些数字信号就是图像数据。
实际上,这些电线分成两组。
一组是控制线,它会读写感光传感器里的寄存器,决定传感器什么时候开始采集图像,什么时候停止采集,还可以设置曝光时间,设置分辨率等等,这些都是通过控制线来完成的。
另一组,是数据线,负责把采集到的图像数据传输给 CPU。
驱动工程师做的事情,主要就是跟这两组电线有关。
他们要阅读芯片使用手册,理解传感器的各个寄存器的功能,然后,基于 Linux 内核,通过控制线设置寄存器操作芯片;通过数据线,读取图像数据。
最终,驱动工程师的工作结果是什么呢?
不是一个硬件产品,而是一系列函数接口,给应用工程师调用,来实现产品功能。
总结一下,驱动工程师的工作输入是硬件资源 + 芯片手册 + Linux 内核,输出是一系列软件函数接口。
应用工程师在干什么?
好,说完了驱动工程师,咱们再说应用工程师,可以这么理解,驱动工程师的工作输出,是应用工程师的输入。
驱动工程师把硬件资源正确地管理起来,提供稳定的接口,应用工程师要调用这些接口,来实现产品功能。
大体来讲,应用工程师要用这些接口读取图像,把图像按一定的标准编码,保存起来,或者通过网络协议发送出去。
至于到底是保存起来还是发送出去,这就要看产品需求了。
所以,应用工程师往往面对的是最终用户的需求,比如用户是想在手机上看到摄像头的画面,还是电脑上看到,还是想把视频保存到本地的存储卡,或者想把视频传到云端,或者用户根本不需要这些视频数据,他只是通过摄像头识别人脸来做一个开门的动作。
这个摄像头是用在家里,还是用在工厂,还是用在路边,白天用还是晚上用,是在固定的位置用,还是可能移动着用,这些都决定了应用工程师要实现什么样的功能。
所以,应用工程师要熟悉操作系统提供的各种接口,比如设计多线程架构并发运行,调用文件系统接口保存数据,调用网络接口收发数据,如果是保存数据,那就要保证这个数据是完整的不丢失;如果是通过网络传输,那就要保证视频数据快速、稳定传输。
除此之外,还要做日志管理、程序远程升级,还要处理各种异常情况,比如网络断了怎么办,设备突然重启了怎么办,存储卡满了怎么办等等。
最后,要让整个设备起来,不是跑十分钟,而是跑个几年都不出问题。
总结一下,应用工程师的工作输入,是驱动工程师提供的读取摄像头数据的函数接口 + 操作系统接口 + 产品需求,输出是一个稳定、功能完善的、直接面向消费者的硬件产品。
应该学什么呢?
ok,说了这么多,那我们应该学什么呢?说回视频开头的那两个 offer,我最终是选了应用工程师的 offer。 为什么呢?主要有三个原因。
好入门
第一,应用工程师的入门门槛更低一些。
这点大家应该也都知道,驱动比较难。
为什么难呢?它这个难啊,不像是那种特别牛逼的算法,像什么深度学习呀、图像处理呀,可能需要好多精通数学物理的博士写论文,然后再依据论文去写代码实现。
驱动不需要写论文去论证的,它的难,在于它的复杂度,牵扯面太广了。
你写一小段代码,背后可能牵扯 Linux 内核、硬件手册、原理图、设备树、总线、中断、DMA、时序等等这些东西,都要理解,才能写出正确的代码。
Linux 内核又复杂又庞大:
硬件手册纯英文的,几千页:
这里面的东西,随便一个知识点,都够你学一阵了。
应用工程师的入门相对来说就简单一些,主要是熟悉一下 Linux 的各种接口,学习操作系统、数据结构、网络协议等等这些内容,将它们综合运用完成产品开发。
虽然一个完善的应用层程序也没那么简单,但当你只负责应用层的一个小模块时,是不用像驱动那样,牵扯到那么复杂的内容的。
岗位多
第二,应用工程师的岗位更多一些。
我把4个摄像头都拆开了,左边3个都是华为海思的芯片:
最右边是海康威视的摄像头,看不出是什么芯片,有可能也是海思,不过芯片上的字写的是海康的,我们当它是海康自己的芯片吧。
海思芯片的驱动程序,主要是海思原厂的驱动工程师来写,其他公司很少有机会去写这个芯片的驱动程序。
这一个厂家的一款芯片生产出来,会被开发成马路摄像头、家用摄像头、门禁摄像头、扫地机器人摄像头、无人机摄像头、行车记录仪等等各种各样的产品,这些产品需求各有不同,都需要应用工程师来开发。
一款芯片的驱动程序,可能是一个几百人的团队写的。而这个驱动程序的用户,是成百上千家公司,成千上万的应用工程师。
所以驱动工程师的岗位需求相对来说就少很多,应用工程师的岗位就多一些。我们做选择,当然是选岗位多的那个了,找到工作的几率更大一些。
贴近用户和市场
第三,我认为应用工程师更贴近用户和市场。
前面说了,驱动代码要按照芯片手册和系统内核的要求来写,这就导致驱动程序的写法更加程式化,基本是按照一个固定的套路来写的,创新的空间比较小。
驱动工程师的工作成果,是一个个函数接口,客户,是应用工程师。所以驱动工程师每天跟寄存器打交道,跟芯片手册打交道,跟 Linux 内核打交道,跟应用工程师打交道,跟最终用户和市场需求是没有什么直接接触的。
而应用工程师的工作成果,是一个个功能完善的产品,客户是最终用户。所以应用工程师每天跟产品需求打交道,他们知道用户需要什么,市场需要什么,真实的世界需要什么。
这也是为什么我觉得应用工程师更适合创业,他们更容易发现用户的痛点,发现市场的机会。
总结
所以我一直不建议大学生一上来就因为“驱动工资高”“驱动听起来牛逼”,然后直接死磕驱动。驱动工资高,是因为门槛高、岗位少,而且通常要有经验,是这几个因素互相叠加造成的。
这条路不是不能走,但牵扯的面儿太广了,风险比较大。
如果你在学校阶段已经做过比较复杂的功能。比如真的移植过板子,调通过复杂的传感器,改过设备树,那你当然可以试一试。
但如果你现连 Linux 多线程、网络、文件 IO、交叉编译、调试都还不熟,一上来就说我要学驱动,我真觉得有点悬。
很可能最后就是竹篮打水一场空,驱动没学明白,应用项目也没做出来。
如果你说你就要做驱动,我建议也等你做应用做了几年,开始真正理解产品链路了,知道应用怎么调用驱动,知道驱动不稳定会带来什么问题。这个时候你再往驱动走,反而更稳。
不过,等你真的做过产品,你会发现,应用并不低端,驱动也不神秘。能把复杂系统做稳定的人,才是真正有价值的工程师。
这几个字很重要啊,把复杂系统做稳定,大家可以心里默念3遍。
OK,文章内容就到这里了,我是科岩。如果觉得对你有帮助、有启发,欢迎给个点赞和转发,我们下期再见!
----------END----------
点击「阅读原文」加入「科岩成果大本营」
跟科岩以及450+营友一起体系化学习
成为 AI 时代更有竞争力的嵌入式工程师!
你好,我是科岩。我做嵌入式工程师十几年了,每当调通一块板子时,都会有满满的成就感。
我将持续分享个人的成长收获,帮助你提升技术能力与认知视野。另外我还听说,关注我的人个个都是人才,一起加油吧,人才们 :)
这是我的个人经历: