打印

C 语言嵌入式系统编程修炼之道

[复制链接]
568|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
heping517|  楼主 | 2016-1-31 16:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
不同于一般形式的软件编程,嵌入式系统编程建立在特定的硬件平台上,势必要求其编程语言具备较强的硬件直接操作能力。无疑,汇编语言具备这样的特质。但是,归因于汇编语言开发过程的复杂性,它并不是嵌入式系统开发的一般选择。而与之相比,C语言-- 一种"高级的低级" 语言,则成为嵌入式系统开发的最佳选择。笔者在嵌入式系统项目的开发过程中,一次又一次感受到C语言的精妙,沉醉于C 语言给嵌入式开发带来的便利。
沙发
heping517|  楼主 | 2016-1-31 16:45 | 只看该作者
以通用处理器为中心的协议处理模块,用于网络控制协议的处理;

使用特权

评论回复
板凳
qiangg| | 2016-1-31 16:46 | 只看该作者
以数字信号处理器(DSP )为中心的信号处理模块,用于调制、解调和数/ 模信号转换。

使用特权

评论回复
地板
heping517|  楼主 | 2016-1-31 16:47 | 只看该作者
着眼于讨论普遍的嵌入式系统C 编程技巧,系统的协议处理模块没有选择特别的CPU ,而是选择了众所周知的CPU 芯片--80186,每一位学习过《微机原理》的读者都应该对此芯片有一个基本的认识,且对其指令集比较熟悉。80186 的字长是 16位,可以寻址到的内存空间为1MB,只有实地址模式。C 语言编译生成的指针为 32 位(双字),高 16 位为段地址,低16位为段内编译,一段最多64KB。

使用特权

评论回复
5
qiangg| | 2016-1-31 16:47 | 只看该作者
协议处理模块中的FLASH和RAM几乎是每个嵌入式系统的必备设备,前者用于存储程序,后者则是程序运行时指令及数据的存放位置。系统所选择的FLASH和RAM的位宽都为16位,与CPU 一致。

使用特权

评论回复
6
engao| | 2016-1-31 16:48 | 只看该作者
实时钟芯片可以为系统定时,给出当前的年、月、日及具体时间(小时、分、秒及毫秒),可以设定其经过一段时间即向CPU 提出中断或设定报警时间到来时向CPU 提出中断(类似闹钟功能)

使用特权

评论回复
7
qiangg| | 2016-1-31 16:48 | 只看该作者
NVRAM(非易失去性RAM)具有掉电不丢失数据的特性,可以用于保存系统的设置信息,譬如网络协议参数等。在系统掉电或重新启动后,仍然可以读取先前的设置信息。其位宽为8 位,比CPU 字长小。**特意选择一个与CPU 字长不一致的存储芯片,为后文中一节的讨论创造条件

使用特权

评论回复
8
engao| | 2016-1-31 16:48 | 只看该作者
UART 则完成CPU 并行数据传输与RS-232串行数据传输的转换,它可以在接收到[1~ MAX_BUFFER] 字节后向CPU 提出中断,MAX_BUFFER为UART芯片存储接收到字节的最大缓冲区。

使用特权

评论回复
9
qiangg| | 2016-1-31 16:49 | 只看该作者
键盘控制器和显示控制器则完成系统人机界面的控制

使用特权

评论回复
10
bboo| | 2016-1-31 16:50 | 只看该作者
嵌入式系统需要良好的软件开发环境的支持,由于嵌入式系统的目标机资源受限,不可能在其上建立庞大、复杂的开发环境,因而其开发环境和目标运行环境相互分离。因此,嵌入式应用软件的开发方式一般是,在宿主机(Host)上建立开发环境,进行应用程序编码和交叉编译,然后宿主机同目标机(Target)建立连接,将应用程序下载到目标机上进行交叉调试,经过调试和优化,最后将应用程序固化到目标机中实际运行。

使用特权

评论回复
11
engao| | 2016-1-31 16:50 | 只看该作者
CAD-UL 是适用于x86 处理器的嵌入式应用软件开发环境,它运行在Windows操作系统之上,可生成x86 处理器的目标代码并通过PC机的COM口(RS-232串口)或以太网口下载到目标机上运行,如图2 。其驻留于目标机FLASH存储器中的monitor程序可以监控宿主机Windows调试平台上的用户调试指令,获取CPU 寄存器的值及目标机存储空间、I/O 空间的内容。

使用特权

评论回复
12
bboo| | 2016-1-31 16:54 | 只看该作者
模块划分的"划"是规划的意思,意指怎样合理的将一个很大的软件划分为一系列功能独立的部分合作完成系统的需求。C语言作为一种结构化的程序设计语言,在模块的划分上主要依据功能(依功能进行划分在面向对象设计中成为一个错误,牛顿定律遇到了相对论),C 语言模块化程序设计需理解如下概念:

使用特权

评论回复
13
bboo| | 2016-1-31 16:57 | 只看该作者
某模块提供给其它模块调用的外部函数及数据需在.h 中文件中冠以extern 关键字声明;

使用特权

评论回复
14
bboo| | 2016-1-31 16:57 | 只看该作者
模块内的函数和全局变量需在.c 文件开头冠以static关键字声明;

使用特权

评论回复
15
bboo| | 2016-1-31 16:59 | 只看该作者
永远不要在.h 文件中定义变量!定义变量和声明变量的区别在于定义会产生内存分配的操作,是汇编阶段的概念;而声明则只是告诉包含该声明的模块在连接阶段从其它模块寻找外部函数和变量。

使用特权

评论回复
16
bboo| | 2016-1-31 16:59 | 只看该作者
/*module1.h*/
int a = 5; /*  在模块1 的.h 文件中定义int a */

/*module1 .c*/
#include "module1.h" /*  在模块1 中包含模块1 的.h 文件 */

/*module2 .c*/
#include  "module1.h" /*  在模块2 中包含模块1 的.h 文件 */

/*module3 .c*/
#include "module1.h" /*  在模块3 中包含模块1 的.h 文件 */

使用特权

评论回复
17
bboo| | 2016-1-31 17:01 | 只看该作者
以上程序的结果是在模块1 、2、3 中都定义了整型变量 a ,a 在不同的模块中对应不同的地址单元,这个世界上从来不需要这样的程序

使用特权

评论回复
18
bboo| | 2016-1-31 17:02 | 只看该作者
/*module1.h*/
extern int a; /*  在模块1 的.h 文件中声明int a */

/*module1 .c*/
#include "module1.h" /*  在模块1 中包含模块1 的.h 文件 */
int a = 5; /*  在模块1 的.c 文件中定义int a */

/*module2 .c*/
#include "module1.h" /*  在模块2 中包含模块1 的.h 文件 */

/*module3 .c*/
#include "module1.h" /*  在模块3 中包含模块1 的.h 文件 */

使用特权

评论回复
19
engao| | 2016-1-31 17:02 | 只看该作者
这样如果模块1 、2 、3 操作a 的话,对应的是同一片内存单元。

  一个嵌入式系统通常包括两类模块:

  (1 )硬件驱动模块,一种特定硬件对应一个模块;

  (2 )软件功能模块,其模块的划分应满足低偶合、高内聚的要求。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

90

主题

648

帖子

0

粉丝