怎样自学嵌入式LINUX?

对于嵌入式Linux项目的开发,主要包含以下的知识点:

1.数据输入/输出的接口 – 嵌入式Linux驱动开发

2.数据运行的平台和支持环境 – uboot开发,Linux内核裁剪,文件系统移植

3.数据处理和转换 – 嵌入式应用层开发

如果继续细分下来,就要包含以下工作:

嵌入式Linux驱动开发又分为

1.对于外部设备的硬件实际操作和调试(这部分和单片机时相通的),包含SPI,I2C,ETH,HDMI, CMOS等

2.Linux实现驱动模块的API接口(包含基础的Module_xxx的函数,还有添加类,设备的接口函数以及引申的虚拟总线接口)

3.为解决驱动代码冗余的设备树相关知识和解析设备树的代码实现

uboot开发,Linux内核裁剪,文件系统移植

1.uboot主要涉及嵌入式裸机的应用开发,非原厂人员基本不会修改,顶多修改下logo,或者加些简单的控制, 基本不会去在uboot中实现复杂应用。

2.Linux内核裁剪,我所接触的就是Menuconfig内的配置删减功能,以及将驱动模块添加到内核的实现,更复杂的我没有涉及过,不发表看法

3.文件系统移植,主流的是移植支持QT或者安卓的环境到平台中,当然无界面的应用使用最小系统也能满足需求, 已经在此基础上移植支持的基础lib,启动文件,指令文件和目录等,更复杂的我也没有涉及

嵌入式应用层开发

嵌入式的应用层是具体实现功能的部分,主要包含

1.使用open,write,read,ioctl等对底层硬件信息的操作(包含接收,发送)

2.基于系统接口的对于命令行信息,进程和线程,socket通讯接口(TCP/UDP), 同步机制(互斥锁,自旋锁,管道,消息队列等), 文件I/O等基础Linux API处理

3.基于上述接口实现的上层应用实现,如基于TCP的网络应用HTTP或MQTT,视频应用RTMP,以及为了功能需求而引入的线程或进程机制,而为了满足复杂应用的需求,线程或进程间同步机制也被使用,此外可能会引入Sqlite用于数据的管理,引入openssl用于数据的加密,这些都是应用层开发常用的技术手段,嵌入式Linux比单片机的最大优点就是有很多拿来即用的方案,十分方便应用层的功能开发。

4.为了满足工业界面化需求引入的界面实现方案,目前嵌入式的主流就两大类QT/C++和Android/Java(为了满足Jave对底层的操作,引入了JNI的实现)

了解到这里,你大概对嵌入式Linux的项目整体有了认知,下面标些重点:

  1. 嵌入式Linux驱动中驱动层相关的API接口,DTS语法这些都是从业者必须掌握的技术,如果你想从事驱动层的开发,这部分是必须去理解掌握的,那么从业中一般人和资深者最大的区别是什么,对于硬件的调试经验,如何I2C或SPI数据不通,如何快速区分是软件还是硬件问题(器件问题还是电路问题),并有可行的方法去解决,这才是最重要的技巧, 涉及硬件的调试经验是你买块开发板去学习最难掌握的事,这种就是纯项目经验。

  2. uboot开发,Linux内核裁剪,文件系统移植,这部分我很难给出经验,一方面这方面在工作中占比不高(从我的开发经验来说),另一方面这部分其实都是按照教程在走流程(包括实际开发中,很多也是按照官方的方案走流程),非原厂的很少去理解这部分内部的实现,不过我认为这是合理的,这三块都是这个世界上最优秀的那一批工程师多年积累的,如果一般人都能快速吃透,那个人一定是天才,我是做不到,这部分的源码很多是精华,但我不推荐入门者去啃这部分,能够编译构建个满足需求的环境就够了,如果真想去学习,等经验丰富想提升在去花时间会更快捷且有用。

  3. 嵌入式应用层开发, 对于项目来说,主要关注的其实就是驱动和应用两块,其中应用又是具体的实现部分,往往也是需要掌握的核心(事实上,很多公司购买的测试方案板基本都包含了所有的需要的外设驱动和实现, 顶多改下pin脚或者将接口更换下,或者外部器件更换,修改些寄存器的配置,非原厂和方案商,驱动开发在工作中占比很少), 我上面提到了应用基本在现实的产品都有运用,而且应用层目前已经开始向桌面或移动端的应用靠拢,除了对底层硬件的直接操作外,其运用的语言包含C(Linux API), C++, Python, nodejs, Java以应对图形界面,网络web,算法等的多方面需求,事实上,这里很多实现真的在桌面端的Linux中进行执行完全没有问题,而且跑的更快,调试也更方便,我自己实现的很多代码,都是在WSL或者虚拟机里运行,涉及硬件的话包装成数据包测试的,都是验证完功能后在交叉编译到嵌入式平台测试,效果也基本一样。

讲完了这些,应该基本对嵌入式Linux到底做什么,什么是重点又一定认识了,下面真正开始分享我的学习方法了。

  1. 熟悉Linux平台的常用指令,顺便熟悉vim的用法

我列举些常用的sudo,ls,vim/vi, ifconfig, clear, chmod, mkdir, cp, tar, cat等

  1. 熟悉交叉编译的相关知识,包含基础Makefile的理解,入门不要花费大量时间去掌握Makefile的语法,这里推荐文档<跟我一起写Makefile.pdf>, 初期理解前三章,后面根据经验总结在去同步掌握。

这两部分必须掌握,至少是熟悉,只有这样才不会托后面的进度。

下面开始选择主要学习的方向,驱动层还是应用层,和大多数培训机构或者开发板的厂商按照驱动动辄几十章来说,我更倾向于应用层的开发,同时兼顾对底层驱动的开发调试,这当然和我自身的从业经历有关,我更偏向于工作上用的到的技术,当然这并不是底层不重要,当给你一块完整经过测试的开发板时,很多底层硬件的调试经验也就剩下驱动软件的开发(很可能都不会自己去实现一遍,只是同一套代码编译在跑一遍),很多为什么这样设计的思想也就理解不了,在这种情况下,重复花大量时间是不明智的,当然无论最后选择驱动层还是应用层,入门都不建议在uboot,内核或者文件系统花大量时间,能够搭建满足需求的稳定平台就够了,初期不要去深究,不是因为这部分不重要,而是因为当你对嵌入式Linux都一知半解的时候,去啃其中最复杂的部分不是事倍功半吗,等开发经验丰富,自然会总结类似的设计思想,在回过头过来去学习,那时也能有自己学习方法,事半功倍。

3.对于应用层,怎么学习就有的说了,既有python,node这样环境的移植,又有sqlite数据库,openssl加密算法,opencv图像处理库,mqtt这种通讯应用的移植,还有建立在这些移植的库和应用基础上的功能应用需求,界面的开发,因为涉及行业的不同,往往需要的技术也不同,不过需要的也基本就是上面提到的知识,这些知识基本上和桌面端开发并没有太大的区别(事实上很多代码使用桌面端编译工具重新编译下,就可以直接执行,所以没有开发板完全可以学习), 这里主要提一点,关于Linux API是其中比较需要系统去学习的,我也在整理这方面的知识和demo方案,分享如下:

另外对于如何学习这部分内容,我个人认为我一年前所说的方法仍然是合适的:

不过一年前我关注的是用需求学习嵌入式可以更加快速的学习嵌入式,但是现在我更关注的是通过整个应用的实现,可以系统的掌握嵌入式整个产品的开发流程,这也是我在这行业走了几年后获取的最重要的经验,很多时候嵌入式产品并没有那么复杂,而学习嵌入式Linux同样。对与过来人来说,Linux操作系统和uboot那块是精华,这本身没错,我目前偶尔也在去深入学习了解那部分的代码,但对于入门者来说,特别是为了踏入行业,找份工作的入门学习者,这部分是和实际产品开发脱钩的,或者其中很小的一部分,如果初入门就扎入茫茫的Linux内核代码和驱动应用中,不仅体验十分差,对于找到工作的帮助也没有那么大。

我遇到很多提升非常快的人,都是工作中为解决实际问题而去针对性学习和提升的,而我说的学习方法也同样如此,把学习当作工作目的去对待,当你转变思想后,自然就会去思考如何做,会去检索查资料,会去设计软件实现,也就自然去琢磨如何学才能够实现,会在遇到问题时去从整体方面去思考解决,这不仅是嵌入式Linux的学习思路,也是工作中去实现需求,解决问题的思路。

另外,如果你只想从事嵌入式Linux开发,单片机不学也影响不大,他们共通点也就只有对硬件底层的实际操作是一致的,但这部分技术选择Linux学习还是单片机学习在我看来并没有太大区别,不过如果你不熟悉软硬件联调,用单片机过渡下也可以,最后我分享一个我自己正在实现的嵌入式方案,你可以考虑实现其中的一部分,自然就知道我所说的方法的含义。

你可能感兴趣的:(linux,驱动开发,运维)