怎样学习嵌入式?先来了解嵌入式系统学习的框架
怎样学习嵌入式?先来了解嵌入式系统学习的框架
学习嵌入式必须掌握一定的方法,才能比较快速有效的学习。这个方法就是框架学习法,如前所述,首先在了解这个基础框架之前我们要有一定的基础,那么这个基础就是单片机和 C 语言,不需要掌握的有多好,但一定要具备一定的 C 语言编程能力。像其他有些课程,比如计算机专业课程中的编译原理、数据结构,计算机系统体系结构,这些知识实际上还不太需要,了解一下就可以了。
有了 C 语言编程基础,并且学过单片机,这个时候就可以学习一下嵌入式 Linux 的基本框架了,很简单,那就是首先要搞清楚什么是 BootLoader、Linux 内核(kernel)、和文件系统,接下来简单介绍一下。
什么是 BootLoader 呢?
实际上它是个引导程序,也就是硬件复位以后第一个要执行的程序,它主要工作就是初始化操作系统运行的环境,比如说内存、定时器、缓冲器等,当这个工作做完以后,再把操作系统的代码加载到内存,然后操作系统就可以启动并执行,到此为止,bootloader 的任务就完成了。
那么有人问了,没有 bootloader 行不行呢,可以!但是因为操作系统本身一般是个通用的软件,它要在不同的平台上运行,比如 X86,ARM,POWERPC 等等,而不同的处理器的初始化操作是不同的,如果操作系统的软硬要考虑在启动时候各种平台的差异性,那就显得过于复杂。除此之外,也有其他方面的原因,比如烧写系统的便捷性考虑等等,这里暂不做深入的探讨。
常用的 bootloder 有很多种,比如 U-BOOT、REDBOOT、LILO 等等,我们开发板用的是 Uboot。
什么是 Kernel 呢?
Kernel 就是 Linux 的内核,也就是说 Linux 操作系统本身的代码。那么 U-BOOT 启动到最后,就是把它加载到内存,并且跳转到 Kernel 来执行。
什么是文件系统呢?
现在我们来介绍一下文件系统,这里需要了解一个事实,就是说 Linux 启动到最后一定要挂载一个文件系统。这个是 Linux 的一个特点,它不像其他操作系统,比如像 VxWorks,是不需要文件系统的,VxWORKS没有文件系统也可以运行。 而且还需要了解一点,像 QT 系统、Android、以及 Ubuntu 系统它们的底层都是 Linux 内核,不同的是它们的文件系统不一样,也就是说,Android 系统相关的一些代码,比如说图形界面系统、Android 的虚拟机,Android 的框架代码都在 Linux 最后挂的文件系统里面。 如果大家理解了这点,那么这几个系统的基本架构也就清楚了。
搞清楚了这几个概念,实际我们就了解了 Linux 系统最基本的框架,然后我们根据开发板配套的资料,去学习如何编译这几个文件,因为像 Uboot、Kernel、文件系统,最后编译生成出来分别是一个独立的文件,就是说会生成三个文件,最后我们要学会把这几个文件烧写到板子上。
学会了编译和烧写,接下来呢,我们在这个框架的基础上,去学习如何做 Linux 上面的应用程序。
什么是应用程序(APP)呢?
它是运行在操作系统上面,通过调用操作系统的资源去工作,是最终的业务逻辑,比如我们 Windows 上面有很多的应用程序,像 QQ、暴风影音、WORD、EXEL 等,各种各样 APP有很多。
根据我们后期的视频教程,大家应该很快就能学会,比如说串口程序、网络程序等等,这些都是应用程序,我们不需要做太多,学习几个加深一下对框架的认识就可以了。
再接下来,我们就需要学习 Linux 驱动方面的一些知识了,这也是在基础框架里面的,驱动程序可以看成是操作系统的一部分,它在底层专门和硬件打交道。那么大家稍微了解一下,就会知道 Linux 的驱动包括有三种:字符设备、块设备以及网络设备。
这个时候呢,大家要注意,只需要学习字符类设备驱动,其他两种先不要去花时间研究。一定要记住,最初学习嵌入式技术的时候不要去研究块设备和网络设备。也就是说,把字符类设备搞明白就可以了。因为一般的公司开发嵌入式的产品仅限于字符设备的开发,掌握字符设备的框架思想和开发步骤就能够胜任了。至于块设备和网络设备,直接用开发板或者某个开发平台本身提供的驱动就足够了,这些是一线处理器厂家做的事情,一般情况下不需要我们去完成,这些处理器研发的厂家在为处理器开发配套 BSP 的时候才会涉及这些工作。
当然了,有的同学可能会说,某某公司就是在做块设备驱动,我的意思是讲,从嵌入式这个行业总体上来讲,大多数公司都不需要那么做,很多技术往往是直接拿来用的。我们掌握了字符设备驱动的开发方法,已经能够应付大多数公司的开发要求,对于一个还没有入门的学生来讲,一定要按照我说的办法来学习。等将来熟练掌握基本技能以后,可以根据框架学习的方法,再去研究更深入的编程。这个时候,那些计算机专业的课程,比如数据结构、计算机系统体系结构、各种算法等等就可以派上用场了,自己的水平也会在学习的过程中再次升华。
学习字符类设备驱动,请跟着迅为的视频去学习 LED 的驱动编写方法,以及蜂鸣器、AD 转换等这些跟 GPIO 相关的驱动开发技巧。掌握了这些,可以讲,我们已经成为了一个比较合格的嵌入式驱动工程师!
这个时候我进一步介绍一下什么是快速原型,如果学过软件工程的话,那么大家会听说过一种自顶向下的产品开发方法,这个方法很有效,多数产品的开发方法都是遵循这个思想,大概就是从最初的可行性分析,然后概要设计、详细设计、编码、测试等等。
除此之外呢,还有一种开发方法就是‘快速原型’,这个是微软采用的一种方法,简而言之呢,快速原型是个逐渐迭代的方法,就是说让产品尽快把雏形开发出来,然后逐渐清晰,一步步走向成熟。在这里我们把快速原型法用到学习上,它原来是种开发方法,我们这里借鉴过来,借鉴到框架学习的思想上。也就是说,我们掌握一定的基础以后,就要去学习框架,当这个基础框架清晰以后,再去学习更新更深入的框架知识,这样一环套一环,环环相扣,最终研究越来越深入,进而成为这个行业的专家。
那么在嵌入式行业的工程师的职位其实也是这个样子的,大家看一下:
基本数字电路 + C 语言 + 基础框架知识 -----> 嵌入式驱动工程师
数据结构+编译原理 ------> 高级嵌入式驱动工程师
计算机系统体系结构 + 操作系统(从抽象到具体)-------> 系统架构工程师
因为在第一个阶段,你会发现,只要熟练掌握 C 语言,有良好的编程功底就够了,在工作的时候很少涉及到编译原理、数据结构这些方面的知识,那么很多其他专业的毕业生,甚至原来学机械设计的同学都可以成为嵌入式驱动工程师。
实际也是这样,在大多数嵌入式技术公司,尤其是应用产品开发的公司,只要了解基本的 Linux 架构的知识,并且能够编写字符类的驱动程序就够了。因为像网络设备驱动以及块设备驱动,基本都有个 DEMO 设计,只要参考这个 DEMO 做就可以,根本不需要我们做什么,如果说需要做的话,那也是改一下 GPIO 的设置,修改一下中断的引脚,仅此而已。
那么深入学习的话,分析操作系统源码的时候就会发现,数据结构的知识逐渐排上用场,尤其是在某些专业公司,负责某个专用领域的时候,工作中可能会改写操作系统的某部分代码,来适应他们自己硬件的各种情况,将会深入分析某方面的技术,比如文件系统、网络协议等,这个时候数据结构等方面知识就显得很重要了。
有了基础的原型以后,通过继续学习新的知识,逐渐使自己的认识提高一个层次,更精深的了解嵌入式技术,同时知识体系更加完备,可以做更高层次的工作了。
应用这样的学习方法,在学习过程中,也会使学习过程始终有目标,而不会感觉枯燥,每天都会有成就感,从一开始就能抓住嵌入式系统的脉络,只要付诸努力,持久学习下去,就能成为嵌入式行业的专家。
最后我们总结下,要想比较快的掌握嵌入式技术,要应用框架学习的方法,在一定的知识基础上就开始学习基础的框架知识,这样就很容易入门,随着开发经验的积累,再去学更深入的基础知识,以及更深层次的框架知识。这样相互迭代,直到能够精通嵌入式技术。
这个方法也充分说明计算机科学是门实验科学。那么在学习过程中,要注意,不用学习过多的基础知识,也就是说有了 C 语言和单片机的基础就可以学习嵌入式的基本框架,然后就能够成为一个合格的嵌入式工程师;以后可以继续深造,学习数据结构编译原理操作系统等方面的知识,并深入学习算法,从而再去学习 Linux 更深层次的框架结构,使得整体水平得到进一步的升华。
现在我们总结一下,把学习嵌入式技术的路线图跟大家澄清一下,那就是:
单片机 + C 语言 -----> 学习基础框架知识(包括 bootloader,Linux 内核、文件系统的编译和烧写 ----->再去学习 Linux 上层应用的编程,以及字符设备的驱动,学完以后就会觉得入门了,能做一些事情了-----> 最后深入学习计算机系统结构、数据结构、操作系统原理等等一些知识,通过分析 Linux 系统源码,直到熟练掌握嵌入式编程技术。
框架学习法视频讲解:https://www.bilibili.com/video/BV1HE411w7by