admin 管理员组

文章数量: 887021

目录

一.作者:懒懒土拨鼠

第一阶段称为stm32+RTOS阶段。

第二阶段称为多核+Linux阶段。

第三阶段

最后荐书环节

二.作者:程序员良许

转折点

入门

新挑战

Linux应用的学习

1.环境搭建

2.基本操作

3.系统编程

4.网络编程

5.数据库编程

6.Shell编程

Linux应用编程书籍推荐:

三、作者:DiedCode

1,学习单片机:

2,过渡

3,看ucos(非必须)

4,Linux应用编程

把握以下几点:

5,嵌入式Linux

6,单纯的心趣

四、今天又是充满希望的一天

1.1 嵌入式定义

1.2 就业岗位

1.3 学习路线

(1)安装虚拟机和Linux系统。

(2)学会使用Linux常用命令。

(3)学会使用Linux常用工具。

(4)学会编写shell脚本。

(5)学会Linux下C编程。

(6)增强理论知识。

(7)文件系统。

(8)内核裁剪。

(9)驱动开发。

(10)移植bootloader。

五、韦东山

(1)什么人需要学习裸机

(2)以前的视频是从裸机讲起的,现在为什么改了?

嵌入式Linux系统的组成:

要学习bootloader吗?

要学习Linux内核、要学习驱动程序吗

要学习Linux应用程序吗?

应用程序是怎么启动的?要了解一下根文件系统

学习方法

先不要打破砂锅问到底

思路要清晰,不怕抄代码

六、悠悠荡荡我懂等

嵌入式的技能清单和升级线路

第一部分:虚拟机安装和LINUX系统安装

第二部分:嵌入式LINUX环境搭建

第三部分: U-Boot

第四部分:LINUX内核移植

第五部分:LINUX根文件系统

第六部分:LINUX驱动开发

第七部分:Linux 应用学习

第八部分:QT移植与开发

第九部分:无线通讯应用

第十分布:嵌入式系统应用程序,驱动程序调试

七、

下面是在网上找的一些代码经验:

另外还有一些关于调试的经验:

八、嵌入式学习路线和书籍推荐---Codesheep


一.作者:懒懒土拨鼠

 
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

以下是该作者的个人经历经验,供参考。

最近ai爆火,嵌入式作为老旧的技术渐渐式微。但天有不测风云,老美作妖,芯片行业风口,嵌入式可以趁势飞一波。鉴于大佬们都不屑做这种老旧技术,鄙人不才,姑且把自己的招聘道路对嵌入式软件的思考说给各位嵌入式同学,前车之鉴,后事之师。

乐鑫科技(提前批):7.16笔试/挂

选择填空60/编程40,基础题不难,编程题两道算法,这不是为难嵌入式的吗,编程白卷,挂。

联发科(提前批):7.22笔试/7.25一面/挂

嵌入式软件岗。台企做射频芯片,wifi/蓝牙这种,台湾第一,给的不高但有加班费,且大陆接触不到核心技术。笔试C基础选择填空简答翻译/两道编程。编程题是分割字符串,双向链表查找非0节点并打印,现在看很简单,C基础我刷的《王道程序员面试宝典》,选择填空我还行,但是编程当时的我就……交了白卷,时间也是一方面。

一面纯聊项目,并适当引申问一些基础知识,引申了:arm工作模式/静动态链接的区别,最后一个项目我做的机器学习,单纯为发论文那种,没说清楚,估计扣分了。又问非技术问题,和同学如何分工合作,与导师意见不一致怎么办,第一次被问,答的很一般,但也不是说的差。整体感觉聊的还行,可是挂了,群里好多人都是这样,可能是掐尖吧。

汇顶(提前批):7.25直接一面/挂

BSP/驱动岗。先问点iic,spi基础知识,速率,工作模式。然后手撕memcpy,哪搞过这种纯c编程,写的漏洞百出,我自己都看不下去……又问我信号量组织方式,就让你简述,语言没组织好,本身也不熟。果断挂了。BSP方向最喜欢问单片机知识。后来听群里大佬说汇顶给的比联发科还低,他们都拒了……

OPPO(提前批):8.2直接一面/挂

c/c++芯片方向。问哪些课学的不好,急中生智答中特……问哪些学的好,答ARM体系结构。然后被逮住问:7种异常是什么(没答全),中断触发到返回的具体行为(CM3权威指南里有),中断嵌套如何实现(NVIC相关),中断机制的具体实现(还在答中断具体行为,他问的应该是两级向量表如何查找),中断部分结束。

问单片机与嵌入式系统的最大区别在哪里,答嵌入式系统可以跑多任务,然后逮住OS开始问。任务在内存中的组织方式(TCB-用户栈-用户代码),上下文切换时任务在内存中是如何变动,任务调度点,优先级反转如何解决,任务抢占如何发生,通信机制。

问Linux开发驱动的流程,懵逼。又问c知识指针与引用的区别。然后让我自己挑些会的说一说,答了点单指令多数据流,感觉不感兴趣,又说了流水线冲突与解决,反问cache-miss什么情况,分支预测什么原理(高级计算机结构课上内容)。看来芯片方向看重体系结构的知识,课上学的终于有用了。

通过里面的最低分,部门挑简历时没挑我,挂了。这次面试真的在我最擅长的方向被问的一身汗,虽然挂了但是找到下一步需要完善的点,挂的不亏。之后我就把自己的优势定位在ARM体系结构和CPU原理/OS任务切换与调度原理/静态链接知识(这里推荐《程序员的自我修养》)。

诺瓦科技(提前批):7.30笔试/一面/挂

做LED屏解决方案,感觉用的知识不深。笔试考了DMA与中断传输的比较,矩阵键盘检测,计算算法的复杂度,甚至还有稳压电路的知识,做的不好。

面试让画项目框图,画乱了。硬是把我自己独立完成全部软件硬件的四轴飞行器项目说的好像是个假的一样,我特么自己都服我自己。然后问C基础,我答的还行,但已经无法补救。这次面试之后我开始把所有项目叙述和重点问题全部写纸上,每天背一遍。

是的,你没有看错,我提前批5连挂,群里大佬都在讨论去联发科还是汇顶了,我一个菜鸡什么话都插不上,心情和自信都已跌入谷底,真的就已经卑微求offer了……

中兴(正式批):8.11一面/8.13二面/9.1签约洽谈/拒

然后我就迎来了第一个正式批,清水河现场面。此时被鞭打多了也知道点引导话题了。专业面就问项目,问些概念和项目里的知识:什么叫软硬实时,m4内核双堆栈机制,顺便答了arm模式切换和上下文切换,bootloader,链接原理,说我是做了些东西的。一面当天正好成都暴雨,路上积水连车都不敢走,到现场裤子鞋湿透,面试之后正好雨停。回想着专业面被肯定,我有一种感觉,从今日开始我要拨云见日。

二面英文自我介绍,崩,然后问我有offer吗,投华为了吗,然后就反复问我:为啥没投华为,我还是不明白你为什么不投华为。问的我贼气,我不投怎么了。后来在职学姐告诉我,应该答不喜欢华为的文化,两家是竞争关系。

洽谈还是职业规划等老生常谈,他们南京的嵌入式主要是做设备驱动,机顶盒。没有自研芯片,也就是说没多少芯片的核心技术。我还是打算去芯片原厂的。谈薪资就看获奖经历什么的,本科的奖倒是不少,然并卵。说让我考虑,后来拒了。

虽然中兴拒了,但是在刚刚5连挂的时间节点上给了我宝贵的肯定,非常雪中送炭。

大华股份(提前批):7.27笔试/8.14一面/8.18二面/8.24 hr面/9.7意向书/9.18逼签/9.23拒

算法工程化岗。提前准备了一些ucos移植,arm指令集流水线和静态链接的知识,事实证明,准备的方向很对,他很感兴趣。

电话一面,问了ucos移植的细节,提到了一种并发的指令集(没用过),聊聊项目,又聊行业认知,最后问我的优势劣势分别是什么,答优势是对底层原理的理解和对编译器的了解,劣势是不懂Linux。他表示赞同,说我基础不错。信心终于提升一点。

电话二面。上来直接进入正题,自我介绍什么的都没搞,直接问:信号量实现的底层原理,可不可以用一个全局变量代替信号量的计数值,答不可以信号量是临界资源要进临界区,问怎么进临界区,答关中断保存cpsr,他比较满意。

然后问中断机制,大概有多少中断,可修改向量表吗(通常不可,有例外),又问m4内核的双堆栈机制。BL指令的跳转范围(32MB)。

最后问静态链接,深挖强弱符号的东西,最后说我对底层还是比较了解。

hr面就常规,觉得契合与否,1246大小周能不能接受。杭州,6险1金有食堂,后来知道我有其他offer要给我提薪,没让提拒了(因为后来拿到了更合适的)。

大疆:8.16笔试/8.25电话一面/8.28视频二面/9.3感谢信

笔试编程题依然空白,选择填空基本拿满。

一面就问项目,反复问上系统的必要性,估计是个搞os的根本不懂四轴,以前栽过,这次答圆了,又主动答了中断机制,看他不是很感兴趣。最后问我懂不懂os的内存管理,答不懂,之后就是笔试编程为啥不做,答嵌入式对算法只是了解,项目里没用到。

二面感觉和一面没什么区别,还是自我介绍&&项目介绍,把四轴的控制流程说了一遍,他对四轴还是懂一点,但飞控算法没问,难道大疆不该很看重这一块吗,把所有项目大概都问了一遍,无异常。然后问,你的劣势在哪,答不会Linux,又问我图像处理的算法,靠本科上课学的还没忘干净的知识答一点,中位数滤波,边缘滤波,想深问,我说我只是了解。感觉他不很满意。

二面挂了,挂的很不甘心,我的cpu原理知识还没吐出来呢,静态链接也没问,arm这块就问了个中断机制。回来反思为什么引不出自己的优势,感觉自己所答还是很零散,中断就中断,os就os,指令集就指令集,串不起来。后来我找到一种组织的方式,能从中断入手把arm架构,上下文模切换,指令流水和程序优化串起来讲,形成一个模板,只要问到其中某一个知识我就能把全部一串说出来,他感兴趣自然再深问。涨了一波经验,挂的不亏。

寒武纪(提前批):9.3一面/9.6二面/9.11 hr面/拒

上海系统软件工程师。大疆挂面总结来的那套“模板”第一次实战。

一面还是项目,挨个问简历里些写的。IIC与SPI的不同(片选方式,异步同步),IIC读写方向如何区分(地址位最后一位的高或低)看我答出了比较满意,说没几个答对的,驱动确实是我写过的。然后问9轴数据的意义,答了姿态解算中队数据的融合。然后就是双堆栈机制与模式切换,任务调度点与任务在内存中的组织方式(TCB-用户栈-用户代码),优先级反转与解决,死锁的原因,然后makefile语法一个。其他单片机小项目根本没问。看得出对我的回答很满意。然后手撕代码环节,特意找了个最简单的给我,牛客原题链表表示的两数相加,撕半小时,通过率0%……他说会综合考虑。

二面疯狂问CPU知识,“模板”用上了。先问m4 的双堆栈与上下文切换,17个寄存器的功能,LR的作用。顺势答为何中断返回要LR中的值减4,然后指令流水、CPU知识就跟着出来了。又问分支预测发生在指令处理的哪个阶段,cache的作用,回写与写透的区别,为什么设计三级缓存。

然后问信号量,进入临界区的操作,为什么关中断可以保护临界区,cpsr如何保存。

最后问静态链接,预处理是什么编译选项,-g是什么意思,如何使用ar生成库文件,这块不熟,会不会gdb(不会)。那就说说makefile一条指令的格式,.c生成.o什么选项,.o生成.elf什么选项,.o与.elf的区别联系,举个区别的例子。

然后开始讨论行业认知。为什么从事芯片行业,美国制裁华为你怎么看,制程对芯片的影响,为什么中国制造业跟不上。感觉他很感兴趣,当场表示通过。

hr面就个人介绍挖了一下个人学习方法,社团经历,期望薪资等等,我问寒武纪是否加班,是不是1246大小周,她很震惊,不知道1246为何物,并说寒武纪不加班,干完就能走。

寒武纪两位面试官的肯定给了我极大的自信,我也一度很想去,毕竟是国家队的AI四小龙之一,技术实力毋庸置疑,关于为什么没去,在芯原之行之后说。

矽力杰:9.9和主管电话聊/9.18 hr面/9.24拒

南京嵌入式软件岗。做电源模拟IC国内第一,最近几年开始做物联网SoC,在南京计划1年左右上市,使用M0内核和开源协议栈,做解决方案,技术难度倒不特别深,现在射频SoC厂商如雨后春笋一般冒出来,物联网这块看来市场很大,但是我本人不喜欢做物联网。

我的流程非正常,笔试都没写电话聊完直接告诉我很合适很想让我去,态度那叫一个好,hr面也是态度很好,没有丝毫套路。最后问了我目前offer,我说大华和寒武纪还没谈,她说会给我定一个有竞争力的薪资。

最后的薪资真的很有诚意,干的好1-2年给股票,另外还有很高的签字费,承诺绝对不加班,不得已加班给加班费,算下来一年能拿很多对于南京嵌入式来说,还有股票签字费不加班,我心动了。

最后夸一下这个厂,对待人才很有诚意,不像有的公司承诺给一个让你“无法拒绝”的薪资然后白菜的一批,而且真不怎么加班,喜欢物联网的同学可以考虑。

芯原微电子:9.16清水河笔试/9.17一上午5轮面试/9.18通过/9.21 openday洽谈/9.24网签

成都算法工程化岗。笔试题量超大,是一个半小时的量但是只给你一小时,各种智力题和基础知识,涵盖c、os、编译器和cpu知识,很多都是4选1答,只要你在一个方面有深入理解就行。我觉得很基础但是实在写不完。

专业面,npu的人面的也算是缘分。先说项目,直接画个框图给他,说的熟的不能再熟了。然后提问中断机制,这就进入了我的“模板”,然后重点问了流水线效率问题,为什么中断返回PC要减4,拿出试卷让我答没写完的题。然后让结合项目代码分析如何避免流水线冲突(调整指令执行顺序,分支预测,增加部件),还好我顶住了,他们也开始感兴趣了。

然后问静态链接,也是熟的不能再熟的东西。其中一个面试官问我是否想去做编译器,我说只做编译器一个点有点狭窄我还是想着眼于整个系统,后来知道他原来是编译器组的leader。

然后和技术主管聊,当时不知道是npu部门的leader(也是我现在的leader),聊些技术方向,未来期许,职业规划,聊了比较久,他说不错很优秀。

然后英语面,爆炸。问我团队工作中什么最重要,喜欢哪个城市为什么,说了啥不重要,重要看你会不会说英语,显然我不会,估计是C。

hr面套路,优缺点,已有什么offer什么岗位。

CEO面,我宣讲时提了一个比较有深度的问题,他记得我。问为什么芯原做芯片定制而不是直接生产出来再卖,答案是减少积压风险,答错。他宣讲时就说今天要问,还是答错了。

openday,搞了一整天,各条产品线负责人上来宣讲,好困,芯原自研IP核有核心技术,还是不错,npu是前沿技术,部门老大对我也比较看好,于是去了。就是薪资一般,一年涨薪至少10%看绩效,不加班法定节假日3倍工资,周末和晚上加班没有加班费(7点人都走光了)。

回来和我的老师讨论offer问题,芯片行业老师还是最看好华为,可以说是业界第一。中策就是寒武纪、芯原、龙芯中科这种有技术实力但是盈利情况并不很好的国家队公司,下策就是解决方案供提供商,他们的芯片技术自主权十分有限,拿大华来说,他们的图像IP核都是买的华为的,芯原的,寒武纪的,芯原的异构并行npu可以决定哪部分算法调度在哪个核上去跑,怎么从结构上优化网络,但是大华就只能根据我们的文档去应用,我们的嵌入式工程师还要去杭州总部指导他们的工程师,原厂工程师在下游方案提供商那里很吃香的。

在这些IP原厂中,我的老师觉得寒武纪定位不清晰,又做IP又产芯片又做云,现在还搞校企联合,有些浮躁,财报也是大起大落的,目前特别依赖输血。芯原就好一些,只对标企业用户,虽然也在亏损,但是定位清晰,有自己很多市场接受的产品,目前亏损主要是成本太大。但是在这个时间节点上国家肯定会拉高芯片行业,寒武纪还没倒呢芯原怕什么。决定之后寒武纪、大华、矽力杰就都拒了。

我所从事的是内核移植和算法工程化岗,只做设备和驱动前途有限,这方面最后细说。

欢迎学弟学妹来我司从事自主IP核的研发。我司妹子多而且质量高哦。

龙芯中科:9.20一面/二面已签遂拒

北京嵌入式软件岗。龙芯是国产CPU的巅峰,中科院计算所背景,技术是有但是盈利模式没做成熟。介绍项目,老生常谈,叙述中断机制,bootloader,模板开启引出流水线,他竟然没深问。问我会不会gdb,答不会。又问了一个机器学习项目,看我叙述清晰也没再问了(他不懂这块)。问我对工作什么期许,聊聊岗位,已有什么offer什么岗位。看他不怎么问我技术问题我有点急,我直接说我基础很好,所有简历里提到的您随便问,他笑,看你这么自信我就不问了,等二面吧。后来24号签了,也不准备继续了。

最后说一些我对嵌入式技术的见解

        嵌入式作为一种已经存在将近50年的技术,本身是比较老旧的,但这并不代表它会被新的技术所取代,嵌入式系统本身就是微小的计算机系统,只要二进制计算机不过时,嵌入式技术就不会消失。我的老师经常给我们强调“程序员的自我修养”和对底层原理的理解,现在技术更新换代非常快,新框架新风口,但是只要它跑在二进制计算机上,有些东西就是不会变的。所以理解计算机工作的本质,掌握“以不变应万变”的能力在嵌入式编程中尤为重要,“好的程序员对自己程序的每一个比特都了如指掌”。不仅是嵌入式方向,其他技术方向也是如此,着眼于系统才能立于金字塔顶部,在35岁之后避免职业瓶颈。

        吹了一波嵌入式的重要,再谈一点我个人对嵌入式未来的理解。传统嵌入式MCU、os应用编程、驱动开发其实已经很成熟,比如linux驱动就已经有成熟的框架,完全不需要你懂源代码,前景有限(但是也是基本功之一)。未来应是ai的时代,云计算已经比较成熟,但云端所能做的毕竟有限,而且传输问题(可能5G出来会好一点),功耗问题一直没完全解决,阿尔法狗背后有1000台左右的CPU,200台左右的GPU在跑,每小时光电费都要300美元左右,所以ai一直落不了地。对于端级的ai,集成度基本已经到了尽头,目前最先进的制程是5nm,而在1nm的量级将会产生量子效应,也就是说,集成度的极限要到了。集成度上不去直接影响芯片的大小,端级ai不可能像服务器一样搞好大一个主板,目前基本是用异构多核的方式提升计算性能。但是并行计算也有性能的瓶颈,算法中很多情况是下一步计算需要用到上一步的结果,有相关性的,没法并行。这个计算的瓶颈,牵扯到流水线阻塞,cache命中率,IO操作等等,一定是底层架构方面的问题,有我们嵌入式程序员广阔的发展空间。

        第二个热点我觉得是5G相关,这块我不太了解,大致说说。首先是低功耗问题,商用对功耗非常敏感,这肯定和底层系统有关,要裁剪硬件软件。其次就是协议栈了,美国就怕这个才封了华为,由此可见重要程度。

        stm32和51单片机入门自不必说,说些进阶的路线。老师曾给我们仔细设计了一系列挑战任务。

第一阶段称为stm32+RTOS阶段。

任务1:裸板驱动,比如在裸板上点亮LED灯,一般是以stm32为平台,通过汇编代码手动配置最底层的寄存器,完成时钟树、GPIO口的初始化,重点1:理解软件和硬件是如何联系在一起的(地址,宏定义和typedef封装)。重点2:理解汇编语言操作寄存器的过程。重点3:理解启动文件。有人会说,什么年代了还用汇编,直接c实现不更简单。关于c实现更简单我同意,但是我觉得真正想理解硬件就必须在汇编层面上去理解,越深入你越会发现汇编的重要,启动文件可是纯汇编的。推荐野火的《stm32完全开发手册》《ucos-II移植》。正点原子那拼凑出来的辣鸡就不要看了,别问我咋知道的。

任务2:移植一款RTOS并在stm32平台通过两个任务(点灯任务,灭灯任务)实现led的周期闪烁,我所移植的是ucos2。重点1:使用汇编语言手工编写ucos2与stm32硬件平台的接口部分,这一过程将会涉及到对m4内核模式切换、中断系统的运行机制的理解。重点2:理解多任务并发编程。理解ucos2中关于任务组织方式的源代码,理解上下文切换的本质(关于源代码的理解强烈推荐廖勇老师主编的《嵌入式操作系统》,一行一行带你读源码,这本书也已经被我翻的发黑了……吃透够你彻底理解RTOS)。

任务3:在Linux平台上使用makefile的方式完成任务2的源代码的交叉编译。难点1:makefile语法。难点2:理解静态链接的全部原理和ELF可执行文件。预编译、编译、链接、装载的全过程,对编译过程是理解是所有c程序员的自我修养(强烈俞甲子大神的推荐《程序员的自我修养》,读懂静态链接就足够成为面试的亮点,懂动态链接更好但也更复杂),这种修养决定了嵌入式程序员把握大型程序能力的上限。难点3:理解链接文件。各个段的地址可不是随便安排就完事了。这个任务带领我们“惊鸿一瞥"了计算机技术中那些“以不变应万变”的能力中的一个。

任务4:在你的系统中使用一种数学算法,培养知识迁移的能力。你要知道软件只是实现功能(陪跑的),一个嵌入式软件程序员想有所发展必定要和某个特殊领域的算法结合。我所做的是四轴飞行器项目,里面的算法是姿态解算算法和PID控制算法,都不算太难开源的也不少,重点在训练知识迁移的能力。不得不说我数学真的不好,姿态解算里面那个互补滤波我也就懂个大概流程,里面式子为什么那样算那样互补基本不懂,很数学(从此放弃做科研),但是PID必须弄通透。

以上任务不打折扣地做下来怎么说也得一年,何况各位还有各种商业项目缠身,那就更容易分心。对于我一个读研之后才接触OS的菜鸟硕士,对自己要求也没那么高,在研二到这种程度就能找一份工作了。面试官们都说我基础很好嘿嘿嘿……其实面试官对于嵌入式应届生并没有太高的编程技术要求(寒武纪现场编程没做出来之后面试官亲口说的),甚至芯原的笔试根本就是全方位的基础知识集合。他们最看重的是你的潜力,首先是做项目是否认真地刨根问底,对技术的追求,这些直接体现在你的基础知识上,项目中的所有东西要能经得起面试官细致的地毯式轰炸。第二个就看你目光是否长远,行业认知,未来趋势,表达交流能力,他希望你有自己的见解,毕竟对于一个985硕士他培养的是未来的骨干而不是只会干活的码农。

第二阶段称为多核+Linux阶段。

老师不让我们碰Linux,在RTOS没吃透的时候。 以上过程走完之后就可以碰Linux了,这时候你肯定已经有自己的一些判断,你可以找一块更高端的板子,a系列甚至是多核的,再走一遍裸板驱动、移植Linux、交叉编译环境的调试,ai算法工程化等等高端玩法,这也是我今后的研究方向。

第三阶段

要么是转管理带技术团队,或者就去研究架构做技术专家。要么OS内核架构要么底层软件系统架构,都是核心技术,这一块目前我一个只完成第一阶段的菜鸡看不透。

最后荐书环节

        其实书不在多,啃透就行,除上面提到的《野火stm32完全开发手册》、《M3权威指南》、《程序员的自我修养》、《嵌入式操作系统》还有经典的《深入理解计算机系统》:出版至今几十年了,基本内容没怎么变过依然为行业经典,充分说“以不变应万变”的重要性。里面各个方面的知识都有,我目前关注了程序优化和指令集部分,日后会继续拜读其他章节。以上书目建议把书翻黑为止。

《高级计算机系统结构》,没错就是计算机学院和软件学院必开的那门高计课,虽然大部分讲的X86,但是各个模块俱全,我面试时那些cache知识、指令流水知识和各种处理器知识就是来自这里。

《C语言程序设计现代方法》:扔掉那本红色的辣鸡,所有C语言的细节这本书都有,遇到基础语言的问题翻这个就对了。《C和指针》也要看起来。

对于面试还需要《王道程序员面试宝典》《C陷阱与缺陷》,帮助你理解C语言的细节,各种细节,你从来没关注过的细节,助你选择填空拿满。嵌入式程序员不需要费劲去关注算法,遇到动态规划什么的直接不做就好了,《剑指offer》不用刷,去牛客刷点链表和字符串足够了。

        以上,希望帮到大家。

二.作者:程序员良许

来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

以下是作者的个人经历和总结。

转折点

        本来我就想一直踏踏实实的做机械,但阴差阳错的,第一份工作由机械工程师调剂到电子工程师。虽然是电子工程师,但做了很多代码工作,那时候学了一些Verilog,以及C#,并且用C#开发了一个测试工具及一个生产用的上位机,据说那个测试工具现在还在电子部门使用。

        可是,我在学校学的是机械啊,跟软件相关的东西顶多是C语言及汇编语言,但C语言是十年前(那时候)学的,早就还给老师了。为了工作的需要,我学会了Verilog及C#,同时对STM32有个大概的了解。

入门

        第二份工作,我是嵌入式工程师。在去公司之前,我系统的学了一遍51,看的是「郭天祥十天学会51单片机」,对单片机有个初步的入门。真正入职后,再利用一个月的时间系统学习一遍C语言,看的是C语言之父写的「C程序设计语言」。这本书虽然写于80年代,但现在看来依然不过时。而且这本书比较薄,容易看完,比较有成就感。

        看完 「C程序设计语言」之后,最好再看「C和指针」,「C专家编程」,「C陷阱与缺陷」。这三本书号称「C语言三剑客」 ,学完它们你的C语言水平绝对是非常之高了。做我们这行,C语言是基础语言,一定要把C语言完全拿下。

        之后为了工作的需要,开始接触了Marvell 88MC200及88MW300。这两款是WIFI芯片,但本质是单片机,采用的是ARM M3内核。底层驱动已经由厂家写好了,我们要做的工作就是在SDK基础上做应用做二次开发。在这个过程中,我对敏捷开发有了初步的认识,看了「高效程序员的45个习惯:敏捷开发修炼之道」这本书。

        在第二家公司里,我知道了物联网的整体解决方案,对于物联网的整体框架有了更深入的了解。同时对嵌入式开发所需的技能有了全面的掌握,达到能够独立做一个物联网项目的水平。当然,期间还学会了版本控制工具git,看的是「Pro Git」「git权威指南」。同时再进一步系统学习了STM32,看的书是野火的「STM32库开发实战指南」,但看的视频却是正点原子的。这里强烈推荐正点原子的视频,真的是做的非常好。

新挑战

        我的新岗位是Linux应用开发工程师,使用C++ 开发。而在那时,我既不会Linux,也不会C++,所以公司敢录用我真的是勇气可嘉。

        从单片机到Linux又是一个比较大的跨度。Linux主要有三个方向:运维、应用、底层,而我选择的是应用方向。为了工作的需要,我必须先拿下C++。

        我采用的是先看视频再看书的方式。我建议先把老师讲的知识完全掌握了以后,再利用书籍进一步扩展其它知识。但是,不管是看书还是看视频,一定要写代码,一定要写代码,一定要写代码!!

        C++ 实在是太难了,我用了一个多月才将视频里的知识完全拿下来。之后,在工作中,陆续开始看「C++ Primer」进一步巩固。其它书籍推荐:「Effective C++」,「C++ 语言的设计与演化」,「C++ 标准程序库」。在stackoverflow上有个C++必读书单,可以去看看。

        学完C++我再学习了Linux系统编程,同样采用的是先视频后书籍的方式进行。

Linux应用的学习

        主要有六部分:1. 环境搭建;2. 基本操作;3. 系统编程;4. 网络编程;5. 数据库编程,6. Shell编程。下面一一详细介绍。

1.环境搭建

        对于Linux环境的获取,我们通常有三种方式:

  • 将电脑整体安装为Linux系统;
  • 在电脑里安装一个虚拟机,跑Linux电脑;
  • Window+Linux双系统。

        得到Linux环境后还不够,还要知道如何配置、如何远程连接Linux电脑、如何与Linux电脑互传文件、如何在主机上阅读Linux电脑中的代码,等等。

2.基本操作

        而对于应用、驱动方向的人员来说,只需掌握一些基本的常用的命令即可。

3.系统编程

       在学系统编程之前,一定要先学习Makefile,这会为后续的学习提高很大效率。之后的系统编程,主要有几大块:IO编程、进程、线程、进程间通讯(包括管道、信号、信号量、共享内存等)。这几部分学完了,基本也就差不多了。

4.网络编程


网络编程主要就是socket,poll,epoll,以及对TCP/IP的理解,同时要学会高并发式服务器的编写。

5.数据库编程

数据库的内容其实并不属于Linux,但在项目中经常要用到。这部分主要要学会数据库的基本操作,以及如何写一套接口去操作数据库。

6.Shell编程

Shell是Linux下的脚本语言,功能虽然不如高级语言强大,但它可能做很多事,在某些场合甚至比高级语言要方便得多。当然除了Shell脚本,还有Python脚本。

Linux应用编程书籍推荐:

  • UNIX环境高级编程。简称APUE,号称程序员的圣经。它不是一本API字典,它还讲述了很多操作系统的细节,内存,文件系统等方面,是一本难得的好书。但是它起点有点高,不适合初学者。
  • Linux程序设计。如果觉得APUE有点难入门的话,可以选择此书进行入门。
  • Unix/Linux系统编程手册。这本书号称是一本超越APUE的书,它是一本比较新的书,里面新增了APUE所没有的Linux/Unix新特性。而且对于一些概念性的东西讲的确实比APUE好。但至于能否超载APUE,还有待历史的考验。
  • UNIX 网络编程。也是一本非常经典的书,主要是网络编程方向的。
  • MySQL必知必会。本书在Amazon上长期排在数据库销售榜首,建议想快速了解数据库原理和MySQL的新手阅读。快餐性质,简洁明快,小开本,而且很薄,比较好阅读。
  • Linux Shell脚本攻略。这本书很薄很精华,它追求的不是全,而是精,所以用它来入门再适合不过了。

        学完以上六部分,基本就有能力完成Linux环境下的应用编程了。当然,在有些场合我们可能还需要用到Python脚本。像我公司的项目部分脚本就是用Python完成的。对于Python的入门,可以参考「简明Python教程」。但如果想进一步提高的话,那就需要阅读大量书籍了。对于Linux层级的脚本应用,掌握一些基础的足够了。

 

三、作者:DiedCode

来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

以下是作者所讲经验,仅供参考。

没必要看视频,有份好的文档比视频好。

必备资料:正点原子和野火。

路线:单片机—嵌入式Linux

1,学习单片机:

直接看野火的文档,芯片手册,外设手册

我是把文档手册看完后,然后再在开发版验证一下,最好能改一下代码,按照看看是否符合预期。

2,过渡

计算机操作系统

数据结构:链表,二叉树,排序。这是最基本要求。

编译原理:学一下简单的Linux命令行,这个看b站视频。

参考:我看的书是大话数据结构和计算机课本。

3,看ucos(非必须)

直接看野火文档,源代码,其实可以不用看,但我觉得学完后,对计算机操作系统有更深刻的认识。除了ucos,还有其他的几款实时操作系统,野火上面很全,有时间的话,研究一下其他几款os,感觉也挺好。(不看,可以看freertos)

4,Linux应用编程

参考:Linux/Unix系统编程手册,网络部分可以看一下Unix网络编程前几章。

这个不难,就是调用API,然后必须运行程序看效果。

上面几本书籍可以当作字典,没必要上来就看。学习的话,可以看王桂林的文档,我的cpp,c,Linux系统编程,Linux网络都是看他的文档,还有他的cpp课程值得你看,我的cpp是看他的视频。

现在正点原子,野火文档都写了Linux应用编程,其实就那些东西,我推荐你还是看正点原子or野火。我当时学的时候,还没有这些东西,现在真的太方便了。

把握以下几点:

文件

进程,线程,信号

进程,线程通信同步

网络:这个简单,就那几个API,TCP和udp。

5,嵌入式Linux

目前我正在学,我看到资料是正点原子,野火和韦东山作为参考。

我还是按照学单片机的方法:先理解程序逻辑和理解手册,再在开发版验证。这样就不会因为开发版的问题断断续续。

我是直接看的驱动,学驱动的时候,需要看一下前面的裸机程序。中间的移植那些东西暂时没看。

我的学习方法还是记笔记,学驱动肯定要记驱动框架,就是调用内核API的流程,裸机代码放哪,xx需要写在哪里,等等。

不过要深入的话,看Linux源代码还是必须的,因为既然学到底层了,还是有必要看下内核api实现代码,不然总感觉有点在沙子上修房的感觉。不过还是等我把文档上面的驱动搞完后,在细致的研究一下,加深理解。

另外感觉不要一开始就看Linux各种书籍,实在太多了,而且理论多。我认为学技术的话,看野火和正点原子完全可以,所以理论方面目前暂定几本书:Linux设备驱动程序开发详解,Linux设备驱动程序,Linux内核设计与实现,深入理解Linux内核。我感觉前面三本书,学完教程后再看比较好,或者当作参考。后面那一本就需要和源代码一起看,这个就比较耗费时间和精力了。

6,单纯的心趣

以后的打算是研究一下Linux某个子系统,然后再研究一下图像处理,机器学习,深度学习。活到老学到老。不过做毕设的时候用的是CNN+lstm,差点被逼疯。

 

四、今天又是充满希望的一天

1.1 嵌入式定义

嵌入式系统是一个非常广泛的定义,从技术层面来说可以分为硬件层,驱动层,系统层和应用层。

  • 硬件层,就是原理图、PCB图、电路板那些。
  • 驱动层,主要工作是对MCU寄存器进行读写、总线的使用以及对传感器什么外设的操作等,简单说就是编写直接操作硬件的代码。
  • 系统层,把前面的驱动层封装起来,并弄出个接口(驱动接口),同时加上进程控制、内存管理、文件系统、网络通信四样东西,再把这些东西再封装起来,最后提供接口给应用层。当然,由于嵌入式系统是专用设备,具有可裁剪的特性,所以上面五样东西不一定都有。
  • 应用层,只要是涉及人机交互界面的都属于这里,其中一种就是手机移动开发。

在驱动和硬件这两个层次做出来的产品,我们现在称之为智能硬件。

嵌入式分为广义和狭义两种。广义的嵌入式就是片上系统(system on a chip),包括单片机、PSOC、NIOS、Microblaze等。而狭义的嵌入式就是ARM9、cortex A8等特定的跑操作系统的芯片。这里主要介绍狭义嵌入式的学习路线。

1.2 就业岗位

        嵌入式的工作也分成几个岗位,分别是系统工程师、驱动工程师、软件工程师、UI工程师。

  • 系统工程师:熟悉操作系统的内核原理、熟读内核源码。主要职责为系统打补丁或者添加新功能,如:热升级、提高系统的容错性等。一般的公司是不做这种开发的。
  • 驱动工程师:熟悉各种外设的驱动开发,为内核和GUI提供接口。由于很多IC厂商提供了相关芯片的驱动程序,而导致很多驱动工程师下岗(需求量减少)。
  • 软件工程师:熟悉各种编程语言和GUI图形库、框架(不是会查文档就可以的,而是要求非常熟悉框架)。由于项目需求经常变更,开发效率跟不上变化,所以软件工程师的需求量大大增加。 

1.3 学习路线

(1)安装虚拟机和Linux系统。

(2)学会使用Linux常用命令。

        学会最基本的命令,如:ls、cd、find、grep、ps、diff、fdisk、ifconfig等。

(3)学会使用Linux常用工具。

  1. 编辑器(写代码必备的)。推荐学vim
  2. gcc和gdb。gcc是编译器,gdb就是代码调试器。
  3. makefile、autoconf、automake。这里可不像VC++6.0这种工具,点个鼠标就给你编译好。在Linux下,你得用makefile和make工具,来编译代码。其中autoconf和automake可以自动生成makefile。
  4. ssh、tftp。如果你在ARM开发板上弄了个Web服务器,那么,你就可以用这些工具去访问它。其中,ssh工具建议用SecureCRT或者MobaXterm
  5. samba。要想用Linux跟windows交换数据,还可以搭建samba服务器。
  6. 版本控制器。有svn,cvs,git等,推荐学git。有了git,你就不必手动备份代码了。

(4)学会编写shell脚本。

        在实际工作中,复杂的系统管理操作,不会一行一行地敲命令,而是用脚本(命令是基础)。脚本也是一种编程语言,只不过是解释型语言。相比C/C++、C#、JAVA这类高级语言,脚本要易学很多(因为增加了语法糖)。在Linux下,shell也有很多种,如:bsh、bash、csh、tcsh、ksh、zsh等,一般是学bash,其它的遇到再学也不迟,因为都是大同小异的。此外,bash语法比较奇特,很多符号(如:$#,$0,$?等)比较难记,不过也没必要特意去死记它,有个印象就可以了,用到的话再查手册,这里重点掌握正则表达式。如果有时间的话,建议再学python脚本,python的语法要容易很多,用途也比bash广很多。

(5)学会Linux下C编程。

        尽管学会bash已经能做很多事情了,但是驱动和内核开发还是用C语言,因为那时候系统还没起来,bash是用不了的。此外,C语言的执行效率比bash要高,网络编程的Socket也常常用C语言开发。在这里,得掌握基本的文件操作、进程/线程控制、Socket等。推荐《Linux环境C程序设计》、《UNIX环境高级编程》、《UNIX网络编程 卷1》、《UNIX网络编程 卷2》,或许这些教材有点难,但是,请不要钻牛角尖,不懂的暂时跳过,在学完下一阶段的理论之后,再来看,之前不懂的东西就变得容易。

(6)增强理论知识。

  • 单片机:不想学单片机的话,可以学计算机组成原理。
  • 数据结构:主要掌握表和树,其中链表会在操作系统的调度算法中用到。
  • 操作系统:全部都是重点,必须深入研究,才会对Linux有个较全面的认识。
  • 编译原理:有时间的话,最好多看看,没空的话,也得了解一下。对于提高编程能力,有一定的帮助。
  • 数据库:除了基本的数据库理论之外,还得掌握SQLite或者Oracle。
  • ARM体系结构:介绍ARM的架构和指令集,在移植uboot和驱动中会用到,不做这两项工作的话,可以不学。
  • 计算机网络基础:开发中用到的tcp、udp、ssh、tftp、http、rtp就会涉及到网络相关的知识,也就是socket套接字编程。
  • 接口应用:如:串口、zmodem、IIC、SPI、1-wire、USB、HDMI、CAN、IIS、PCIE、蓝牙、陀螺仪等。

        学完上面这些理论之后,得再复习一下linux下C编程,你会有更大的收获。

        下面第七、八、九阶段,使用开发板自带的bootloader即可,暂时不必研究它。

(7)文件系统。

        在学习操作系统原理的时候,已经有介绍文件系统了,而且不需要深入研究文件系统的具体算法,只需要了解其特性再学会使用它就可以了。如:NFS、FAT32、NTFS、yaffs2、ext4、ZFS等。

(8)内核裁剪。

        一般初学,可以先掌握内核剪裁(具体工作就是填写若干个选项)。剪裁只是去掉内核部分不需要的功能,以减少代码体积。这里只要求你对内核的各个功能选项都很熟悉就可以了。如果剪裁还不能满足要求的话,得阅读内核源码,修改内核了。推荐《Understanding the Linux Kernel》和《Linux Kernel Development》。阅读内核源码,推荐windows下的source insight或者eclipse。

(9)驱动开发。

        由于系统还没起来,所以驱动能用到的API(内核的部分API,如:kprintk、kmalloc等)并不多,很多函数还是得自己写的,其中,会经常访问临界资源,所以得掌握自旋锁、睡眠锁。此外,驱动程序出问题的话,整个系统就挂掉了,所以还要掌握各种调试驱动的方法,如:goto语句、日志系统、KDB等。接下来就要熟悉掌握字符设备和块设备的驱动程序了。推荐《小白的博客》和《Linux Device Drivers》(不建议看中文版)。

(10)移植bootloader。

        单片机也有bootloader,在keil C下的startup.a51,主要是做一些初始化工作。那么,在ARM上面的bootloader也是一样的功能,同样,也没有那么重要所以把它排在后面。常用的bootloader有vivi和uboot,一般学习uboot,主要掌握uboot的启动流程和移植。在经过前面的学习,那么uboot对你来说已经非常容易的了,一般只需要学会使用uboot或者用已经移植好的uboot,不需要深入研究它。推荐看uboot自带的帮助文档以及《深入理解BootLoader》。阅读uboot源码,推荐windows下的source insight或者eclipse

五、韦东山

(1)什么人需要学习裸机


如果你符合这些条件之一,那么可以从裸机开始学习:

  •  没有硬件基础,比如看不懂原理图,想纯粹地掌握硬件编程;
  • 没有单片机开发经验,想顺便掌握单片机的开发技能;
  • 有单片机基础,但是想深入内部原理的人(MDK 等图形工具屏蔽了太多细节);
  • 想深入研究 U-Boot,但是 U-Boot 又太复杂,所以先把各个部件按裸机来研究一下;
  • 想深入了解主芯片的人:

        学习 STM32 还不如在 Linux 下学习裸机,Windows 工具封装了太多细节,在 Linux 下学习可以学到更多,并且完全覆盖 STM32 单片机的知识。

        在日常开发过程中,我们使用 Linux 驱动来操作硬件,很多时候不涉及寄存器。如果你需要微调驱动、解决 BUG,那就需要看芯片手册。在我们的裸机文档里,有深入的讲解。

(2)以前的视频是从裸机讲起的,现在为什么改了?


        2005 年左右,嵌入式 Linux 在全世界、在中国刚刚兴起。那时候芯片厂家 Linux 开发包不完善,从bootloader 到内核,再到设备驱动都不完善。

        所以工作中需要掌握所有知识:U-boot、Linux 内核、Linux 设备驱动、应用、项目。

        但是 U-boot 那么难,那就先把它拆解开学习各个裸机程序吧。所以以前的课程就会分为这几部分:裸机、U-boot、Linux 内核、Linux 设备驱动、应用、项目。

        现在 15 年过去了,嵌入式 Linux 世界发生了翻天覆地的变化:

  • ① 基本系统能用

        芯片厂家都会提供完整的 U-boot、Linux 内核、芯片上硬件资源的驱动。
        方案厂家会做一些定制,比如加上某个 WIFI 模块,会添加这个 WIFI 模块的驱动。你可以使用厂家的原始方案,或是使用/借鉴方案商的方案,做出一个“能用”的产品。

  • ② 基础驱动弱化,高级驱动专业化

        基础的驱动,比如 GPIO、UART、SPI、I2C、LCD、MMC 等,有了太多的书籍、视频、示例代码,修修改改总是可以用的。

        很多所谓的驱动工程师,实际上就是“调参工程师”。

        高级的驱动,比如 USB、PCIE、HDMI、MIPI、GPU、WIFI、蓝牙、摄像头、声卡。很多时候只是配置一下应用层工具就了事,能用就成。

  • ③ 项目为王

        你到一个公司,目的是把产品做出来,会涉及 APP 到内核到驱动全流程。

        所以,如果你不是立志成为某方面的专家,那就做一个全栈工程师吧。

        可以先掌握必备的 APP 基础、驱动基础,然后马上开始学习项目开发。

嵌入式Linux系统的组成:

  1. 组成:嵌入式Linux系统= bootloader + linux内核 + 根文件系统(里面含有APP)。
  2. bootloader:它的目的是启动内核,去哪等读内核?读到哪里?去Flash等外设读内核,存到内存里去。所以需要有Flash里外设的驱动能力,为了调试方便还会有网络功能。所以,可以认为 booloader = 裸机集合,它就是一个复杂的单片机程序。
  3. Linux内核:Linux内核的最主要目的是去启动APP,APP保存在哪里?保存在“根文件系统”里。“根文件系统”又保存在哪里?在Flash、SD卡等设备里,甚至可能在网络上。所以Linux内核要有这些Flash、SD卡里设备的驱动能力。
  • 不仅如此,Linux内核还有进程调度能力、内存管理等功能。
  • 所以:Linux内核 = 驱动集合 + 进程调度 + 内存管理等。

要学习bootloader吗?

  • Bootloader有很多种,常用的叫作u-boot。
  • 在实际工作中,对于u-boot基本上是修修改改,甚至不改。但是u-boot本身是很复杂的,比如为了便于调试,它支持网络功能;有些内核是保存在FAT32分区里,于是它要能解析FAT32分区,读FAT32分区的文件。
  • 花那么多精力去学习u-boot,但是工作中基本用不到,这对初学者很不友善。
  • 所以,对于初学者,我建议:理解u-boot的作用、会使用u-boot的命令,这就可以了。
  • 如果你的工作就是修改、完善bootloader,那么再去研究它吧。

要学习Linux内核、要学习驱动程序吗

  • 之前我们说过Linux内核 = 驱动集合 + 进程调度 + 内存管理等,如果要学习Linux内核,从驱动程序入手是一个好办法。
  • 但是人人都要学习Linux内核、人人都要学习Linux驱动吗?显然不是。
  • 作为初学者,懂几个简单的驱动程序,有利于工作交流;理解中断、进程、线程的概念,无论是对驱动开发、应用程序开发,都是很有好处的。
  • 所以对于初学者,建议前期只学习这几个驱动:LED、按键、中断。
  1. LED驱动程序:这是最简单的驱动程序。
  2. 按键驱动程序:它也比较简单,从它引入“中断”。
  3. 中断:从“中断”它可以引入:休眠-唤醒、进程/线程、POLL机制、异步通知等概念。这些概念无论是对驱动开发,还是对应用开发,都很重要。
  • 所以,对于初学者,我建议必须学习这几个驱动:LED、按键、中断。
  • 入门之后,如果你想从事内核开发、驱动开发,那么可以去钻研几个驱动程序(输入系统、I2C总线、SPI总线等),掌握若干个大型驱动程序后,你对内核的套路就有所了解了,再去研究其他部分(比如进程管理、文件系统)时你会发现套路是如此通用。
  • 摄像头(VL42)、声卡ALSA驱动是Linux中比较复杂的2类驱动,它们是很难的,如果工作与此相关再去研究。

要学习Linux应用程序吗?

  • 要学,即使以后你只想研究内核,一些基本的应用开发编写能力也是需要的:
  1. 基本设备的访问,比如LCD、输入设备
  2. 进程、线程、进程通信、线程同步与互斥
  3. 休眠-唤醒、POLL机制、信号
  4. 网络编程
  • ①②③部分的知识,跟驱动有密切的关系,它们是相辅相承的。
  • 掌握了基本驱动开发能力、基本应用开发能力之后,在工作中你就可以跟别人友好沟通了,不至于一脸懵逼。

应用程序是怎么启动的?要了解一下根文件系统

  • 你辛辛苦苦写出了应用程序,怎么把它放到板子上,让它开机就自动启动?
  • 你写的程序,它依赖于哪些库,这些库放到板子上哪个目录?
  • 怎么做一个可升级的系统?即使升级中途断电了,也要保证程序至少还可以运行老的版本?
  • 这些都需要我们了解一下根文件系统。
  • 先了解一下init进程:它要读取配置文件,根据配置文件启动各个APP。
  • 了解了init进程,你就了解了根文件系统的组成,就可以随心所欲裁剪系统,为你的项目制作出最精简的系统。

学习方法

先不要打破砂锅问到底

  • 嵌入式涉及硬件知识、软件知识,软件里涉及汇编、ARM架构、C语言、Makefile、Shell;又分为bootloader、内核、驱动、基本的APP、GUI。
  • 比如我们会用到Makefile,了解它的基本规则,会用我们提供的Makefile就可以。不需要深入研究那些make函数,因为在工作中都有现成的Makefile给你使用,不需要自己去编写一套Makefile
  • 比如我们会用到bootloader,工作中基本不需要改u-boot,会用那几个命令就可以
  • 甚至有些学员先去买本shell的书来学习shell命令,何必?我们在视频中用到什么命令,你不懂时再去百度一下这些命令就可以了
  • 不要脱离初学者的主线:应用基础、驱动基础。有了这2个基础后,你想深入研究某部分时,再去花时间吧。

思路要清晰,不怕抄代码

  • 但是要理清楚思路,你写这个程序要完成什么功能、怎么实现这些功能?这个要弄清楚。
  • 有了思路后再写代码,不知道怎么写?没关系,看看视频,看看示例,然后关闭视频看看能否自己写出来

六、悠悠荡荡我懂等


来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

嵌入式的技能清单和升级线路

第一部分:虚拟机安装和LINUX系统安装

 熟悉运用 Linux环境下,常用命令的操作与系统设置,如常用的 Shell;掌握基本的Shell(bash) 应用。

第二部分:嵌入式LINUX环境搭建

1、 建立嵌入式 Linux开发环境

2、 熟悉嵌入式开发平台

3、 嵌入式 Linux开发工具

4、 Linux下的调试技巧

5、 MAKE工程管理器

6、 硬件环境的搭建;arm-linux-gcc与 gcc安装配置

第三部分: U-Boot

了解 U-Boot 的作用及工作流程;了解Bootloader 的代码结构、编译过程;移植U-Boot;掌握常用的U-Boot命令。

  1. Bootloader介绍
  2. u-boot工程介绍
  3. u-boot的编译使用
  4. u-boot源码分析
  5. u-boot资源分配
  6. 配置编译u-boot
  7. u-boot移植过程
  8. u-boot常用命令操作
  9. 添加u-boot新命令
  10. 设置u-boot环境变量
  11. u-boot驱动添加如网卡:DM9000

第四部分:LINUX内核移植

推荐孟宁的《庖丁解牛Linux内核分析》,讲的还行还有那本kernel完全注释也不错

主要的熟悉内核的原码结构和kbuild Makefile语法;掌握和内核、驱动模块编译相关的原理及方法。

  1. Linux内核介绍
  2. Linux内核特点
  3. Linux内核源代码结构
  4. Linux内核选项解析
  5. Linux内核编译链接
  6. 内核模块编译、使用方法

第五部分:LINUX根文件系统

  1. busybox 包移植、编译
  2. Linux跟文件系统制作过程
  3. 根文件系统介绍
  4. nfs文件服务器系统搭建

第六部分:LINUX驱动开发

(最多的就是字符设备了,驱动编写说简单简单说难也难,写多了感觉就挺枯燥的。)

  1. 了解掌握三大设备字符,块,网络设备具体。首先最简单的 按键 GPIO口控制led灯驱动
  2. spi,iic,can三大总线。以及中断驱动,在驱动中中断程序的编写,消息队列的应用
  3. ADC驱动开发
  4. 网卡驱动开发
  5. 串口uart驱动开发
  6. LCD屏,液晶显示器
  7. 触摸屏驱动+tslib(中间插件移植与设置),
  8. USB驱动开发+USB无线网卡移植
  9. maplay移植与应用(mp3播放)+mplayer移植与应用(视频播放Mp4/广告机等播放) HDMI接口的使用
  10. SD驱动开发
  11. RTC驱动开发
  12. 电源管理方法

第七部分:Linux 应用学习

主要目标是精通嵌入式Linux下的程序设计,熟练掌握嵌入式Linux的开发环境、系统编程以及网络编程,熟悉C++、QT编程并且深刻体会整个嵌入式Linux项目开发流程,强化学员对Linux应用开发的能力。

  1. Linux系统中的进程的概念,在应用程序中线程与父子进程的创建与应用
  2. 线程之间、进程之间的通信
  3. 进/线程间区别联系。
  4. 管道(PIPE)
  5. 信号(SIGNAL)
  6. 内存映射(MAPPED MEMORY)
  7. 消息队列(MESSAGE QUEUE)
  8. 信号量(SEMAPHORE)
  9. 共享内存(SHARE MEMORY)
  10. TCP协议在应用程序中的编程开发(SOCKET套接字编程开发)
  • 10.1. ISO/OSI七层协议模型与IP网络四层模式
  • 10.2.TCP/IP协议簇
  • 10.3. 基于嵌入式Linux的TCP/IP网络结构
  • 10.4. 基于嵌入式Linux的SOCKET编程
  • 10.5.UDP与TCP的区别
  • 10.6. UDP SERVER-CLIENT关系程

     11. 文件读写与存储

第八部分:QT移植与开发

(与c++语言挂钩了,要有语言基础。c++算是面向过程开发中最复杂的语言)

了解嵌入式Linux下的几种常见GUI及其特点,重点能掌握QT的有关内容,具备QT程序设计能力。了解嵌入式数据库的配置与开发

  1. 嵌入式Linux GUI介绍
  2. 嵌入式QT开发包移植
  3. QT介绍及其信号插槽机制
  4. QT图形界面编程技术
  5. QT应用程序与Linux驱动的衔接
  6. QT在实际项目中具体应用

第九部分:无线通讯应用

  1. 无线wifi模块应用
  2. 3G模块应用

第十分布:嵌入式系统应用程序,驱动程序调试

  1. Linux基本工具调试使用。GDB,insight调试等
  2. Linux应用程序的编程

下面是一些具体比较细的知识点了。

嵌入式LININX开发第一学习阶段,主要打好基础,学好C编程,Linux系统编程。

  1. C语言编程基础
  2. 嵌入式开发基础:Linux概述安装,shell命令,vim编辑器,GCC,GDB,Makefile,交叉开发环境构建
  3. 嵌入式Linux系统编程:shell编程,文件编程,串口编程,进程编程,线程编程,网络编程
  4. 嵌入式项目开发:数据采集控制系统,串口服务器

嵌入式LININX开发第二学习阶段,掌握ARM汇编程序设计,驱动程序设计。

  1. ARM体系结构:ARM体系,ARM指令,Thumb指令,汇编程序设计,逻辑程序开发
  2. Linux内核移植:bootloader,内核配置,文件系统
  3. 驱动程序开发:驱动架构模型,字符设备驱动,块设备驱动,网络驱动
  4. 嵌入式项目开发:智能家居系统,视频监控系统

嵌入式LININX开发第三学习阶段,掌握C++面向对象程序设计,Qt编程。

  1. C++语言编程基础
  2. QT编程开发:QT开发基础,QT布局与控件,QT绘图,QT事件,QT网络通信,QT数据库,QT移植
  3. 嵌入式项目开发:实时视频流(海康大华等项目),gsm通信,3/4/5g的一些小项目(华为中心爱立信) git上很多开源的小项目,随便做两个都行。

我校招简历上技能知识这一块填的是:

  • 熟练掌握C 语言(指针,数组,函数,结构体);
  • 掌握基础数据结构和算法(堆栈,链表,队列,二叉树,哈希表,简单排序等);
  • 熟悉C++编程语言(继承,封装,多态);
  • 熟练掌握Linux 系统编程(文件管理,多进程,多线程,进程通信,Socket编程等);
  • 了解Linux 内核驱动编程,熟悉shell等脚本语言,掌握Ubuntu,RedHat下程序开发;
  • 理解面向过程和对象编程,掌握Eclipse下简单的Java及Android开发。
  • 了解 bootloader,内核配置,文件系统,kernel移植。

七、

下面是在网上找的一些代码经验:

  • 切记能不用全局变量就不用全局变量,除非在调试中需要迅速从RAM中获取信息。比如通过在RAM中记录程序是否击中,这确实需要在你需要记录程序击中点的时候直接改写一个全局变量结构体,但切记要做共享内存临界区保护以防止你在不同线程中同时操作。不使用全局变量的原因还有一个,就是一般CPU不会把全局变量放在寄存器里,这使得使用全局变量需要额外的非必要的读取和存储。
  • 进入中断后不要睡眠,需要在中断中延时务必直接占用CPU资源来直接等待。
  • 写寄存器前务必先读取,通过位操作更改你想更改的比特位后再重新写入,写入后回读测试是否符合预期
  • 节约内存可以考虑const和union
  • 反复调用的地方尽量考虑静态内存,不要为了数据大小准确而反复malloc, , 需要通过反复验证找到最大的需求值,然后直接使用静态数组。

另外还有一些关于调试的经验:

调试是一个特别重要的手段,问题趋势大概如下:

  1. 最基本的调试(打印调试)
  2. 如果不能打印怎么调试(GDB、一些仿真器/模拟器等等)
  3. 如果不能用任何仿真和模拟(JTAG在线调试)
  4. 如果不让用JTAG(GPIO调试)
  5. 如果不让用GPIO(可以把信息存在文件系统里然后dump出来)
  6. 同时,在做ARM调试的时候,有经验的工程师会打开汇编语言显示去逐行进行调试,因为有着太多的优化问题导致光看C语言是不准确的。比如GPIO调试,这个调试最重要的就是GPIO输出要快,所以要避免函数调用,一定要用宏来做。

再说一个关于调试的思路,比如,存储的数据和预期不一样,至少有以下几种可能:

  • (1)发送端正确而接收端不正确
  • (2)上层应用处理数据的时候导致结果异常
  • (3)文件系统自身缺陷导致数据存储错误
  • (4)RAM时序配置不对导致数据在内存中错误,又要细分为读错误、写错误
  • (5)Flash时序配置错误导致数据在非易失区域错误,细分为读错误、写错误

面对如上可能,要自上而下逐一排查:

  • ①示波器或者逻辑分析仪测量总线上数据是否正确
  • ②应用层做单元测试,增加测试组合,边界测试
  • ③文件系统要在另一套系统上做仿真模拟
  • ④在测RAM的时候,要独立实践一个简短高效的可以在CPU内部RAM运行的外部RAM测试程序(默认CPU内部RAM是正确的)
  • ⑤在测Flash的时候要保证所有代码都放到RAM里
  • ⑥底层调试不要使用打印,在不能使用JTAG的情况下,使用若干GPIO输出不同编码来指示程序运行状态
  • ⑦在操作GPIO时不要调用API接口而应该直接用寄存器地址操作来尽可能的减少延时

八、嵌入式学习路线和书籍推荐---Codesheep

 

 

 

 

本文标签: 嵌入式 经验 硬件 Linux