更新于 2021-09-21,规范下文档大纲,之前风格太丑。
本文为本人大学和工作4年期间,学习嵌入式的实际学习过程分享。因为自己走了不少弯路,为方便知友们少走弯路,学习路径相对我实际学习过程略有先后顺序调整,仅供参考。
0. 写在最前
嵌入式学习路径是一个漫长而又有趣的过程,有趣是随着知识的积累感受的成就感,漫长是相对于软件来说,入门还是有一定门槛的。
但一定不要一个人学习,因为上述学习路径长,难度渐渐加深,一个人总有不理解,晦涩难懂的地方,你需要有人来探讨。注意是探讨,不是一味的请教别人,遇到问题自己先通过网络查询资料,先学习和思考,再请教他人。因此强烈建议现实生活中找一两个同样方向的人一起学习,在学校就比较方便了,加个单片机社团就有学习氛围了。
不要一个人学习,学习需要探讨,一个人学习容易放弃,一伙人则会相互激励。
不要一个人学习,学习需要探讨,一个人学习容易放弃,一伙人则会相互激励。
不要一个人学习,学习需要探讨,一个人学习容易放弃,一伙人则会相互激励。
大部分人的主要疑问:哪里可以找到一伙人?
学生党:问问学校电气, 机电学院里面有没有类似的工作室. 可以利用实验室资源最大化学习。
工程师:通过自己买开发板或者打样。交流的途径有:各类技术论坛,stm32这块,可以去正点原子论坛, 野火论坛,也有对应微信公众号,可以找找有没有衍生出的微信群或者QQ群。linux这块,100ask论坛,ZLG开发交流群. 各种交流群, 论坛, 只要用心去找, 一定能找到。
1. 基础课程
1.1 C语言
具体细节的知识点我这里就不详细的展开描述了,毕竟C语言的书和视频教程网上一大堆,学习资源充分。
但这里建议,C语言的基础还是要打扎实的,最简单的方法就是高中对付高考的方法:题海战术。其实就是将C语言书籍后面的C习题,每一题的做一遍,自己动手敲一遍,想一遍,调试一遍。这样将会极大的锻炼到你的基础编码能力。
觉得C语言课本后面的习题太简单没有难度的,可以转战LeetCode。
1.2 数字电路
具体的细节说实话我也不记得了,但是最基本你要知道与或非门如何实现组合逻辑;组合逻辑的输出反馈到输入作为下一次逻辑的输入就构成了时序电路,掌握时序逻辑的分析方法;另外还需掌握数据锁存器类的掉电数据不丢失的电路是什么样的原理。掌握这些概念,或许最开始仅仅是一知半解,没有能将知识串起来,但是等到某一天你的知识体系成熟的时刻,你就豁然开朗了。
个人觉得,学习数电主要是要理解到下面这几个点:
- 人类文明的进步,探索发现了PN结这种东西具有单向导电性,由此制作做了二极管。(理解PN结单向导电原理)
- 由于二极管的单向导电性,由此又制作出了与或非门电路。(理解二极管如何构成与或非逻辑门)
人们做出了与或非逻辑后,发现世界上逻辑就是在此基础上复杂化而已。可用通过与或非门实现加法器,移位器,编码器,译码器等各种想要实现的组合逻辑(掌握通过门电路设计组合逻辑的方法)
- 但现实生活中的逻辑往往不像组合逻辑这么单纯,输入转化为输出就结束了。往往上一次的输出会影响到下一次处理。时序逻辑的出现就这么引入了,同时也带来了时钟的概念。(掌握组合逻辑输出反馈为下一个时钟的输入得到时序电路的分析方法)
- 上面这些都是实时输出的,即输入的同时才能得到对应的输出,一旦输入没有,输出也就丢了。数据没有办法保存。于是人们又通过门电路制作出了可以锁存数据的RS触发器,PROM存储器。(掌握存储器的电路原理,如何通过总线时序访问)
准确理解了上述内容后,在后续学习微机原理的课程中,你会发现CPU的核心单元就是一个复杂点的时序逻辑,而外设资源的话,都是些组合逻辑或时序逻辑包起来的黑盒子。
1.3 代码托管
Git工具和GitHub使用。将代码保留一份到Github上,方便以后复用。慢慢你会发现,自己整理的代码就是最好的笔记。git教程推荐廖雪峰的git教程,简单易懂。国内的话,可以考虑 gitee。
给点小建议,对于复杂的逻辑,代码笔记中要有必要的注释。代码风格最好做到统一规范,写代码要像雷军一样自信,"我写的代码像诗一样优雅"。代码风格格式化工具,很多编辑器自带代码格式化功能,如 VSCode。也可以使用 CoolFormat 手动进行格式化。
2. 入门课程
2.1 51单片机
讲道理,目前Proteus仿真软件确实很强大,使用它学习51的书籍,教程,示例十分的多,非常适合学习。但我还是建议真心学习的的话,去淘宝上淘个实物开发板和模块,学生党经济能力一般的就上闲鱼,买个二手板子,包邮不超过50。为什么建议买实物呢?因为Proteus仿真毕竟是仿真,对于很多硬件上的电压、信号时序等要求不像实际电路严谨,或者说不够严苛。就好比i2c时序不是很符合从机的要求也能正常通信,但同样的程序放到实物单片机上就很有可能i2c通信不上。
这里再顺带手的介绍下51主要学习些什么?以及简单的学习步骤:
- 创建工程,学会如何编译,如何下载,理解sbit,sfr等51单片机特有的寄存器数据结构
- 假设使用的STC系列的单片,要学会去STC官网(http://stcmcu.com)下载官网资料,数据手册文档。官方下载工具、电路参考设计等资料。(从芯片厂商官网上获取学习的资源也是一项很重要的能力),或许51这样的单片机资料太多,基本你想要做的东西,别人早就做过了,官网的资料早就变成千万的人的博客文章,但以后学习一些不是热门的处理器,官网的资料就显得很权威也很重要了。
- 学习51单片机的IO模块,使用IO点灯(流水灯)、控制数码管、控制8*8点阵模块、按键输入。
- 学习51单片机的中断模块,先从最简单的外部中断,使用中断的方式识别按键事件。
- 学习51单片机的定时器模块,实现1s定时,实现简单的数字秒表,实现IO口输出PWM波。
- 学习51单片机的串口模块,掌握串口电平标准,TTL、RS232、USB电平标准,掌握串口波形组成,掌握波特率,多主机通信等概念
- 51基础模块学习完了后,就可以学习扩展模块了。可以使用IO口模拟各种各样的低速总线协议,如i2c协议、spi协议还有一些特定模块自定义的协议,如DS18B20温度传感器的单总线协议,加深对协议的理解。学习的过程可以通过买该协议对应的模块进行学习,尽量挑网上教程多的模块买,如i2c就买eeprom和mpu6050,spi就买flash。
- 学到这里,就可以做点小东西了,比如说旋转LED,循迹小车,遥控小车。最开始就跟着网上的教程学习,学习的第一步总是从模仿开始的。先模仿,再理解,再改进,最后吸收转化为自己的能力。
建议上述过程多花点时间,做到绝大部分地方都能搞懂,都能够理解。毕竟是基础,后面的学习是在其上进行扩展,基础学的好,后面有着触类旁通的功效。
2.2 微机原理(可选)
一般的小伙伴这个时候就会开始上手STM32了,但是我建议在上手STM32之前,先看看8086处理器的设计,即学习下《微机原理》这门课,我觉得还是很有必要的。微机原理,可以大概的了解的,CPU如何执行指令,如何通过地址总线、数据总线、控制总线访问内部寄存器,外部存储器,中断如何被响应,以及中断的具体内部处理过程。
2.3 STM32
接下来可以安安心心的学习STM32了,这个就比51要复杂了。但是不慌,本质和51是一样的东西,只是功能模块变复杂了,模块数量变多了。但是万变不离其宗,本质上模块无非就是组合逻辑或者是时序逻辑电路,而模块寄存器就是该逻辑电路的输入。我们只要看懂模块框图,将框图中的配置和相应的寄存器对应上,学习就是一样的。stm32单片机,推荐购买野火或者正点原子的开发板学习,并非打广告,而是教程确实讲的好。这个跟着视频一个一个模块学习就可以了。或者以作品为导向,做个平衡小车,OLED时钟等小玩意。
2.4 数据结构 & RTOS
裸机程序做完了就可以学学rtos小型的嵌入式操作系统了,野火和正点原子都有出书籍和视频教程的。学习RTOS之前,有需要的同学可以自行考虑下要不要学一下数据结构,不一定要学的很深,最起码队列和栈结构要了解,最好的话自己用c实现一遍。
2.5 PCB 绘制 & DIY 小作品
单片机这种简单的小板子推荐使用国产的 LCEDA。Altium Designer 更专业,但是是收费软件,替代方案为 KiCAD。
STM32 功能模块比较多,如果全部都学的话自然是最好的,但是怕单单是学习慢慢的会觉得无趣(看视频教程、分析源码、自己实现一遍、接着开始下一个知识点也是上述三个步骤),久了怕人会坚持不下来,渐渐的消磨了学习的激情。因此,学习STM32我建议以项目为导向,当然一些基本的GPIO、中断、i2c、LCD、Touch、ADC、TIMER等外设还是要先熟悉的。STM32可以做的东西就多了。大家可以在知乎上或者在各大电子论坛上搜索下有意思的电子小东西,挑自己感兴趣的做。比如说我比较感兴趣的有:1. 可调电子表 2. 自平衡小车 3. 四旋翼飞行器 4. 旋转LED 5. 红外遥控复制器 6. 自制STM32仿真器 7. NES游戏机 等等等。
既然以作品为导向,那自然也就需要自己打板了。打板子的,最近嘉立创在搞活动,真的好便宜呀,5元5片,全国包邮。打板的话,需要学习下 Altium Designer 软件,从此开始制作属于自己的小玩意。AD的资料网上也很多。我是看的郭天祥的AD6.9视频入门的。目前国产的立创 EDA 出了专业版,画画简单的电路板还是没有什么问题的。
DIY 的话,Arduino 也可以考虑,有 C 基础就可以轻松上手。
3. 提高课程(Linux)
单片机学的差不多,就可以开始嵌入式 Linux 学习了,仔细细分的话可以细分为嵌入式 Liunx 驱动开发和嵌入式 Linux 应用开发。
3.1 Ubuntu 入门
安装Ubuntu,学习Linux基础使用,我是看慕课网的Linux达人养成计划系列视频入门的,重点学习下以下内容:
- Linux 基本操作,常用命令
- Linux C 编程,能够使用 gcc 进行编译
- Makefile,推荐陈浩 《跟我一起写 Makefile》
- Shell 脚本
- 感兴趣入门下Python脚本
3.2 Linux 驱动
有了Linux使用基础,开始学习处理器,s3c2440处理器,购买开发板学习,推荐韦东山视频,跟着韦东山走,一期,二期,三期,毕业班视频。
主要的学习内容有:
- 裸机驱动,就理解为单片机就好了,性质是一样的,只不过这里不像 51 和 STM32 使用 IDE 进行编译和链接,而是自己使用交叉编译工具配合 Makefile 手动的编译链接。
- uboot 入门,学习通用的引导流程,熟悉 uboot cmd,bootcmd,环境变量,flash 烧写等。
- kernel 驱动,这里的 kernel 驱动和裸机驱动还是很大区别的,单片机驱动相对来说说仅仅只是看懂 SOC 手册,配置寄存器,但是内核驱动往往为了兼容大量的 SOC 主控,大量的外设厂商,存在一层软件抽象。在内核中,我们称之为子系统。子系统有很多内容,选自己工作相关的仔细研究即可,切勿贪多嚼不烂。
3.3 Linux 驱动移植
- rootfs 制作,基于 busybox 制作内核文件系统。
- uboot 移植,kernel 移植。
4. 提高课程(软件)
有了一定的嵌入式基础后,后面在实际工作中,你会发现,很多硬件强相关的驱动代码都是由物料供应商提供。举个例子,我之前在上海做手机开发,高通 SOC 方案驱动子系统非常的完整,有高通的一套标准在里面,而对应的手机物料供应商,比如LCD(屏幕)、TP(触摸)、Sensor(摄像头)、指纹、各类传感器,在出售物料的同时,会根据你的 SOC 主控方案直接提供可用的驱动程序(按照高通规则都匹配好了,MTK也是一样),很多硬件驱动代码,供应商全部帮你做好了。我们更多的是开发业务代码。
4.1 数据结构
基本的队列、链表、环形缓冲区这些是基本功了,建议自己实现一遍。不要忘了我之前提到的,自己曾今写过的代码就是最好的笔记。gitee 和 github 记得保留起来。这些代码会经常使用到,在不断的使用中,慢慢的修复缺陷,完善代码的鲁棒性。
4.2 设计模式
推荐 《Head First》,我看的是 Java 语言的版本。可以初步学习下 Java 语法再看。代码设计思想不受语言限制的,好书值得一看。
5. 积累与思考
5.1 知识体系库
慢慢的,当我进入一个细分的领域,音视频开发领域,就会发现,很多时候,不仅仅是熟练通用开发能力,即我上面提到的驱动开发、软件业务开发这些技能。很多业务依赖于你要懂专业知识可能得心应手,不然连代码中的数据结构为什么要如此设计都搞不明白。
因此但进入专业领域,可以尝试慢慢的将平时积累的知识组织起来,慢慢的积累,最开始可能自己也是一知半解,博客抄一抄,官方协议文档翻译翻译。但是知识就是这样的,最开始没有成体系之前,一知半解很正常,一旦到了一定的量,熟悉后,一旦知识串起来后,那种的融汇贯通的感觉是极其美妙的。
因此,建议平时学习的过程中,养成做笔记的好习惯。想要深入研究那一方面后,可以不断的积累学习,进行系统的整理,慢慢的等待融会贯通的那一日到来就可。我目前使用的语雀知识库,私人服务器搭建的是 showdoc 文档库。
5.2 文档规范 & 代码模块化(组件化)
不难发现,很多开源软件都配有详细的文档,从最简单的介绍这个软件是什么,有什么用,该怎么用,到注意事项,都写得一清二楚。甚至有的开源软件还会介绍内部的实现细节。
再参考我之前提到的,自己曾今写过的代码就是最好的笔记,我们可以不断的完善自己曾今写过的代码,慢慢的将独立功能的代码模块单独出来。方便自己以后在不同的项目复用。
复用的话,毕竟好记性不如烂笔头,代码核心思想,一个月两个月还能记得,时间久点别说核心思想了,可能连使用都不太记得怎么用了。这个时候就意识到了,代码配套文档介绍的重要性。毕竟在代码刚开发完成的时候,趁着思路清晰的时候,把文档写掉,注意事项记录的清清楚楚,明明白白后,后面复用将会方便很多。
提供一个我写的代码组件,我写的也不完善,最基本的要求,保证自己以后要用自己看的懂,这个要求讲道理不高吧。
mazcpnt/maz-debugcmd对应文档:
mazcpnt/maz-debugcmd |