嵌入式软件开发学习路线

在这个领域学习过程中碰了不少壁
大学里的三年里 笔者也只能算是刚入门
这篇文章会随着我自己的学习不断地更新
这是我觉得比较好的学习路线 希望初学者能少走弯路
如有说得不对的地方 还请帮忙指正,谢谢


1. 数电模电、c语言、数据结构

嵌入式软件会直接和硬件打交道 数电模电是基本功 多懂点不会亏
c语言是基础中的基础 多阅读别人的程序可以加速学习(特别是优秀的开源工程)
数据结构了解一些常用的即可

2. 51单片机/8051汇编

这部分学习很有必要 能让你对“我们是怎样让硬件工作的”有个深刻的了解
学习一种复杂指令集 对以后精简指令集的学习有帮助

3. 常见外围电路、外设、外部总线学习

一些常见的外围电路:
三极管开关电路、继电器、步进电机驱动(H桥)、IO扩展等等 数电模电里都会教
学习这些东西的过程中 同时也会了解到一些时序、串行并行通讯的概念了
这也是锻炼自己看数据手册的机会(顺便说一下英语能力很重要 尝试阅读英文手册吧)
外部总线,比如I2C、SPI
比如现在很多IC都用I2C来通讯 一通百通
用外部总线做通讯的时候 有时候还有自己设计封包的需要 可以参考网络封包

4. 嵌入式程序 一些常见的编程思想

学到这里就有能力制作一些小作品了
这时候有必要学一些必要的思想 这里列举一些常见的
学习的途径主要还是积累吧

a. 模块化程序设计

初学者写的代码一般都很糟糕 难以阅读
其实一开始只要做到合理的函数、变量命名、合理的模块划分即可
在了解扇入扇出、高内聚低耦合、重用读这些基本概念之后 还是得多阅读别人的代码才能有提高

b. 状态机

数电里会提到状态机这个概念 我们在编程时经常要用到  
一个平面状态机的简单例子,就是自锁开关 
两个状态——“按下”、“弹起”,用户传入的信息就一个“press”,该消息传入则切换状态。

状态机能做什么? 其实我们经常写这样的东西,以下程序里circle就是有3个状态的状态机
1
2
3
4
5
6
7
8
9
10
11
12
static uint8_t circle = 0;

if (0 == circle) {
/* do something */
circle++;
} else if (1 == circle) {
/* do something */
circle++;
} else if (2 == circle) {
/* do something */
circle = 0;
}
可以去看看《Practical Statecharts in C/C++》 很有启发作用

c. 抽象、以及一些简单的“设计模式” 以及如何在c下实现

抽象其实就是把具体的东西包装起来 比如库函数把寄存器操作封装起来 就是一层抽象

设计模式并不是什么深奥的东西
它只是一个软件工程师的经验总结
帮助我们在遇到某些情况时找到合理的解决方法
前人总结好的东西 总有需要用到的地方
比如单例模式和多例模式:
在c下全局变量就是单例模式 整个程序里就只存在一份
而文件操作中用到的“FILE”就是多例模式 可以操作多个文件 
一个实例就是一个结构体变量 相关的操作函数通常是这样的形式
`void cat_catch (struct cat *pcat);`

5. ARM CM3核单片机(如NXP-LPC系列和STM32)

ARM-CM3核是目前低成本嵌入式开发的常用内核
32位单片机 常跑裸机程序或使用小巧的RTOS进行开发
从存储空间和性能上来说 资源比8位机来说丰富了很多
相应的 寄存器复杂度也会上升 厂商会提供固件库

6. RTOS(实时系统)学习

在没有RTOS的情况下开发 有多任务需求时 我们常设计状态机,实时性高的突发任务放在中断里完成
任务复杂的情况下 设计一个合理的状态机就比较难了 而且多个任务间的运行时长会互相影响
举个例子: 我们做人机交互时常用GUI,“响应用户操作”和“具体功能”就是同时进行的两个任务
如果“具体功能”正在执行一个几秒钟的的操作不返回,“响应用户操作”就会受到影响。
换在别的场合,可能就不是影响用户体验那么简单了。
放在RTOS下就简单多了
RTOS的学习 能帮助理解许多编程上的概念:多线程、线程安全、同步互斥等等

有些实时系统不仅提供多任务支持,还提供一些配套的硬件抽象层、中间件(USB TCP/IP 文件系统 GUI等等)
会为开发提供不少便利 阅读它们的代码 也是一种很好的学习方式

7. 学习工程思想

到这里应该积累了一些开发经验了
会发现在在项目规模变大之后 有很多需要注意的地方
模块划分、编译管理、跨平台、可移植性、代码风格、源代码管理……每个都有学问在里面

8. GNU工具、Linux、现代编程语言学习

学习一些可以高效开发的现代编程语言(比如python)
可以快速做出一些简单的工具帮助开发

为什么要学Linux
Linux在嵌入式开发中常用做目标系统
而最近开发工具也有转向linux的趋势 比如gcc-arm交叉编译器
还有一个重头 就是学习makefile(顺便可以把编译的过程学习一遍)
笔者最近接触开源工程比较多 有很多是用makefile编译的 想要玩转它们 还是要搞清楚makefile的..
推荐《程序员的自我修养——链接、装载与库》

GNU有很多现成的工具 学习起来可能比图形化的工具困难些 但是会用之后能让开发效率UP UP..

9. more…..

无止尽地学习