作者:叫我一声小明哥
日期:某个不想学习的夜晚前言
曾听说过,人生总是要向前看。可笔者发现,随着年龄的增长,在向前看的同时,向后看的次数也越发的频繁。回首自己走过的路,或是艰辛,或是平凡,这都不重要,关键这是自己的路,也是自己想走的路。
本人从大二开始接触嵌入式,懵懵懂懂到如今工作两年,走了近七年的嵌入式之路。没有很辉煌的成绩,也没有自我满足,写这篇文章也没有其他的杂七杂八的目的,就是一份对自己定期的总结报告。
同时希望大神能够对笔者理解的误区和错误及时指出,也希望本文能够给更多彷徨的学生,刚入门的嵌入式工作者一些建议。
初探嵌入式
第一个问题,嵌入式系统的定义是什么?百度百科给出嵌入式系统的定义用于控制、监视或者辅助操作机器和设备的装置。笔者理解,就现在的社会状况而言,嵌入式系统随处可见。手机、电脑、电视、汽车等等所有看起来不那么low的用电设备(比如说10块钱买的台灯)基本能归入嵌入式系统。无论是虚拟技术、智能设备、云计算、大数据、机器人、无人机、装备制造业等等,嵌入式系统都有涉及。随着物联网时代的加速,笔者认为嵌入式系统或许迎来一个新的小高潮。
第二个问题,嵌入式系统包括哪些方向?笔者认为,一个完整的嵌入式系统包括下位机、上位机。下位机就是电路板及其内部程序,上位机就是人机交互界面及其内部程序。
第三个要点,笔者认为,如果没有强烈的学习冲动和学习能力,不建议从事嵌入式行业。
下位机
下位机主要包括到PCB设计和下位机软件设计。
PCB设计当归功于嵌入式硬件工程师。印制电路板,行业内简称PCB。笔者只用过AltiumDesigner设计原理图和PCB,某乎里有帖子提到PADS和candence在设计时会更好用一些,笔者没用过,不做评述。嵌入式硬件工程师除了设计PCB之外,还需要有基本的嵌入式软件设计能力,根据自己设计的PCB完成PCB接口功能调试。所以,一名嵌入式硬件工程师的技术积累应该包括:各种芯片的datasheet,各种芯片的最小电路,各种主控芯片的接口驱动测试程序等。当然,市面上各种开发板是一个很好的参考,但是开发板的设计并不一定能够保证你的产品能够通过各种干扰和稳定性测试,且长时间保持稳定运行。嵌入式硬件设计很有成就感,但相对应难度系数比较高。笔者的硕士导师曾经说过,他在搭模拟电路的年代,就因为某个三极管的摆放位置导致PCB输出的电流一直不稳定。
下位机的软件设计当归功于嵌入式软件工程师。下位机的软件设计主要分为底层驱动软件设计和应用层软件设计。当然,也有人认为底层驱动软件设计又可分为系统内核设计和接口驱动设计,笔者仍按照前述分类进行阐述个人理解。对于底层驱动软件设计来说,当前下位机软件能用的系统内核有很多,μClinux、freertos等等开源的嵌入式实时操作系统有很多,网上移植成功的demo也有很多,主控芯片也告别了89C51那种嵌入式的“开荒”时代,所以对设计一个新系统的需求越来越少。但是对当前的开源系统(如linux)裁剪,移植的需求越来越多,所以工程师可以没有一个好的想法设计一个新的操作系统,但是一定要懂操作系统,会操作系统。对于应用层软件设计,就是根据客户需求,在底层软件的基础上,完成功能设计。笔者认为,一名嵌入式软件工程师的技术积累要包括熟悉操作系统基本原理,能看懂硬件电路,各种接口驱动程序,各种数据结构及应用算法等。一名合格的嵌入式软件工程师,写文档的时间要比写代码的时间长。
上位机
笔者接触过的上位机包括计算机,工控机,触摸屏(显示屏)。
计算机与工控机类似,都是用高级语言构建“友好的人机交互界面”。笔者接触过VC++6.0/MFC,C#.Net,QT等。由于此部分上位机软件的运行多依托PC机(例如Windows系统环境等),基本上比下位机的硬件配置高很多,因此可扩展性很高,可以内嵌复杂度很高的算法,可以理解为偏纯软件方向。触摸屏则一般应用在工业装备制造(列车司机室)或者智能随身设备(手机)。
注:关于智能手机,计算机等究竟是否属于嵌入式系统,仁者见仁智者见智。但根据百度百科的定义和笔者的理解,应该算。但是web开发、前端开发等应该不算。
由于笔者仅在读硕士期间,做过几个项目的上位机开发,工作内容与之无关,因此对工作的技术积累不做评述。
入门嵌入式
了解了什么是嵌入式之后,仍想从事嵌入式行业的读者,应该考虑下一个问题,究竟怎么学习嵌入式。笔者工作之后,接触了比较多的嵌入式软件设计和部分嵌入式硬件设计。因此本章只对下位机进行个人见解的阐述,对上位机软件设计不做评述。
嵌入式硬件设计
简述硬件设计流程。
1. 安装Altium Designer,并破解。
2. 建立一个PCB工程,并在工程下添加原理图和PCB。
3. 设计原理图,包括元器件的封装等。
4. 生成并绘制PCB(强烈不推荐自动生成)
5. 与PCB生产厂家联系,制作PCB(不提厂家,以免打广告)
对于AD的基本操作,不是本文重点,这里不予叙述。
讲一点从前人和自己总结的原理图和PCB绘制经验。
原理图熟悉使用Sheet Symbol 和Port很重要,将原理图模块化,非常方便后期维护、升级和文档整理;
使用一些常用的快捷键(如PL)能够有效提高效率,快捷键自行百度;
原理图设计不正确,PCB一定有问题,原理图设计正确PCB不一定问题;
使用按条件选取,自动编号等常用功能有效提高效率,常用功能自行百度;
据说PCB布线敢走直角的要么是大神,要么是菜鸟;
4层板规则:TOP-GND-PWR-BOT或者TOP-PWR-GND-BOT
6层板规则:TOP-SIG1-GND-SIG2-PWR-BOT(笔者只用过这一种规则)
8层板规则:没画过
笔者了解到,一般有高速信号的时候,会用6层甚至8层板。对于PCB板层分布的原理,笔者没有进行深入的研究和测试,不予详述。
嵌入式软件设计
简述软件设计流程。以STM32为例。
1. 接口驱动软件设计(新手不建议封装)
2. 根据需求设计应用软件
3. 将程序下载到MCU里
学会了中断和各接口驱动,就可以称自己为一名合格的入门级嵌入式软件工程师。
就STM32而言,建议使用库函数版,软件设计非常简单。流程大致如下:配置时钟,配置GPIO,配置接口结构,配置中断,使能。
切记,定义变量要通俗易懂;(笔者习惯使用模块_功能,如:List_InsertNode表示链表插入节点)
切记,一个函数只完成一项功能;
切记,写好函数注释文档。
软件入门比较简单,看看开发板的配套教程,在网上查一查相关配置,基本上都能完成定时器、串口、CAN、GPIO、PWM等功能。
中级嵌入式
目前,笔者自认为嵌入式软件设计方向可以称得上中级嵌入式,故本章只针对嵌入式软件设计的一些进阶的内容进行介绍。
指针与数据结构
笔者将指针与数据结构放在一起,是因为笔者在进行数据结构学习的期间,很自然的熟悉了对指针的操作。然后再回过头来学习指针,简直如鱼得水。
指针被称为C语言的精髓,C语言凭借指针在各种编程语言的排行榜占据一席之地。
常用的数据结构,链表,队列,堆栈,树,图。用合适的数据结构存储合适的数据,会有意想不到的效果。比如利用堆栈的先进后出特性解决迷宫问题;比如用队列的先进先出特性设计缓冲区等等。
这里推荐两本书《C和指针》《嵌入式系统软件设计中的数据结构》,网上免费的电子版资源有很多,无论是新手还是进阶阅读学习都比较适合。笔者《C和指针》读过三遍,《嵌入式系统软件设计中的数据结构》读过一遍。
操作系统
笔者所描述的操作系统均指嵌入式实时操作系统,以下简称RTOS。
时下的RTOS大部分都是依托优先级调度法和时间片来进行任务调度(笔者见识有限)。 优先级调度法就好像中断一样,高优先级的任务总能打断低优先级的任务,以此来满足系统高实时性的需求。
笔者建议学习RTOS一定要读源码(FreeRTOS,uCosII,Linux等至少一种),当下设计一款新的操作系统需求几乎为0,但是对现有操作系统的裁剪、移植的需求越来越多,因此最低标准一定要懂原理。
如果想学习RTOS这块的设计方法,笔者推荐某乎上的一篇帖子https://www.zhihu.com/question/25628124/answer/133388181,讲的还不错。
在学习RTOS之前,笔者建议研究一下STM32的启动文件和core_cm3文件,笔者对底层的深入就是从启动文件开始的。学习RTOS期间,应该会接触到一些其他的东西,笔者认为BSP和BootLoader 是比较实用,且重要的。
嵌入式Linux
因为Linux开源很强大,所以时下嵌入式Linux开发的需求越来越多。对于Linux,笔者也不过自学了半年左右的时间,太高深的不予评述。如果读者还没有接触过嵌入式软件开发,笔者建议直接在Linux环境下进行学习和开发。
推荐一本电子书《嵌入式Linux-操作系统基础教程》,很适合像笔者一样的初学者。无论是Windows还是Linux系统下编程,操作逻辑流程都是一样的。搭建程序编辑环境,搭建编译环境,下载程序。
笔者在嵌入式Linux方面仅仅是熟悉,理解不够深刻,不敢妄加评述,不过还是建议读者有时间可以学习嵌入式Linux。