对于一个优秀的嵌入式Linux开发工程师,需要了解的知识可能涉及计算机领域的各方面, 大致思考下就可以罗列很多知识点: - Linux环境下的Bash语法(ls, cd, tar, ps等), Makefile的推导规则,交叉编译环境的构建
- 汇编语言,C/C++语言编程能力,根据实际项目需要可能还会用到java,js等。
- ARM底层硬件知识,包含(GPIO, I2C, SPI, PWM, PWM等硬件配置), 以及配合的传感器,FLASH, WIFI/4G/蓝牙,LCD等外挂设备。
- 嵌入式Uboot的功能开发,如底层驱动的裸机实现,应用功能的实现。
- 嵌入式Linux平台的内核驱动开发,包含内核API,驱动的实现框架,设备树DTS语法,设备树应用,内核裁剪和编译的机制。
- Linux系统层的API(open, read, write, pthread, setenv等)接口和应用开发
- 多线程和多进程的应用功能开发,包含线程创建,删除,同步,互斥锁,信号量,消息队列等。
- 通讯协议的掌握(包含TCP/IP. Modbus,BLE, 厂商自定义协议-如AT,开发者自定义协议的掌握)
- 应用层功能逻辑开发开发,如硬件操作,数据管理,界面开发能力(Linux平台使用QT/C++, Android平台使用Java), 第一种在工控,医疗领域还是主流,但随着SOC的性能快速提升,Android目前逐渐占据主流,此外,因为C/C++本身语言在特殊场景,如Web服务的羸弱,可能会引入中间层的处理,如node。
对于上面的知识点,如果已经了解掌握,或者了解掌握了大半部分,那么本篇也就博君一乐了,当然对上述知识一知半解,认为嵌入式Linux十分困难,那么你的想法其实是十分正确的,因为其中每项都不是一两本书讲清楚的,就举几个我看过的书籍的例子: - Bash语法: 《鸟哥的私房菜基础篇》, 《Linux命令行与shell脚本编程大全》
- C语言: 《C primer plus》, 《C专家编程》,《C缺陷和陷阱》
- C++语言: 《C++ primer plus, 深入理解C++11》, 《C++编程新思维》
- 协议: 《TCP/IP协议卷一》, 《嵌入式网络那些事》,《HTTP权威指南》
- 驱动开发:《 Linux设备驱动开发详解:基于最新的Linux 4.0内核》
- Linux系统层API:《UNIX 环境高级编程》
- QT/C++: 《QT5开发及实例》, 《QT高级编程》
- Java:《Java权威指南》,《Effective Java》
还只是我曾经阅读过嵌入式Linux开发中相关书籍中的一部分,大致扫下就可以发现每一本都是大部头,如果在初始阶段时去深入钻研上面提到的知识点,按照上面的书去学习嵌入式Linux,那么恭喜你,找到了嵌入式Linux--入门到放弃的方法。从我的经历,以及我认识的行业里面的开发者,技术都是通过大学生竞赛或者工作项目总结出来的,往往提升最快的时候就是在项目的完成过程中,当然在这其中也涉及各种技术书籍和资料的学习,这是自己的内功,但学习不是目的,如何应用才是,转变学习思维为工程思维,这才是我分享的嵌入式Linux的学习方法的核心,这也是我工作这几年的最重要的经验总结,甚至高于上面的所有知识技巧, 学习思维在之前已经点明了, 大致是按照别人推荐的书籍学习,或者按照开发板提供的文档一章一章学习下去,这里当然包含开发板中的实践。 工程思维则是为了应用实践的思维方式,学习为应用服务,对于与当前应用无关的技术可以先跳过,积累一定经验后,在通过开发中积累的经验,结合在过程中整理的资料,最后实际技术和经验的同步提高,这段说的有点抽象,不过下面以一个比较接近实际产品的设计思路去理解什么是工程师思维。 定义一款智能音箱,功能包含语音输出,语音识别,摄像头,屏幕界面显示,触摸控制,手机蓝牙管理,这应该是比较常见的一款产品了,从框架上基本包含嵌入式平台的开发,远端服务器开发,手机APP开发(IOS/安卓)端,因为后两者于嵌入式平台开发无关,所以下面以工程思维分解嵌入式平台的工作: - 芯片的选型,根据成本,性能和需求选择合适的MCU,初步设计硬件的框架(这部分是产品和硬件开发的工作,作为软件只需要了解就可以,不需要掌握), 然后获取官方的资料(包含SOC的配置参数,编译器,方案资源包等),当然有公司提供核心板以及资料的话就更简单了,如果你是购买开发板先作demo方案,那么这一步已经完成了。
- 搭建交叉编译环境和掌握Linux平台开发的技巧,包含虚拟机安装,Linux平台的常用指令了解,环境变量的修改,Vim的运用,为了方便后期调试,可能还要完成ssh,samba等的安装,这一步网上都有教程,而且如果你只是想用起来,不追求理解,按照教程执行从我的角度看来虽然问题一堆,但学习起来并不会有挫败感。
- 前面其实都是准备工作,下面先具体的开发过程中的具体任务:
- 系统平台: uboot, 设备树,内核,文件系统
- 语音输出:音频输出实现驱动和应用
- 语音识别:音频采集驱动和上层应用,网络传输, WIFI模块驱动和上层应用
- 摄像头: CMOS驱动,图像采集、显示应用
- 屏幕界面显示和触摸控制: LCD驱动,触摸芯片驱动,QT界面实现和触摸反馈
- 手机蓝牙管理: 蓝牙模块驱动,数据通讯,应用层具体逻辑
到了这一步,我们其实并不利用到上面我提到的所有知识点,但是到我们对嵌入式Linux开发具体是什么应该有一定概念了,如何配合着这个思路来提高自己呢?这里就涉及到如何为了应用而学习了。 4. 将任务确定为目标,根据目标来学习,这也是其中重要的部分,因为上面每一点展开来讲都是个大工程,而实际项目中往往个人只会负责其中的一部分(因为工作量而不是难度问题), 所以我就从其中我擅长的部分来说明: 系统平台构建是项目的基础: 最简单当然是能够根据官方提供的编译器和资源包,编译能在自己平台运行就够了,更复杂点掌握如何修改硬件驱动,设备树,内核menuconfig,这部分任何书籍和教程都很难教会,需要实践中遇到问题,记录,总结,在这个流程中掌握的。 语音识别中的网络传输: socket通讯一般涉及TCP/IP协议栈,多线程或多进程,异步通讯等知识,其实网络通讯正常时只要使用系统提供的API接口就够了,这些技术是用来分析和处理你开发中出现的异常问题,可能是代码问题,也可能是网络本身的问题,你要根据实际情况去分析。我学习TCP/IP协议不是在看<TCP/IP详解>这本书学会的,而是在查找异常原因,分析WhireShark包时,把书本当成工具时才掌握的。 CMOS驱动:这部分因为我之前参与过支持摄像头采样的芯片开发,负责验证和方案的,所以理解还算深刻,CMOS功能一般分两部分,基于I2C的配置接口,和基于MIPI或DVP的数据输出接口,事实上作为开发者,主要就是通过I2C完成对CMOS的功能配置,就是CMOS驱动开发的主要工作,这部分很多官方开发板也有例程,虽然调试CMOS有难度,但我并不认为单独一项工作是天堑。 因为篇幅已经比较长了,这里就不一一详述各部分的实现了,其实都和上面的类似,每一项都没有难到无从下手的地步,但为什么入门时不得其法,因为把上面的所有实现技术综合列出来,你就会发现基本包含我前面列的需要的知识点,掌握这些知识点后,开发当然会很简单,但在没有掌握的情况下,并不是不能够做产品开发啊,在实践中遇到问题再补充并总结,从我的经验来说,会提升的更加迅速。 为了实践而学习,而不是为了学习而实践,了解这种思想,这正是我分享的嵌入式学习方法。最后,可以通过简单的方法实践这种思路的转变。 定义一款停车场扫码进场设备的需求,功能包含二维码付款(扫码和被扫),车辆检测,车牌检测,后台应用端管理,语音播报,剩余车位显示。去理解这些功能背后实现的技术,针对去学习,就会发现并没有那么困难
|