学习嵌入式应该两年了。
第一次接触嵌入式的概念是在大一,我遇到了一个好老师。他给我讲了很多课本之外的知识。
也让我开始了,超越我们同龄人的学习过程。
首先说嵌入式是什么?
如果你从课本上搜概念,大概就是这样以应用为中心,以计算机技术为基础,软硬件可裁剪,等等之类的
书本化的概念。即便你背过了,你也不会真的理解。
那么,如果我来说说呢?
嵌入式是一个很大的概念,小从单片机,51,avr,大到arm,cortex,只要是将mcu用于工业控制并形成专用的系统
的都可以说是嵌入式。这就是以应用为中心。
那么,嵌入式的开发呢?显而易见,编程。所谓的嵌入式开发大部分都要与代码打交道,如何实现该系统的实时控制,
如何实现这个功能,那个功能,都是需要我们要么编程,要么移植代码。这就是以计算机技术为基础。因为我们的开发
是离不开电脑的。
那么软硬件可裁剪呢?以arm为硬件,linux为软件。如果我需要制作一个有用户交互的系统(也就是用户可以输入命令,可以显示信息的系统)
我们需要什么呢?首先我们需要一个最精简的操作系统。也就是什么驱动都没有的纯净版linux,接着就要添加我们所需要的功能了。
我们需要像用户显示信息,OK需要液晶屏。我们需要用户输入命令,或者通过屏幕来进行操作。那么我们就需要键盘驱动,需要触摸屏控制器驱动。
如果我们需要有语音提示,那么就要有声卡驱动。
可是如果有一天老板说了,声音提示我们没什么用,我们不需要了,那么怎么办呢?裁剪掉。前半部分说的是增加,后半部分说的是减少。这样我们就
对软硬件可裁剪有一个直观的了解了。软硬件的可裁剪让我可以把系统的成本降得更低,不需要的功能完全没必要添加。这样我就需要更小的内存空间,
更低的系统配置要求,同时成本也可以控制在很低的范围。
对于系统的可裁剪性,开源的linux 比起不开源的wince无疑具有更强大的优势,这也是嵌入式领域,linux更广泛的原因之一,linux可裁剪性更好。
刚才说的是概念,那么具体我们来说一说怎么学习。
学习任何一项技术,我们都应该从基础开始。
那么嵌入式的基础是什么呢?(因为我学的是arm9,linux。所以接下来我只说linux。)
嵌入式最基础的知识是linux系统的了解和操作。你可以选任意的一个操作系统。可以是早期的redhat,晚一点的fedora
更新的ubuntu,都没有关系,因为他们只linux的不同桌面版本,他们的内核是一致的。对系统的基本操作也是一致的。
最基础的就是从命令开始,如何查看ls,如何复制cp,如何删除rm,如何压缩解压tar。如何修改网络ifconfig。
学习命令的过程不是简单的记忆命令,而是要发散出去这个命令牵扯出了关于linux怎样的知识。
以ls为例,
ls有一个参数是-l是显示该目录下文件的所有属性。
显示出了所有的属性,你就要知道他的属性都代表什么。比如如下的例子
lrwxrwxrwx 1 root root 。。。。。。。第一个字母代表的是链接文件,后面是他的文件属性可写可读可执行可写可读可执行可写可读可执行。
为什么有三个呢?因为有文件所有者权限,该用户群组内权限,组外用户权限。看到这里你就对linux下的文件管理有了一个更深层次的了解。
所以在第一步熟悉linux操作系统的时候要发散出来看。遇到问题要懂得自己在网上寻找答案。
这里就不得不说一个搜商的问题了。
学一个东西,一定要遇到问题的。只有遇到问题你并且解决了,你才真正得到了进步。因为你解决问题的过程是你进步最快的时候。遇到问题了
要学会找关键字,学会看相关网页。你再解决问题中会看海量的信息,这些可能对你眼下的问题没什么帮助,但是另一方面他拓宽了你的知识面,
你的眼界。
刚开始遇到问题,总会立刻就去问别人。其实这是个非常不好的习惯,你要先试着自己解决,先在网上搜索,搜索相关的解决方法并尝试,解决不了
再去请教别人,并把你的尝试过程告诉他,增加他对你问题的理解。就像你在论坛上问问题。一定要把你的出错过程,解决问题的尝试过程贴出来,这样
才会有高手愿意帮你解答,因为你努力了。
如果这一步你走过了(万事开头难。)
那么就该进行下一步了。交叉编译环境的建立。
为什么要建立交叉编译环境呢?因为我们所要开发的是硬件是arm,而我们电脑室x86.我想等到以后arm更加的发展,arm架构的pc机出现的话,可能这一步就可以省略了。
当然这是个憧憬。(好像已经出现了arm架构的pc机了)
我们的arm硬件上没有足够的资源可以编译我们要开发的软件。比如内存不够,主频很慢。自然我们需要在pc机上进行开发了。那么怎么让他在arm上运行呢?
用交叉编译器进行编译编译成arm版本。
当你把交叉编译环境也建立好了。接着我们就该动手编一编软件了。
在我们独立进行代码编写的时候我们不得不要进行的一步就是移植。你去书店里,看一看,随便找一本arm嵌入式开发的书籍,大概有1/4的部分在讲移植。可见移植的重要性。
什么是移植呢?我们为什么要进行移植呢?
移植是一个非常偷懒的办法。他不要我们自己从头来编写代码。而是把别人编写好的代码通过一定的修改,改变成我们可以使用的代码,大大提高了我们程序的开发效率。
这点也不得不感谢linux的开源精神。当然我们的程序也要遵循GPL。
接着回答第二个问题,我们要移植什么,肯定是从应用角度来考虑的。比如我现在需要网络功能,我就必须要添加网卡驱动,而大部分的网卡驱动都是写好的了,我只需要根据我的硬件的特点进行修改就可以了。在我们学生阶段,进行移植。一是为了学习一个项目的开发过程,以及解决在我们移植过程中遇到的问题,以此增加我们的经验和解决问题的能力。第二点是我们经常忽略的就是读一读我们移植的代码,我们移植的大部分都是驱动程序。而驱动程序的写法也是有据可循的,在移植的过程中读一读我们移植的代码,对我们的编程能力是非常有好处的。
说清楚出了移植,我们就要具体的操作了。
首先我们要有一个硬件,网上很多卖开发板的店家,无论是mini2440,tq2440,qq2440,fl2440都无所谓,只要有一款硬件就行。我研究过他们几家的电路图
都是以s3c2440作为核心,电路图基本相同。
我们第一步要做的是搭建平台。开发板上的平台分为几部分呢?三部分,bootloader 、kernel、rootfs。这三部分也是我们学习的先后过程。
我们接触到的第一部分就是bootloader。开机运行的第一段程序,就类型于pc机上的bios。
对于s3c2440来说,有两款bootloader一是专用的三星公司开发的vivi另外一款是更加通用的uboot。
我们要学习的不光是他如何烧写内核,如何烧写文件系统(这些命令)。正如我一直强调的学东西发散出去。我们在使用printenv这个命令查看环境变量时,要搞明白他环境变量的意思,都代表什么、用mtd查看开发板分区的时候,要问问自己为什么这么分区。如果做到这样对于bootloader的学习就很透彻了。
第二步就是kernel内核了。我们要做的是移植内核就类似于我们给自己的电脑装系统似的。但是比他要复杂的多。
我们要修改机器码。修改架构,修改编译器。修改nandfalsh驱动。这时候你就会发现bootloader的作用了。因为机器码和nandflash驱动都要求跟开发板的机器码和分区信息一致。这时候你就要在开发板上输入相应的命令,查看所需信息了。(这里你可以参考我的博客自己在目录里找一找)
等把需要修改的都改完了,烧写到板子里验证一下。
在这里有一个大家需要注意的地方就是唯一变量法。因为bootloader我们是不动的,所以现在的变量有两个,kernel和rootfs。最开始的时候千万不要两个都自己做,一起验证。
这样你会分不清究竟是哪里出了问题,增加解决问题的难度,做内核的话,用开发板自带的文件系统。
验证板子可以启动,ok,恭喜你内核的移植成功了。你也迈出了在嵌入式的第一步,很有意义的一步。不过别急,这里还有别的工作要做。
在来说一个概念吧,arm的最小系统。
提起最小系统,我们在单片机的时候早就接触过,不就是复位,下载,电源,时钟电路吗?对于arm这些是不够的,因为我们是要应用的以上四部分对于51的开发是足够的,对于arm远远不够。
arm的最小系统除了以上的几部分还有三个口,串口,u口,网口。串口用于终端命令交互,u口用于内核文件系统的下载,网口用于大文件的传输,或者告诉的传输,为了可以更方便的开发。
如果你内核移植成功了,我可以说你嵌入式的学习入门了。可是不久你就回发现,嵌入式的开发太麻烦了。每次都要下载很麻烦,尤其是对应用程序进行开发的时候。于是便有人解决了这个问题,nfs挂载(network filesystem 大概是这个吧)网路文件系统挂载,他可以通过网线实现文件的快速传输,在你以后的开发中是非常有帮助。要使用它
还需要过一关网卡的移植
我们常用的网卡有两中dm9000 和cs8900这两种的移植问档很多,大家搜索者去努力吧。不要怕遇到问题,要知道不遇到问题是学不到东西的。
网卡移植完了以后,你更贪心了。我想要有用户交互。那么液晶屏,触摸屏,usb键盘。恩,这些是个不错的选择啊。然后再加油吧。等到,你把这一切做完了。开发板可以回应你的操作了,这成就感一定是无可比拟的。
这些都做完了。开始第三部分吧
制作根文件系统。
首先你要了解根文件系统是什么,要哪几种,目前最常用的yaffs2,为什么呢?因为yaffs2对大的存储器支持更换,这在存储器日益发展的今天无疑是个巨大的优势。而其他的文件系统也有各自的应用市场,他们为什么没有被淘汰呢?肯定也是有他们独特的优势。所以了解他们,这对拓宽你的眼界很有帮助。
至于怎么做文件系统,看看博主们的博客吧,写的都很详细。在制作的时候你会发现,不过那个博主写的,他的目录都是那么几个,名字都是一样的,这是因为文件系统是遵循一个文件系统制作协议的,这些都是规定好的。对于哪个文件目录是什么作用,里面装什么文件都是规定好的。我想这些知识你在最开始学习linux操作系统的时候应该会接触一些。
另一个要注意的就是你在制作根文件系统过程中书写的那些脚本文件比如fstab inittble rsS。。。里面的脚本命令。弄明白他们的意思,这也是很重要的,如果这些你都做完了,恭喜你,你终于完成了嵌入式学习的初级阶段,之后再跟别人讨论技术时,自己就可以说的不那么水了。
这时候算一个总结,你需要自己给自己一个项目区完成它。从最基础的搭建环境开始。一方面可以复习你以前做过的,学过的知识。另一方面可以增加你对整个项目全局的把握,从宏观上对嵌入式有个清醒的认识。
以上可以说囊括了几乎所有嵌入式开发中的过程,当然还有一个。
移植bootloader,在你学习的第二个阶段。就该去深入的了解bootloader以及内核的组织结构和启动过程了。
bootloader的移植,跟内核的移植一样,都是很制式。第一步做什么,第二步做什么。找个开发文档,我相信以你前段学习的经验,bootloader的移植你可以很快做成功。
不过现阶段,你要关注的不再是他好不好使了。你要思考更深层次的问题了。他为什么好使?他是怎么好使的?也就是他的运行过程,以及他的编译过程。这两个问题使你可以更深层次的了解bootloader,也可以真正的将软件和硬件联系起来。对于内核同样如此。,越熟悉内核的人,在嵌入式的开发中也最难得。
接下来就涉及到真正的编程了。以上说了这么多,不管是移植还是制作根文件系统,你仔细想想,你是从没有自己编写过代码的。
接下来就到了考验编程能力的时候了。经常前面那么长时间的学习(不编代码),对c语言也好c++ 也好,一定生疏了。这个时候想看一编编程语言吧,熟悉一下。
接下来的编程主要就有两种了。趋向于硬件的驱动程序,还是趋向于软件的应用程序。
这里算是一个抉择,你选择哪一个,就踏实的去学习。这里推荐一下,入门的时候你可以看看视频这样入门会比较简单,比如国嵌的。后期就自己查书了。这样效率最高。
当然这只是我学习嵌入式这两年的时间的一些想法。除了我所做过,所提到的这些。关于嵌入式还有很多别的东西,比如数据库,比如QT,GTK界面,等等包罗万象。
这里只是将我的学习经历说一说,希望给大家有些帮助。可以使大家对迷茫的嵌入式学习多一些清晰。