给排水设计图例管道图例字母根据什么来定的,比如CW表示市政给水管,H表示消防给水管,DW表示生活排水管等等之类。

嵌入式技术
嵌入式新手教程
嵌入式应用手册
嵌入系统的定义
嵌入式系统(Embedded System)是以应用为中心,以计算机技术为基础,系统的软硬件可剪裁,适用于应用系统对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。
嵌入式系统主要分为两个部分:嵌入式硬件部分和嵌入式软件部分。嵌入式软件部分主要由嵌入式操作系统,嵌入式开发调试环境和嵌入式应用软件构成;嵌入式硬件部分主要由嵌入式,嵌入式外围设备等构成。
嵌入式系统的特点
随着信息产业和的发展,嵌入式应用的发展也得到了蓬勃和快速的发展。其特点主要表现在两个方面:
(1) 多样化,广泛化;嵌入式应用领域已应用到社会的各个领域如信息家电、工业控制、通信和智能终端等
(2) 专用化,个性化;嵌入式应用很多是面向特定的应用,如实时控制、低功耗管理、可靠安全控制等,这些应用领域使得嵌入式应用具有专用性和个性特点。
嵌入式系统应用最早是基于的简单控制应用,因为单片机上的资源有限,因此在程序上采用的是前后台的控制设计。随着嵌入式应用越来越复杂化,现在很多嵌入式应用又引进了嵌入式操作系统,利用嵌入式操作系统提供的特有的机制来满足嵌入式一些特定的应用,例如,多任务调度,实时控制和可靠冗余处理等。嵌入式开发不同于桌面程序的开发,一般都是通过交叉调试模式来开发,因此对于嵌入式也有特殊的要求。
嵌入式应用的多样化主要体现在嵌入式设备主控和外围设备的多样化,目前,嵌入式设备的主控芯片类型包括四类:、嵌入式、处理器和片上系统SOC。嵌入式外围设备种类繁多,而且不同的嵌入式应用有不同的外挂设备,为了支持这些不同的外挂设备就必须有这些不同设备的板级支持包BSP (board support package).
嵌入式的专用化和个性化一方面体现在嵌入式硬件有专用和个性的支持,另一方面体现在软件上要提供相应的支持。
嵌入式系统的分类
嵌入式系统其分类也可以从硬件和软件进行划分:
  从硬件方面来讲,各式各样的嵌入式是嵌入式系统硬件中的最核心的部分,而目前世界上具有嵌入式功能特点的处理器已经超过种,流行体系结构包括,MPU等30多个系列。鉴于嵌入式系统广阔的发展前景,很多半导体制造商都大规模生产嵌入式处理器,并且公司自主设计处理器也已经成为了未来嵌入式领域的一大趋势,其中从、到有着各式各样的品种,速度越来越快,性能越来越强,价格也越来越低。目前嵌入式处理器的寻址空间可以从64kB到16MB,处理速度最快可以达到 MIPS,封装从8个引脚到144个引脚不等。
  嵌入式系统的核心是嵌入式。嵌入式微处理器一般就具备以下4个特点:
  1)对实时多任务有很强的支持能力,能完成多任务并且有较短的中断响应时间,从而使内部的代码和实时内核心的执行时间减少到最低限度。
  2)具有功能很强的存储区保护功能。这是由于嵌入式系统的软件结构已模块化,而为了避免在软件模块之间出现错误的交叉作用,需要设计强大的存储区保护功能,同时也有利于软件诊断。
  3)可扩展的处理器结构,以能最迅速地开展出满足应用的最高性能的嵌入式微处理器。
  4)嵌入式微处理器必须功耗很低,尤其是用于便携式的无线及移动的计算和通信设备中靠供电的嵌入式系统更是如此,如需要功耗只有mW甚至μW级。
  根据其现状,嵌入式处理器可以分成下面几类:
  ◆嵌入式微处理器( Processor Unit,MPU)
  嵌入式微处理器是由通用计算机中的演变而来的。它的特征是具有32位以上的处理器,具有较高的性能,当然其价格也相应较高。但与计算机处理器不同的是,在实际嵌入式应用中,只保留和嵌入式应用紧密相关的功能硬件,去除其他的冗余功能部分,这样就以最低的功耗和资源实现嵌入式应用的特殊要求。和工业控制计算机相比,嵌入式微处理器具有体积小、重量轻、成本低、可靠性高的优点。目前主要的嵌入式处理器类型有Am186/88、386EX、SC-400、 PC、、MIPS、ARM/ StrongARM系列等。
  其中Arm/StrongArm是专为手持设备开发的嵌入式微处理器,属于中档的价位。
  ◆嵌入式(controller Unit, MCU)
  嵌入式微控制器的典型代表是单片机,从70年代末单片机出现到今天,虽然已经经过了20多年的历史,但这种8位的器件目前在嵌入式设备中仍然有着极其广泛的应用。单片片内部集成ROM/EPROM、RAM、、总线逻辑、定时/、看门狗、I/O、串行口、脉宽调制输出、A/D、D/A、Flash RAM、等各种必要功能和外设。和嵌入式微处理器相比,微控制器的最大特点是单片化,体积大大减小,从而使功耗和成本下降、可靠性提高。微控制器是目前嵌入式系统工业的主流。微控制器的片上外设资源一般比较丰富,适合于控制,因此称微控制器。
  由于MCU低廉的价格,优良的功能,所以拥有的品种和数量最多,比较有代表性的包括8051、MCS-251、MCS-96/196/296、P51XA、C166/167、68K系列以及 MCU 8XC930/931、C540、C541,并且有支持I2C、CAN-Bus、及众多专用MCU和兼容系列。目前MCU占嵌入式系统约70%的市场份额。近来Atmel出产的Avr单片机由于其集成了FPGA等器件,所以具有很高的性价比,势必将推动单片机获得更高的发展。
  ◆嵌入式DSP处理器(Embedded Digital Signal Processor, EDSP)
  DSP处理器是专门用于信号处理方面的处理器,其在系统结构和指令算法方面进行了特殊设计,具有很高的编译效率和指令的执行速度。在数字滤波、FFT、谱分析等各种上DSP获得了大规模的应用。
  DSP的理论算法在70年代就已经出现,但是由于专门的DSP处理器还未出现,所以这种理论算法只能通过MPU等由分立元件实现。MPU较低的处理速度无法满足DSP的算法要求,其应用领域仅仅局限于一些尖端的高科技领域。随着大规模技术发展,1982年世界上诞生了首枚DSP。其运算速度比MPU快了几十倍,在语音合成和编码解码器中得到了广泛应用。至80年代中期,随着CMOS技术的进步与发展,第二代基于CMOS工艺的DSP芯片应运而生,其存储容量和运算速度都得到成倍提高,成为语音处理、图像硬件处理技术的基础。到80年代后期,DSP的运算速度进一步提高,应用领域也从上述范围扩大到了通信和计算机方面。90年代后,DSP发展到了第五代产品,集成度更高,使用范围也更加广阔。
  目前最为广泛应用的是TI的TMS320C/C5000系列,另外如Intel的MCS-296和Siemens的TriCore也有各自的应用范围。
  ◆嵌入式片上系统(System On Chip)
  SoC追求产品系统最大包容的集成器件,是目前嵌入式应用领域的热门话题之一。SOC最大的特点是成功实现了软硬件无缝结合,直接在处理器片内嵌入操作系统的代码模块。而且SOC具有极高的综合性,在一个硅片内部运用VHDL等硬件描述语言,实现一个复杂的系统。用户不需要再像传统的系统设计一样,绘制庞大复杂的板,一点点的连接焊制,只需要使用精确的语言,综合时序设计直接在器件库中调用各种通用处理器的标准,然后通过仿真之后就可以直接交付芯片厂商进行生产。由于绝大部分系统构件都是在系统内部,整个系统就特别简洁,不仅减小了系统的体积和功耗,而且提高了系统的可靠性,提高了设计生产效率。
  由于SOC往往是专用的,所以大部分都不为用户所知,比较典型的SOC产品是Philips的Smart XA。少数通用系列如Siemens的TriCore,Motorola的M-Core,某些ARM系列器件,Echelon和Motorola联合研制的Neuron芯片等。
  预计不久的将来,一些大的芯片公司将通过推出成熟的、能占领多数市场的SOC芯片,一举击退竞争者。SOC芯片也将在声音、图像、影视、网络及系统逻辑等应用领域中发挥重要作用。
  从软件方面划分,主要可以依据操作系统的类型。目前嵌入式系统的软件主要有两大类:实时系统和分时系统。其中实时系统又分为两类:硬实时系统和软实时系统。
  实时嵌入系统是为执行特定功能而设计的,可以严格的按时序执行功能。其最大的特征就是程序的执行具有确定性。在实时系统中,如果系统在指定的时间内未能实现某个确定的任务,会导致系统的全面失败,则系统被称为硬实时系统。而在软实时系统中,虽然响应时间同样重要,但是超时却不会导致致命错误。一个硬实时系统往往在硬件上需要添加专门用于时间和优先级管理的,而软实时系统则主要在软件方面通过编程实现时限的管理。比如Windows CE就是一个多任务分时系统,而Ucos-II则是典型的实时操作系统。
  当然,除了上述分类之外,还有许多其他分类方法,比如从应用方面分为工业应用和消费电子等,在这里就不一一累述了。
嵌入式系统的应用
嵌入式系统技术具有非常广阔的应用前景,其应用领域可以包括:
  1.工业控制:
  基于嵌入式的工业自动化设备将获得长足的发展,目前已经有大量的8、16、32 位嵌入式在应用中,网络化是提高生产效率和产品质量、减少人力资源主要途径,如工业过程控制、数字机床、电力系统、电网安全、电网设备监测、石油化工系统。就传统的工业控制产品而言,低端型采用的往往是8位。但是随着技术的发展,32位、64位的逐渐成为工业控制设备的核心,在未来几年内必将获得长足的发展。
  2.交通管理:
  在车辆导航、流量控制、信息监测与汽车服务方面,嵌入式系统技术已经获得了广泛的应用,内嵌模块,模块的移动定位终端已经在各种运输行业获得了成功的使用。目前GPS设备已经从尖端产品进入了普通百姓的家庭,只需要几千元,就可以随时随地找到你的位置。
  3.信息家电:
  这将称为嵌入式系统最大的应用领域,冰箱、空调等的网络化、智能化将引领人们的生活步入一个崭新的空间。即使你不在家里,也可以通过电话线、网络进行远程控制。在这些设备中,嵌入式系统将大有用武之地。
  4.家庭智能管理系统:
  水、电、煤气表的远程自动抄表,安全防火、防盗系统,其中嵌有的专用将代替传统的人工检查,并实现更高,更准确和更安全的性能。目前在服务领域,如远程点菜器等已经体现了嵌入式系统的优势。
  5.POS网络及商务:
  公共交通无接触(Contactless Smartcard, CSC)发行系统,公共电话卡发行系统,自动售货机,各种智能ATM终端将全面走入人们的生活,到时手持一卡就可以行遍天下。
  6.环境工程与自然:
  水文资料实时监测,防洪体系及水土质量监测、堤坝安全,地震监测网,实时气象信息网,水源和空气污染监测。在很多环境恶劣,地况复杂的地区,嵌入式系统将实现无人监测。
  7.机器人:
  嵌入式芯片的发展将使机器人在微型化,高智能方面优势更加明显,同时会大幅度降低机器人的价格,使其在工业领域和服务领域获得更广泛的应用。
  这些应用中,可以着重于在控制方面的应用。就远程家电控制而言,除了开发出支持TCP/IP的嵌入式系统之外,家电产品控制协议也需要制订和统一,这需要家电生产厂家来做。同样的道理,所有基于网络的件都需要与嵌入式系统之间实现,然后再由嵌入式系统来控制并通过网络实现控制。所以,开发和探讨嵌入式系统有着十分重要的意义。
USB转CAN 说明书
USB2CAN 使用说明书 V1.1
一.概述 USB2CAN 是 USB 和 CAN 总线数据相互转换的模块,通过 USB 总线与 PC 机连接, 应用于基于 CANBUS 的现场总线应用领域,集成有一个 USB ,两个 CAN 接口。总线 接口为光电隔离,并带有 ESD 保护。该模块体积小,即插即用,自动配置,总线供电 等优点,另外上位机软件操作简单,功能强大。 典型应用有:CAN-bus 网络诊断与测试,汽车应用,电力通讯网络,工业控制设备, CANBUS 实验室,智能楼宇等。
二.功能 1.USB 与CAN 总线的协议转换; 2.USB 接口支持,兼容USB1.1; 3.CAN接口:2路CAN通道; 4.支持CAN2.0A 和CAN2.0B 协议,支持标准帧和扩展帧; 5.支持双向传输,CAN 发送、CAN 接收; 6.支持数据帧,远程帧格式; 7.CAN控制器波特率在5Kbps-1Mbps 之间连续可选,可以软件配置; 8.CAN 总线接口采用光电隔离、DC-DC 隔离; 9.最大流量为每秒钟 帧CAN 总线数据; 10.USB 总线直接供电,无需外部电源; 11.绝缘电压:Vrms; 12.和CAN接口带ESD保护; 12.工作温度:0~70℃; 13.模块尺寸:80*50mm,非常小巧; 14.上位机软件安装方便、操作简单、功能强大。
三.硬件说明 硬件实物为图 3.1,接口示意图见图 3.2
输入接口:USB,直接连接 输出接口: CAN1_H:接 CAN 信号正 CAN1_L:接 CAN 信号负 CAN0_H:接 CAN 信号正 CAN0_L:接 CAN 信号负
四.上位机软件使用说明 1.驱动安装 首& 先& 下& 载& 微& 软& 插& 件&& Microsoft&.NET&& Framework&& 并& 安& 装& ,& 地& 址& 为/download/5/6/7/-759e-473e-bf8f-a/dotnetfx.exe本模块使用 USB 的 HID 类,电脑第一次插入本模块的 USB 接口,会自动寻找并配置。 如图 4.1。
稍等片刻,打开 CAN Tool.exe,软件界面如图 4.2,此时驱动安装成功。
2.设置 CAN 波特率。 参数设置-&CAN 参数设置,如图 4.3,进入 CAN 波特率设置窗口图 4.4。
如图 4.4,根据需要设置 CAN0 或 CAN1 波特率,输入波特率后,直接点”设置”来配置。 如果用户对波特率各个参数有严格要求,可以点”手动选择”来挑选波特率配置,如图 4.5,最 后点”设置”来配置,如图 4.6。
2.验收设置 如果用户只想接收指定 CANID 的帧,可以设置硬件验收滤波器。 参数设置-&验收滤波器设置,进入验收滤波器设置窗口。如图 4.7,4.8。
可以设置 4 种类型的 CAN 验收滤波器: 1 单个标准帧:单独的一个标准帧,只需设置一个 CANID 2 标准帧组:一段范围内的标准组,需设置 2 个 CANID,如 0xx 单个扩展帧: 单独的一个扩展帧,只需设置一个 CANID 4 扩展帧组: 一段范围内的扩展组,需设置 2 个 CANID,如 0xx &如图图 4.9 为设置好的例子。
最后在主窗口打开验收滤波器,如图 4.10
3.发送文件 主窗口点”发送文件”,见到文件编辑窗口,如图 4.11 在文件编辑窗口,点”插入”,加入需要发送的帧。 文件编辑完毕后,可以通过菜单”文件”来执行”新建”,”打开”,”保存”,”另存为”等操作。设置循环方式。 最后点”开始”执行连续发送。如图 4.12。
五.产品销售清单 1)USB 转 CAN 板卡一块。 2)USB 一根,PC 可以与 USB2CAN 卡直连。
六.技术支持与服务 Email:&&&
QQ:&质保服务: 货到 7 日内无条件退货;一年内成本维修或更换;终身技术支持服务。 但下列情况不属于质保服务范围: 1.& 因意外因素或使用不当造成损坏, 包括操作失误、进液、划伤、破裂、磕碰、不正确插拔 等。 2.有明显元器件拆卸、更换的痕迹,有明显板卡、烧毁的痕迹。
GNU ARM 汇编指令
第一部分 Linux下汇编语法尽管在Linux下使用C或C++编写程序很方便,但汇编源程序用于系统最基本的初始化,如初始化堆栈指针、设置页表、操作 ARM的协等。初始化完成后就可以跳转到C代码执行。需要注意的是,GNU的汇编器遵循AT&T的汇编语法,可以从GNU的站点(www.gnu.org)上下载有关规范。一. Linux汇编行结构任何汇编行都是如下结构:[:] [} @ comment[:] [} @ 注释Linux ARM 汇编中,任何以冒号结尾的标识符都被认为是一个标号,而不一定非要在一行的开始。【例1】定义一个"add"的函数,返回两个参数的和。.sec .text, “x”. add @ give the symbol add external linkageadd:ADD r0, r0, r1 @ add input argumentsMOV pc, lr @ return from subroutine@ end of program二. Linux 汇编程序中的标号标号只能由a~z,A~Z,0~9,“.”,_等字符组成。当标号为0~9的数字时为局部标号,局部标号可以重复出现,使用方法如下:标号f: 在引用的地方向前的标号标号b: 在引用的地方向后的标号【例2】使用局部符号的例子,一段循环程序1:& subs r0,r0,#1 @每次循环使r0=r0-1& bne 1f @跳转到1标号去执行局部标号代表它所在的地址,因此也可以当作变量或者函数来使用。三. Linux汇编程序中的分段(1).section伪操作用户可以通过.section伪操作来自定义一个段,格式如下:&.section section_name [, "flags"[, %type[,flag_specific_arguments]]]每一个段以段名为开始, 以下一个段名或者文件结尾为结束。这些段都有缺省的标志(flags),可以识别这些标志。(与armasm中的AREA相同)。下面是ELF格式允许的段标志&标志& 含义a 允许段w 可写段x 执行段【例3】定义段&.section .mysection @自定义数据段,段名为 “.mysection”&.align 2&strtemp:&.ascii "Temp string \n\0"(2)汇编系统预定义的段名.text @代码段.data @初始化数据段.bss @未初始化数据段.sdata @.sbss @需要注意的是,源程序中.bss段应该在.text之前。四. 定义入口点汇编程序的缺省入口是 start标号,用户也可以在连接脚本文件中用ENTRY标志指明其它入口点。【例4】定义入口点.section.data& initialized data here&.section .bss& uninitialized data here&.section .text.globl _start_start:&instruction code goes here&五. Linux汇编程序中的宏定义格式如下:&.macro 宏名 参数名列表 @伪指令.macro定义一个宏& 宏体&.endm @.endm表示宏结束如果宏使用参数,那么在宏体中使用该参数时添加前缀“\”。宏定义时的参数还可以使用默认值。可以使用.exitm伪指令来退出宏。【例5】宏定义.macro SHIFTLEFT a, b.if \b & 0MOV \a, \a, ASR #-\b.exitm.endifMOV \a, \a, LSL #\b.endm六. Linux汇编程序中的常数(1)十进制数以非0数字开头,如:123和9876;(2)二进制数以0b开头,其中字母也可以为大写;(3)八进制数以0开始,如:;(4)十六进制数以0x开头,如:0xabcd,0X123f;(5)字符串常量需要用引号括起来,中间也可以使用转义字符,如: “You are welcome!\n”;(6)当前地址以“.”表示,在汇编程序中可以使用这个符号代表当前指令的地址;(7)表达式:在汇编程序中的表达式可以使用常数或者数值, “-”表示取负数, “~”表示取补,“&&”表示不相等,其他的符号如:+、-、*、 /、%、&、&&、&、&&、|、&、^、!、==、&=、&=、&&、|| 跟C语言中的用法相似。七. Linux下ARM汇编的常用伪操作在前面已经提到过了一些为操作,还有下面一些为操作:数据定义伪操作: .byte,.short,.long,.quad,.float,.string/.asciz/.ascii,重复定义伪操作.rept,赋值语句.equ/.set ;&函数的定义 ;&对齐方式伪操作 .align;&源文件结束伪操作.end;.include伪操作;&if伪操作;&./ .globl 伪操作 ;.type伪操作 ;列表控制语句 ;区别于gas汇编的通用伪操作,下面是ARM特有的伪操作 :.reg ,.unreq ,.code ,.thumb ,.thumb_func ,.thumb_set, .ltorg ,.pool1. 数据定义伪操作(1) .byte:单字节定义,如:.byte 1,2,0b01,0x34,072,'s' ;(2) .short:定义双字节数据,如:.short 0x ;(3) .long:定义4字节数据,如:.long 0x76565(4) .quad:定义8字节,如:.quad 0xabcd(5) .float:定义浮点数,如:& .float 0f-338327\& .E-40 @ - pi(6) .string/.asciz/.ascii:定义多个字符串,如:& .string "abcd", "efgh", "hello!"& .asciz "qwer", "sun", "world!"& .ascii "welcome\0"需要注意的是:.ascii伪操作定义的字符串需要自行添加结尾字符'\0'。(7) .rept:重复定义伪操作, 格式如下:& .rept 重复次数& 数据定义& .endr @结束重复定义& 例如:& .rept 3& .byte 0x23& .endr(8) .equ/.set: 赋值语句, 格式如下:& .equ(.set) 变量名,表达式& 例如:& .equ abc 3 @让abc=32.函数的定义伪操作(1)函数的定义,格式如下:& 函数名:& 函数体& 返回语句一般的,函数如果需要在其他文件中调用, 需要用到.伪操作将函数声明为全局函数。为了不至于在其他程序在调用某个C函数时发生混乱,对寄存器的使用我们需要遵循APCS准则。函数编译器将处理为函数代码为一段.的汇编码。(2)函数的编写应当遵循如下规则:? a1-a4寄存器(参数、结果或暂存寄存器,r0到r3 的同义字)以及浮点寄存器f0-f3(如果存在浮点协处理器)在函数中是不必保存的;? 如果函数返回一个不大于一个字大小的值,则在函数结束时应该把这个值送到 r0 中;? 如果函数返回一个浮点数,则在函数结束时把它放入浮点寄存器f0中;?如果函数的过程改动了sp(堆栈指针,r13)、fp(框架指针,r11)、sl(堆栈限制,r10)、lr(连接寄存器,r14)、v1-v8(变量寄存器,r4 到 r11)和 f4-f7,那么函数结束时这些寄存器应当被恢复为包含在进入函数时它所持有的值。3. .align .end .include .incbin伪操作(1).align:用来指定数据的对齐方式,格式如下:& .align [absexpr1, absexpr2]& 以某种对齐方式,在未使用的存储区域填充值. 第一个值表示对齐方式,4, 8,16或 32. 第二个表达式值表示填充的值。(2).end:表明源文件的结束。(3).include:可以将指定的文件在使用.include 的地方展开,一般是头文件,例如:& .include “myarmasm.h”(4).incbin伪操作可以将原封不动的一个二进制文件编译到当前文件中,使用方法如下:& .incbin "file"[,skip[,count]]& skip表明是从文件开始跳过skip个字节开始读取文件,count是读取的字数.4. .if伪操作根据一个表达式的值来决定是否要编译下面的代码, 用.endif伪操作来表示条件判断的结束, 中间可以使用.else来决定.if的条件不满足的情况下应该编译哪一部分代码。.if有多个变种:&.ifdef symbol @判断symbol是否定义&.ifc string1,string2 @字符串string1和string2是否相等,字符串可以用单引号括起来&.ifeq expression_r @判断expression_r的值是否为0.ifeqs string1,string2 @判断string1和string2是否相等,字符 串必须用双引号括起来.ifge expression_r @判断expression_r的值是否大于等于0.ifgt absolute expression_r @判断expression_r的值是否大于0.ifle expression_r @判断expression_r的值是否小于等于0.iflt absolute expression_r @判断expression_r的值是否小于0.ifnc string1,string2 @判断string1和string2是否不相等, 其用法跟.ifc恰好相反。.ifndef symbol, .ifnotdef symbol @判断是否没有定义symbol, 跟.ifdef恰好相反.ifne expression_r @如果expression_r的值不是0, 那么编译器将编译下面的代码.ifnes string1,string2 @如果字符串string1和string2不相 等, 那么编译器将编译下面的代码.5. . .type .title .list(1)./ .globl :用来定义一个全局的符号,格式如下:& . symbol 或者 .globl symbol(2).type:用来指定一个符号的类型是函数类型或者是对象类型, 对象类型一般是数据, 格式如下:& .type 符号, 类型描述【例6】.globl a.data.align 4.type a, @object.size a, 4a:.long 10【例7】.section .text.type asmfunc, @function.globl asmfuncasmfunc:mov pc, lr(3)列表控制语句:.title:用来指定汇编列表的标题,例如:& .title “my program”.list:用来输出列表文件.6. ARM特有的伪操作(1) .reg: 用来给寄存器赋予别名,格式如下:& 别名 .req 寄存器名(2) .unreq: 用来取消一个寄存器的别名,格式如下:       .unreq 寄存器别名  注意被取消的别名必须事先定义过,否则编译器就会报错,这个伪操作也可以用来取消系统预制的别名, 例如r0, 但如果没有必要的话不推荐那样做。(3) .code伪操作用来选择ARM或者Thumb指令集,格式如下:           .code 表达式  如果表达式的值为16则表明下面的指令为Thumb指令,如果表达式的值为32则表明下面的指令为ARM指令.(4) .thumb伪操作等同于.code 16, 表明使用Thumb指令, 类似的.arm等同于.code 32(5) .force_thumb伪操作用来强制目标处理器选择thumb的指令集而不管处理器是否支持(6) .thumb_func伪操作用来指明一个函数是thumb指令集的函数(7) .thumb_set伪操作的作用类似于.set, 可以用来给一个标志起一个别名, 比.set功能增加的一点是可以把一个标志标记为thumb函数的入口, 这点功能等同于.thumb_func(8) .ltorg用于声明一个数据缓冲池(literal pool)的开始,它可以分配很大的空间。(9) .pool的作用等同.ltorg(9).space &number_of_bytes& {,&fill_byte&}分配number_of_bytes字节的数据空间,并填充其值为fill_byte,若未指定该值,缺省填充0。(与armasm中的SPACE功能相同)(10).word &word1& {,&word2&} …插入一个32-bit的数据队列。(与armasm中的DCD功能相同)可以使用.word把标识符作为常量使用&例如:& Start:& valueOfStart:& .word Start&这样程序的开头Start便被存入了变量valueOfStart中。(11).hword &short1& {,&short2&} …插入一个16-bit的数据队列。(与armasm中的DCW相同)八. GNU ARM汇编特殊字符和语法代码行中的注释符号: ‘@’整行注释符号: ‘#’语句分离符号: ‘;’直接操作数前缀: ‘#’ 或 ‘$’第二部分 GNU的编译器和调试一. 编译工具1.编辑工具介绍GNU 提供的编译工具包括汇编器as、C编译器gcc、C++编译器g++、连接器ld和二进制转换工具objcopy。基于ARM平台的工具分别为arm- linux-as、arm-linux-gcc、arm-linux-g++、arm-linux-ld和arm-linux- objcopy。GNU的编译器功能非常强大,共有上百个操作选项,这也是这类工具让初学者头痛的原因。不过,实际开发中只需要用到有限的几个,大部分可以采用缺省选项。GNU工具的开发流程如下:编写C、C++语言或汇编源程序,用gcc或g++生成目标文件,编写连接脚本文件,用连接器生成最终目标文件(elf格式),用二进制转换工具生成可下载的二进制代码。(1)编写C、C++语言或汇编源程序通常汇编源程序用于系统最基本的初始化,如初始化堆栈指针、设置页表、操作ARM的协处理器等。初始化完成后就可以跳转到C代码执行。需要注意的是,GNU的汇编器遵循AT&T的汇编语法,读者可以从GNU的站点(www.gnu.org)上下载有关规范。汇编程序的缺省入口是 start标号,用户也可以在连接脚本文件中用ENTRY标志指明其它入口点(见下文关于连接脚本的说明)。(2)用gcc或g++生成目标文件如果应用程序包括多个文件,就需要进行分别编译,最后用连接器连接起来。如笔者的引导程序包括3个文件:init.s(汇编代码、初始化硬件)xmrecever.c(,采用Xmode协议)和flash.c(Flash擦写模块)。分别用如下命令生成目标文件: arm-linux-gcc-c-O2-oinit.oinit.s arm-linux-gcc-c-O2-oxmrecever.oxmrecever.c arm-linux-gcc-c-O2-oflash.oflash.c 其中-c命令表示只生成目标代码,不进行连接;-o命令指明目标文件的名称;-O2表示采用二级优化,采用优化后可使生成的代码更短,运行速度更快。如果项目包含很多文件,则需要编写makefile文件。关于makefile的内容,请感兴趣的读者参考相关资料。(3)编写连接脚本文件gcc 等编译器内置有缺省的连接脚本。如果采用缺省脚本,则生成的目标代码需要操作系统才能加载运行。为了能在嵌入式系统上直接运行,需要编写自己的连接脚本文件。编写连接脚本,首先要对目标文件的格式有一定了解。GNU编译器生成的目标文件缺省为elf格式。elf文件由若干段(section)组成,如不特殊指明,由C源程序生成的目标代码中包含如下段:.text(正文段)包含程序的指令代码;.data(数据段)包含固定的数据,如常量、字符串;.bss(未初始化数据段)包含未初始化的变量、数组等。C++源程序生成的目标代码中还包括.fini(析构函数代码)和. init(构造函数代码)等。连接器的任务就是将多个目标文件的.text、.data和.bss等段连接在一起,而连接脚本文件是告诉连接器从什么地址开始放置这些段。例如连接文件link.lds为:ENTRY(begin)SECTION{.=0x;.text:{*(.text)}.data:{*(.data)}.bss:{*(.bss)}}其中,ENTRY(begin)指明程序的入口点为begin标号;.=0x指明目标代码的起始地址为0x,这一段地址为 MX1的片内RAM;.text:{*(.text)}表示从0x开始放置所有目标文件的代码段,随后的.data:{* (.data)}表示数据段从代码段的末尾开始,再后是.bss段。(4)用连接器生成最终目标文件有了连接脚本文件,如下命令可生成最终的目标文件:arm-linux-ld –no stadlib –o bootstrap.elf -Tlink.lds init.o xmrecever.o flash.o其中,ostadlib表示不连接系统的运行库,而是直接从begin入口;-o指明目标文件的名称;-T指明采用的连接脚本文件(也可以使用-Ttext address,address表示执行区地址);最后是需要连接的目标文件列表。(5)生成二进制代码连接生成的elf文件还不能直接下载执行,通过objcopy工具可生成最终的二进制文件:arm-linux-objcopy –O binary bootstrap.elf bootstrap.bin其中-O binary指定生成为二进制格式文件。Objcopy还可以生成S格式的文件,只需将参数换成-O srec。还可以使用-S选项,移除所有的符号信息及重定位信息。如果想将生成的目标代码反汇编,还可以用objdump工具:&arm-linux-objdump -D bootstrap.elf至此,所生成的目标文件就可以直接写入Flash中运行了。2.Makefile实例example: head.s main.c&arm-linux-gcc -c -o head.o head.s&arm-linux-gcc -c -o main.o main.c&arm-linux-ld -Tlink.lds head.o ain.o -o example.elf&arm-linux-objcopy -O binary -S example_tmp.o example&arm-linux-objdump -D -b binary -m arm example &ttt.s二. 调试工具Linux 下的GNU调试工具主要是gdb、gdbserver和kgdb。其中gdb和gdbserver可完成对目标板上Linux下应用程序的远程调试。 gdbserver是一个很小的应用程序,运行于目标板上,可监控被调试进程的运行,并通过与上位机上的gdb通信。开发者可以通过上位机的gdb输入命令,控制目标板上进程的运行,查看内存和寄存器的内容。gdb5.1.1以后的版本加入了对的支持,在初始化时加入- target==arm参数可直接生成基于ARM平台的gdbserver。gdb工具可以从ftp: //ftp.gnu.org/pub/gnu/gdb/上下载。对于Linux内核的调试,可以采用kgdb工具,同样需要通过串口与上位机上的gdb通信,对目标板的Linux内核进行调试。可以从/projects/kgdb/上了解具体的使用方法。参考资料:1. Richard Blum,Professional Assembly Language2. GNU ARM 汇编快速入门,http://blog.chinaunix.net/u/31996/showart.php?id=3261463. ARM GNU 汇编伪指令简介,/jb8164/archive//41661.aspx4. GNU汇编使用经验,http://blog.chinaunix.net/u1/37614/showart_390095.html5. GNU的编译器和,/blog-htm-do-showone-uid-34335-itemid-81387-type-blog.html6. 用GNU工具开发基于ARM的嵌入式系统,/liren0@126/blog/static//7. objcopy命令介绍,http://blog.csdn.net/junhua198310/archive//1669545.aspx
由浅入深的Wince源码 Chap01
//======================================================================// HelloCE - A simple applica for Windows CE//// Written for the book
Windows CE//
Douglas Boling////======================================================================#include &windows.h&&&&&&&&&&&&&&&&& // For all that Windows uff#include &commctrl.h&&&&&&&&&&&&&&&& // Command bar includes#include "helloce.h"&&&&&&&&&&&&&&&& // Program-specific stuff
//----------------------------------------------------------------------// Global data//cot TCHAR szAppName[] = TEXT ("HelloCE");HINSTANCE hI&&&&&&&&&&&&&&&&&&&& // Program instance handle
// Message dispatch table for MainWindowProcconst struct decodeUINT MainMessages[] = {&&& WM_CREATE, DoCreateMain,&&& WM_PAINT, DoPaintMain,&&& WM_HIBERNATE, DoHibernateMain,&&& WM_ACTIVATE, DoActivateMain,&&& WM_DESTROY, DoDestroyMain,};
//======================================================================//// Program entry point//int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,&&&&&&&&&&&&&&&&&&& LPWSTR lpLine, int nCmdShow) {&&& MSG&&& int rc = 0;&&& HWND hwndM
&&& // init application&&& rc = InitApp (hInstance);&&& if (rc)
&&& // Initialize this instance.&&& hwndMain = InitInstance (hInstance, lpCmdLine, nCmdShow);&&& if (hwndMain == 0)&&&&&&& return 0x10;
&&& // Application message loop&&& while (GetMessage (&msg, NULL, 0, 0)) {&&&&&&& TranslateMessage (&msg);&&&&&&& DispatchMessage (&msg);&&& }&&& // Instance cleanup&&& return TermInstance (hInstance, msg.wParam);}//----------------------------------------------------------------------// InitApp - Application initialization//int InitApp (HINSTANCE hInstance) {&&& WNDCLASS
&&& // Register application main window class.&&& wc.style = 0;&&&&&&&&&&&&&&&&&&&&&&&&&&&& // Window style&&& wc.lpfnWndProc = MainWndP&&&&&&&&&&&& // Callback function&&& wc.cbClsExtra = 0;&&&&&&&&&&&&&&&&&&&&&&& // Extra class data&&& wc.cbWndExtra = 0;&&&&&&&&&&&&&&&&&&&&&&& // Extra window data&&& wc.hInstance = hI&&&&&&&&&&&&&&&& // Owner handle&&& wc.hIcon = NULL,&&&&&&&&&&&&&&&&&&&&&&&&& // Application icon&&& wc.hCursor = NULL;&&&&&&&&&&&&&&&&&&&&&&& // Default cursor&&& wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);&&& wc.lpszMenuName =& NULL;&&&&&&&&&&&&&&&&& // Menu name&&& wc.lpszClassName = szAppN&&&&&&&&&&&& // Window class name
&&& if (RegisterClass (&wc) == 0) return 1;
&&& return 0;}//----------------------------------------------------------------------// InitInstance - Instance initialization//HWND InitInstance (HINSTANCE hInstance, LPWSTR lpCmdLine,&&&&&&&&&&&&&&&&&& int nCmdShow) {&&& HWND hW
&&& // Save program instance handle in global variable.&&& hInst = hI
&&& // Create main window.&&& hWnd = CreateWindow (szAppName,&&&&&&&&&& // Window class&&&&&&&&&&&&&&&&&&&&&&&& TEXT("Hello"),&&&&&& // Window title&&&&&&&&&&&&&&&&&&&&&&&& WS_VISIBLE,&&&&&&&&& // Style flags&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // x position&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // y position&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // Initial width&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // Initial height&&&&&&&&&&&&&&&&&&&&&&&& NULL,&&&&&&&&&&&&&&& // Parent&&&&&&&&&&&&&&&&&&&&&&&& NULL,&&&&&&&&&&&&&&& // Menu, must be null&&&&&&&&&&&&&&&&&&&&&&&& hInstance,&&&&&&&&&& // Application instance&&&&&&&&&&&&&&&&&&&&&&&& NULL);&&&&&&&&&&&&&& // Pointer to create parameters
&&& // Return fail code if window not created.&&& if (!IsWindow (hWnd)) return 0;
&&& // Standard show and update calls&&& ShowWindow (hWnd, nCmdShow);&&& UpdateWindow (hWnd);&&& return hW}//----------------------------------------------------------------------// TermInstance - Program cleanup//int TermInstance (HINSTANCE hInstance, int nDefRC) {
&&& return nDefRC;}//======================================================================// Message handling procedures for main window//
//----------------------------------------------------------------------// MainWndProc - Callback function for application window//LRESULT CALLBACK MainWndProc (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& INT&&& //&&& // Search message list to see if we need to handle this&&& // message.& If in list, call procedure.&&& //&&& for (i = 0; i & dim(MainMessages); i++) {&&&&&&& if (wMsg == MainMessages[i].Code)&&&&&&&&&&& return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam);&&& }&&& return DefWindowProc (hWnd, wMsg, wParam, lParam);}//----------------------------------------------------------------------// DoCreateMain - Process WM_CREATE message for window.//LRESULT DoCreateMain (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& HWND hwndCB;
&&& // Create a command bar.&&& hwndCB = CommandBar_Create (hInst, hWnd, _CMDBAR);
&&& // Add exit button to command bar. &&& CommandBar_AddAdornments (hwndCB, 0, 0);&&& return 0;}//----------------------------------------------------------------------// DoPaintMain - Process WM_PAINT message for window.//LRESULT DoPaintMain (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& PAINTSTRUCT&&& RECT&&& HDC
&&& // Adjust the size of the client rectangle to take into account&&& // the command bar height.&&& GetClientRect (hWnd, &rect);&&& rect.top += CommandBar_Height (GetDlgItem (hWnd, IDC_CMDBAR));
&&& hdc = BeginPaint (hWnd, &ps); &&& DrawText (hdc, TEXT ("Hello Windows CE!"), -1, &rect, &&&&&&&&&&&&& DT_CENTER | DT_VCENTER | DT_SINGLELINE);
&&& EndPaint (hWnd, &ps); &&& return 0;}//----------------------------------------------------------------------// DoHibernateMain - Process WM_HIBERNATE message for window.//LRESULT DoHibernateMain (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&&&&&& LPARAM lParam) {
&&& // If not the active window, nuke the command bar to save memory.&&& if (GetActiveWindow () != hWnd)&&&&&&& CommandBar_Destroy (GetDlgItem (hWnd, IDC_CMDBAR));
&&& return 0;}//----------------------------------------------------------------------// DoActivateMain - Process WM_ACTIVATE message for window.//LRESULT DoActivateMain (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& HWND hwndCB;
&&& // If activating and no command bar, create it.&&& if ((LOWORD (wParam) != WA_INACTIVE) &&&&&&&&& (GetDlgItem (hWnd, IDC_CMDBAR) == 0)) {
&&&&&&& // Create a command bar.&&&&&&& hwndCB = CommandBar_Create (hInst, hWnd, IDC_CMDBAR);
&&&&&&& // Add exit button to command bar. &&&&&&& CommandBar_AddAdornments (hwndCB, 0, 0);&&& }&&& return 0;}//----------------------------------------------------------------------// DoDestroyMain - Process WM_DESTROY message for window.//LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& PostQuitMessage (0);&&& return 0;}
由浅入深的Wince源码 Chap02
//======================================================================// FtLi - Lists the available fonts in the system//// Written for the book
Windows CE//
Douglas Boling////======================================================================#include &windows.h&&&&&&&&&&&&&&&&& // For all that Windows stuff#include &commctrl.h&&&&&&&&&&&&&&&& // Command bar includes#include "FontList.h"&&&&&&&&&&&&&&& // Program-specific stuff
//----------------------------------------------------------------------// Global data//cot TCHAR szAppName[] = TEXT ("FontList");HINSTANCE hI&&&&&&&&&&&&&&&&&&&& // Program instance handle
FONTFTRUCT ffs[FLYMAX];INT sFamilyCnt = 0;
// Message dispatch table for MainWindowProcconst struct decodeUINT MainMessages[] = {&&& WM_CREATE, DoCreateMain,&&& WM_PAINT, DoPaintMain,&&& WM_DESTROY, DoDestroyMain,};
//======================================================================//// Program entry point//int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,&&&&&&&&&&&&&&&&&&& LPWSTR lpLine, int nCmdShow) {&&& MSG&&& int rc = 0;&&& HWND hwndM
&&& // Inialize application.&&& rc = InitApp (hInstance);&&& if (rc)
&&& // Initialize this instance.&&& hwndMain = InitInstance (hInstance, lpCmdLine, nCmdShow);&&& if (hwndMain == 0)&&&&&&& return 0x10;
&&& // Application message loop&&& while (GetMessage (&msg, NULL, 0, 0)) {&&&&&&& TranslateMessage (&msg);&&&&&&& DispatchMessage (&msg);&&& }&&& // Instance cleanup&&& return TermInstance (hInstance, msg.wParam);}//----------------------------------------------------------------------// InitApp - Application initialization//int InitApp (HINSTANCE hInstance) {&&& WNDCLASS
&&& // Register application main window class.&&& wc.style = 0;&&&&&&&&&&&&&&&&&&&&&&&&&&&& // Window style&&& wc.lpfnWndProc = MainWndP&&&&&&&&&&&& // Callback function&&& wc.cbClsExtra = 0;&&&&&&&&&&&&&&&&&&&&&&& // Extra class data&&& wc.cbWndExtra = 0;&&&&&&&&&&&&&&&&&&&&&&& // Extra window data&&& wc.hInstance = hI&&&&&&&&&&&&&&&& // Owner handle&&& wc.hIcon = NULL,&&&&&&&&&&&&&&&&&&&&&&&&& // Application icon&&& wc.hCursor = NULL;&&&&&&&&&&&&&&&&&&&&&&& // Default cursor&&& wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);&&& wc.lpszMenuName =& NULL;&&&&&&&&&&&&&&&&& // Menu name&&& wc.lpszClassName = szAppN&&&&&&&&&&&& // Window class name
&&& if (RegisterClass (&wc) == 0) return 1;
&&& return 0;}//----------------------------------------------------------------------// InitInstance - Instance initialization//HWND InitInstance (HINSTANCE hInstance, LPWSTR lpCmdLine,&&& int nCmdShow) {&&& HWND hW
&&& // Save program instance handle in global variable&&& hInst = hI
&&& // Create main window&&& hWnd = CreateWindow (szAppName,&&&&&&&&&& // Window class&&&&&&&&&&&&&&&&&&&&&&&& TEXT("Font Listing"),// Window title&&&&&&&&&&&&&&&&&&&&&&&& WS_VISIBLE,&&&&&&&&& // Style flags&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // x position&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // y position&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // Initial width&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // Initial height&&&&&&&&&&&&&&&&&&&&&&&& NULL,&&&&&&&&&&&&&&& // Parent&&&&&&&&&&&&&&&&&&&&&&&& NULL,&&&&&&&&&&&&&&& // Menu, must be null&&&&&&&&&&&&&&&&&&&&&&&& hInstance,&&&&&&&&&& // Application instance&&&&&&&&&&&&&&&&&&&&&&&& NULL);&&&&&&&&&&&&&& // Pointer to create&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // parameters&&& // Return fail code if window not created.&&& if (!IsWindow (hWnd)) return 0;
&&& // Standard show and update calls&&& ShowWindow (hWnd, nCmdShow);&&& UpdateWindow (hWnd);&&& return hW}//----------------------------------------------------------------------// TermInstance - Program cleanup//int TermInstance (HINSTANCE hInstance, int nDefRC) {
&&& return nDefRC;}//======================================================================// Font callback functions////----------------------------------------------------------------------// FontFamilyCallback - Callback function that enumerates the font // families//int CALLBACK FontFamilyCallback (CONST LOGFONT *lplf, &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& CONST TEXTMETRIC *lpntm, &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& DWORD nFontType, LPARAM lParam) {&&& int rc = 1;
&&& // Stop enumeration if
filled.&&& if (sFamilyCnt &= FAMILYMAX)&&&&&&& return 0;&&& // Copy face name of font.&&& lstrcpy (ffs[sFamilyCnt++].szFontFamily, lplf-&lfFaceName);
&&&}//----------------------------------------------------------------------// EnumSingleFontFamily - Callback function that enumerates fonts//int CALLBACK EnumSingleFontFamily (CONST LOGFONT *lplf, &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& CONST TEXTMETRIC *lpntm, &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& DWORD nFontType, LPARAM lParam) {&&& PFONTFAMSTRUCT
&&& pffs = (PFONTFAMSTRUCT) lP&&& pffs-&nNumFonts++;&&& // Increment count of fonts in family&&& return 1;}//----------------------------------------------------------------------// PaintSingleFontFamily - Callback function that draws a font//int CALLBACK PaintSingleFontFamily (CONST LOGFONT *lplf, &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& CONST TEXTMETRIC *lpntm, &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& DWORD nFontType, LPARAM lParam) {&&& PPAINTFONTINFO&&& TCHAR szOut[256];&&& INT nFontHeight, nPointS&&& HFONT hFont, hOldF
&&& ppfi = (PPAINTFONTINFO) lP& // Translate lParam into struct&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // pointer.
&&& // Create the font from the LOGFONT structure passed.&&& hFont = CreateFontIndirect (lplf);
&&& // Select the font into the device context.&&& hOldFont = SelectObject (ppfi-&hdc, hFont);
&&& // Compute font size.&&& nPointSize = (lplf-&lfHeight * 72) / &&&&&&&&&&&&&&&& GetDeviceCaps(ppfi-&hdc,LOGPIXELSY);
&&& // Format string and paint on display.&&& wsprintf (szOut, TEXT("%s&& Point:%d"), lplf-&lfFaceName, &&&&&&&&&&&&& nPointSize);&&& ExtTextOut (ppfi-&hdc, 25, ppfi-&yCurrent, 0, NULL,&&&&&&&&&&&&&&& szOut, lstrlen (szOut), NULL);
&&& // Compute the height of the default font.&&& nFontHeight = lpntm-&tmHeight + lpntm-&tmExternalL
&&& // Update new draw point.&&& ppfi-&yCurrent += nFontH
&&& // Deselect font and delete.&&& SelectObject (ppfi-&hdc, hOldFont);&&& DeleteObject (hFont);&&& return 1;}//======================================================================// Message handling procedures for MainWindow//
//----------------------------------------------------------------------// MainWndProc - Callback function for application window//LRESULT CALLBACK MainWndProc (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& INT&&& //&&& // Search message list to see if we need to handle this&&& // message.& If in list, call procedure.&&& //&&& for (i = 0; i & dim(MainMessages); i++) {&&&&&&& if (wMsg == MainMessages[i].Code)&&&&&&&&&&& return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam);&&& }&&& return DefWindowProc (hWnd, wMsg, wParam, lParam);}//----------------------------------------------------------------------// DoCreateMain - Process WM_CREATE message for window.//LRESULT DoCreateMain (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& HWND hwndCB;&&& HDC&&& INT i,
&&& // Create a command bar.&&& hwndCB = CommandBar_Create (hInst, hWnd, _CMDBAR);
&&& // Add exit button to command bar. &&& CommandBar_AddAdornments (hwndCB, 0, 0);
&&& //Enumerate the available fonts&&& hdc = GetDC (hWnd);&&& rc = EnumFontFamilies ((HDC)hdc, (LPTSTR)NULL,&&&&&&& FontFamilyCallback, 0);
&&& for (i = 0; i & sFamilyC i++) {&&&&&&& ffs[i].nNumFonts = 0;&&&&&&& rc = EnumFontFamilies ((HDC)hdc, ffs[i].szFontFamily, &&&&&&&&&&&&&&&&&&&&&&&&&&&&&& EnumSingleFontFamily, &&&&&&&&&&&&&&&&&&&&&&&&&&&&&& (LPARAM)(PFONTFAMSTRUCT)&ffs[i]);&&& }&&& ReleaseDC (hWnd, hdc);&&& return 0;}//----------------------------------------------------------------------// DoPaintMain - Process WM_PAINT message for window.//LRESULT DoPaintMain (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& PAINTSTRUCT&&& RECT&&& HDC&&& TEXTMETRIC&&& INT nFontHeight,&&& TCHAR szOut[256];&&& PAINTFONTINFO
&&& // Adjust the size of the client rect to take into account&&& // the command bar height.&&& GetClientRect (hWnd, &rect);&&& rect.top += CommandBar_Height (GetDlgItem (hWnd, IDC_CMDBAR));
&&& hdc = BeginPaint (hWnd, &ps);
&&& // Get the height of the default font.&&& GetTextMetrics (hdc, &tm);&&& nFontHeight = tm.tmHeight + tm.tmExternalL
&&& // Initialize struct that is passed to enumerate function.&&& pfi.yCurrent = rect.&&& pfi.hdc =&&& for (i = 0; i & sFamilyC i++) {
&&&&&&& // Format output string and paint font family name.&&&&&&& wsprintf (szOut, TEXT ("Family: %s&& "),&&&&&&&&&&&&&&&&& ffs[i].szFontFamily);&&&&&&& ExtTextOut (hdc, 5, pfi.yCurrent, 0, NULL,&&&&&&&&&&&&&&&&&&& szOut, lstrlen (szOut), NULL);&&&&&&& pfi.yCurrent += nFontH
&&&&&&& // Enumerate each family to draw a sample of that font.&&&&&&& EnumFontFamilies ((HDC)hdc, ffs[i].szFontFamily, &&&&&&&&&&&&&&&&&&&&&&&&& PaintSingleFontFamily, &&&&&&&&&&&&&&&&&&&&&&&&& (LPARAM)&pfi);&&& }&&& EndPaint (hWnd, &ps); &&& return 0;}//----------------------------------------------------------------------// DoDestroyMain - Process WM_DESTROY message for window.//LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& PostQuitMessage (0);&&& return 0;}
//======================================================================// Shapes- Brush and shapes demo for Windows CE//// Written for the book
Windows CE//
Douglas Boling////======================================================================#include &windows.h&&&&&&&&&&&&&&&&& // For all that Windows stuff#include &commctrl.h&&&&&&&&&&&&&&&& // Command bar includes#include "shapes.h"&&&&&&&&&&&&&&&&& // Program-specific stuff
//----------------------------------------------------------------------// Global data//const TCHAR szAppName[] = TEXT ("Shapes");HINSTANCE hI&&&&&&&&&&&&&&&&&&&& // Program instance handle
// Message dispatch table for MainWindowProcconst struct decodeUINT MainMessages[] = {&&& WM_CREATE, DoCreateMain,&&& WM_PAINT, DoPaintMain,&&& WM_DESTROY, DoDestroyMain,};
//======================================================================//// Program entry point//int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,&&&&&&&&&&&&&&&&&&& LPWSTR lpCmdLine, int nCmdShow) {&&& MSG&&& int rc = 0;&&& HWND hwndM
&&& // Initialize application.&&& rc = InitApp (hInstance);&&& if (rc)
&&& // Initialize this instance.&&& hwndMain = InitInstance (hInstance, lpCmdLine, nCmdShow);&&& if (hwndMain == 0)&&&&&&& return 0x10;
&&& // Application message loop&&& while (GetMessage (&msg, NULL, 0, 0)) {&&&&&&& TranslateMessage (&msg);&&&&&&& DispatchMessage (&msg);&&& }&&& // Instance cleanup&&& return TermInstance (hInstance, msg.wParam);}//----------------------------------------------------------------------// InitApp - Application initialization//int InitApp (HINSTANCE hInstance) {&&& WNDCLASS
&&& // Register application main window class.&&& wc.style = 0;&&&&&&&&&&&&&&&&&&&&&&&&&&&& // Window style&&& wc.lpfnWndProc = MainWndP&&&&&&&&&&&& // Callback function&&& wc.cbClsExtra = 0;&&&&&&&&&&&&&&&&&&&&&&& // Extra class data&&& wc.cbWndExtra = 0;&&&&&&&&&&&&&&&&&&&&&&& // Extra window data&&& wc.hInstance = hI&&&&&&&&&&&&&&&& // Owner handle&&& wc.hIcon = NULL,&&&&&&&&&&&&&&&&&&&&&&&&& // Application icon&&& wc.hCursor = NULL;&&&&&&&&&&&&&&&&&&&&&&& // Default cursor&&& wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);&&& wc.lpszMenuName =& NULL;&&&&&&&&&&&&&&&&& // Menu name&&& wc.lpszClassName = szAppN&&&&&&&&&&&& // Window class name
&&& if (RegisterClass (&wc) == 0) return 1;
&&& return 0;}//----------------------------------------------------------------------// InitInstance - Instance initialization//HWND InitInstance (HINSTANCE hInstance, LPWSTR lpCmdLine,&&& int nCmdShow){&&& HWND hW
&&& // Save program instance handle in global variable.&&& hInst = hI
&&& // Create main window&&& hWnd = CreateWindow (szAppName,&&&&&&&&&& // Window class&&&&&&&&&&&&&&&&&&&&&&&& TEXT("Shapes"),&&&&& // Window title&&&&&&&&&&&&&&&&&&&&&&&& WS_VISIBLE,&&&&&&&&& // Style flags&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // x position&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // y position&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // Initial width&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // Initial height&&&&&&&&&&&&&&&&&&&&&&&& NULL,&&&&&&&&&&&&&&& // Parent&&&&&&&&&&&&&&&&&&&&&&&& NULL,&&&&&&&&&&&&&&& // Menu, must be null&&&&&&&&&&&&&&&&&&&&&&&& hInstance,&&&&&&&&&& // Application instance&&&&&&&&&&&&&&&&&&&&&&&& NULL);&&&&&&&&&&&&&& // Pointer to create&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // parameters&&& // Return fail code if window not created.&&& if (!IsWindow (hWnd)) return 0;
&&& // Standard show and update calls&&& ShowWindow (hWnd, nCmdShow);&&& UpdateWindow (hWnd);&&& return hW}//----------------------------------------------------------------------// TermInstance - Program cleanup//int TermInstance (HINSTANCE hInstance, int nDefRC) {
&&& return nDefRC;}//======================================================================// Message handling procedures for MainWindow//
//----------------------------------------------------------------------// MainWndProc - Callback function for application window//LRESULT CALLBACK MainWndProc (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& INT&&& //&&& // Search message list to see if we need to handle this&&& // message.& If in list, call procedure.&&& //&&& for (i = 0; i & dim(MainMessages); i++) {&&&&&&& if (wMsg == MainMessages[i].Code)&&&&&&&&&&&& return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam,&&&&&&&&&&&&&&&& lParam);&&& }&&& return DefWindowProc (hWnd, wMsg, wParam, lParam);}//----------------------------------------------------------------------// DoCreateMain - Process WM_CREATE message for window.//LRESULT DoCreateMain (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& HWND hwndCB;
&&& // Create a command bar.&&& hwndCB = CommandBar_Create (hInst, hWnd, IDC_CMDBAR);
&&& // Add exit button to command bar. &&& CommandBar_AddAdornments (hwndCB, 0, 0);&&& return 0;}//----------------------------------------------------------------------// MyCreateHachBrush - Creates hatched brushes//HBRUSH MyCreateHachBrush (INT fnStyle, COLORREF clrref) {&&& BRUSHBMP&&& BYTE *pB&&&&&& DWORD dwBits[6][2] = {&&&&&&& {0x000000ff,0x}, {0xx},&&&&&&& {0xx}, {0xx},&&&&&&& {0x101010ff,0x}, {0xx},&&& };
&&& if ((fnStyle & 0) || (fnStyle & dim(dwBits)))&&&&&&& return 0;&&& memset (&brbmp, 0, sizeof (brbmp));
&&& brbmp.bmi.biSize = sizeof (BITMAPINFOHEADER);&&& brbmp.bmi.biWidth = 8;&&& brbmp.bmi.biHeight = 8;&&& brbmp.bmi.biPlanes = 1;&&& brbmp.bmi.biBitCount = 1;&&& brbmp.bmi.biClrUsed = 2;&&& brbmp.bmi.biClrImportant = 2;
&&& // Initialize the palette of the bitmap.&&& brbmp.dwPal[0] = PALETTERGB(0xff,0xff,0xff);&&& brbmp.dwPal[1] = PALETTERGB((BYTE)((clrref && 16) & 0xff),&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& (BYTE)((clrref && 8) & 0xff),&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& (BYTE)(clrref & 0xff));
&&& // Write the hatch data to the bitmap.& &&& pBytes = (BYTE *)&dwBits[fnStyle];&&& for (i = 0; i & 8; i++)&&&&&&& brbmp.bBits[i*4] = *pBytes++;
&&& // Return the handle of the brush created.&&& return CreateDIBPatternBrushPt (&brbmp, DIB_RGB_COLORS);}//----------------------------------------------------------------------// DoPaintMain - Process WM_PAINT message for window.////#define ENDPOINTS 32#define ENDPOINTS 64
LRESULT DoPaintMain (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& PAINTSTRUCT&&& RECT&&& HDC&&& POINT ptArray[ENDPOINTS];&&& HBRUSH hBr, hOldBr;&&& TCHAR szText[128];
&&& // Adjust the size of the client rect to take into account&&& // the command bar height.&&& GetClientRect (hWnd, &rect);&&& rect.top += CommandBar_Height (GetDlgItem (hWnd, IDC_CMDBAR));
&&& hdc = BeginPaint (hWnd, &ps);
&&& // Draw rectangle.&&& hBr = GetStockObject (BLACK_BRUSH);&&& hOldBr = SelectObject (hdc, hBr);&&& Rectangle (hdc, 50, 50, 125, 150);&&& SelectObject (hdc, hOldBr);
&&& // Draw ellipse.&&& hBr = GetStockObject (DKGRAY_BRUSH);&&& hOldBr = SelectObject (hdc, hBr);&&& Ellipse (hdc, 150, 50, 225, 150);&&& SelectObject (hdc, hOldBr);
&&& // Draw round rectangle.&&& hBr = GetStockObject (LTGRAY_BRUSH);&&& hOldBr = SelectObject (hdc, hBr);&&& RoundRect (hdc, 250, 50, 325, 150, 30, 30);&&& SelectObject (hdc, hOldBr);
&&& // Draw hexagon using Polygon.&&& hBr = GetStockObject (WHITE_BRUSH);&&& hOldBr = SelectObject (hdc, hBr);&&& ptArray[0].x = 387;&&& ptArray[0].y = 50;&&& ptArray[1].x = 350;&&& ptArray[1].y = 75;&&& ptArray[2].x = 350;&&& ptArray[2].y = 125;&&& ptArray[3].x = 387;&&& ptArray[3].y = 150;&&& ptArray[4].x = 425;&&& ptArray[4].y = 125;&&& ptArray[5].x = 425;&&& ptArray[5].y = 75;
&&& Polygon (hdc, ptArray, 6);&&& SelectObject (hdc, hOldBr);
&&& hBr = MyCreateHachBrush (HS_DIAGCROSS, RGB (0, 0, 0));&&& hOldBr = SelectObject (hdc, hBr);&&& Rectangle (hdc, 50, 165, 425, 210);&&& SelectObject (hdc, hOldBr);&&& DeleteObject (hBr);
&&& SetBkMode (hdc, OPAQUE);&&& lstrcpy (szText, TEXT ("Opaque background"));&&& ExtTextOut (hdc, 60, 175, 0, NULL, &&&&&&&&&&&&&&& szText, lstrlen (szText), NULL);
&&& SetBkMode (hdc, TRANSPARENT);&&& lstrcpy (szText, TEXT ("Transparent background"));&&& ExtTextOut (hdc, 250, 175, 0, NULL,&&&&&&&&&&&&&&& szText, lstrlen (szText), NULL);
&&& EndPaint (hWnd, &ps); &&& return 0;}//----------------------------------------------------------------------// DoDestroyMain - Process WM_DESTROY message for window.//LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& PostQuitMessage (0);&&& return 0;}
//======================================================================// TextDemo - Text output demo //// Written for the book
Windows CE//
Douglas Boling////======================================================================#include &windows.h&&&&&&&&&&&&&&&&& // For all that Windows stuff#include &commctrl.h&&&&&&&&&&&&&&&& // Command bar includes#include "TextDemo.h"&&&&&&&&&&&&&&& // Program-specific stuff
//----------------------------------------------------------------------// Global data//const TCHAR szAppName[] = TEXT ("TextDemo");HINSTANCE hI&&&&&&&&&&&&&&&&&&&& // Program instance handle
// Message dispatch table for MainWindowProcconst struct decodeUINT MainMessages[] = {&&&& WM_CREATE, DoCreateMain,&&&& WM_PAINT, DoPaintMain,&&&& WM_DESTROY, DoDestroyMain,};
//======================================================================//// Program Entry Point//int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,&&&&&&&&&&&&&&&&&&& LPWSTR lpCmdLine, int nCmdShow) {&&& MSG&&& int rc = 0;
&&& // Initialize application&&& rc = InitApp (hInstance);&&& if (rc)
&&& // Initialize this instance&&& if ((rc = InitInstance (hInstance, lpCmdLine, nCmdShow)) != 0)&&&&&&&
&&& // Application message loop&&& while (GetMessage (&msg, NULL, 0, 0)) {&&&&&&& TranslateMessage (&msg);&&&&&&& DispatchMessage (&msg);&&& }&&& // Instance cleanup&&& return TermInstance (hInstance, msg.wParam);}//----------------------------------------------------------------------// InitApp - Application initialization//int InitApp (HINSTANCE hInstance) {&&& WNDCLASS
&&& // Register application main window class.&&& wc.style = 0;&&&&&&&&&&&&&&&&&&&&&&&&&&&& // Window style&&& wc.lpfnWndProc = MainWndP&&&&&&&&&&&& // Callback function&&& wc.cbClsExtra = 0;&&&&&&&&&&&&&&&&&&&&&&& // Extra class data&&& wc.cbWndExtra = 0;&&&&&&&&&&&&&&&&&&&&&&& // Extra window data&&& wc.hInstance = hI&&&&&&&&&&&&&&&& // Owner handle&&& wc.hIcon = NULL,&&&&&&&&&&&&&&&&&&&&&&&&& // Application icon&&& wc.hCursor = NULL;&&&&&&&&&&&&&&&&&&&&&&& // Default cursor&&& wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);&&& wc.lpszMenuName =& NULL;&&&&&&&&&&&&&&&&& // Menu name&&& wc.lpszClassName = szAppN&&&&&&&&&&&& // Window class name
&&& if (RegisterClass (&wc) == 0) return 1;
&&& return 0;}//----------------------------------------------------------------------// InitInstance - Instance initialization//int InitInstance (HINSTANCE hInstance, LPWSTR lpCmdLine, int nCmdShow){&&& HWND hW
&&& // Save program instance handle in global variable.&&& hInst = hI
&&& // Create main window.&&& hWnd = CreateWindow (szAppName,&&&&&&&&&& // Window class&&&&&&&&&&&&&&&&&&&&&&&& TEXT("TextDemo"),&&& // Window title&&&&&&&&&&&&&&&&&&&&&&&& WS_VISIBLE,&&&&&&&&& // Style flags&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // x position&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // y position&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // Initial width&&&&&&&&&&&&&&&&&&&&&&&& CW_USEDEFAULT,&&&&&& // Initial height&&&&&&&&&&&&&&&&&&&&&&&& NULL,&&&&&&&&&&&&&&& // Parent&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&& NULL,&&&&&&&&&&&&&&& // Menu, must be null&&&&&&&&&&&&&&&&&&&&&&&& hInstance,&&&&&&&&&& // Application instance&&&&&&&&&&&&&&&&&&&&&&&& NULL);&&&&&&&&&&&&&& // Pointer to create&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // parameters&&& // Return fail code if window not created.&&& if ((!hWnd) || (!IsWindow (hWnd))) return 0x10;
&&& // Standard show and update calls&&& ShowWindow (hWnd, nCmdShow);&&& UpdateWindow (hWnd);&&& return 0;}//----------------------------------------------------------------------// TermInstance - Program cleanup//int TermInstance (HINSTANCE hInstance, int nDefRC) {
&&& return nDefRC;}//======================================================================// Message handling procedures for MainWindow////----------------------------------------------------------------------// MainWndProc - Callback function for application window//LRESULT CALLBACK MainWndProc(HWND hWnd, UINT wMsg, WPARAM wParam,&&&&&&&&&&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& INT&&& //&&& // Search message list to see if we need to handle this&&& // message.& If in list, call procedure.&&& //&&& for (i = 0; i & dim(MainMessages); i++) {&&&&&&& if (wMsg == MainMessages[i].Code)&&&&&&&&&&& return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam);&&& }&&& return DefWindowProc (hWnd, wMsg, wParam, lParam);}//----------------------------------------------------------------------// DoCreateMain - Process WM_CREATE message for window.//LRESULT DoCreateMain (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& HWND hwndCB;
&&& // Create a command bar.&&& hwndCB = CommandBar_Create (hInst, hWnd, IDC_CMDBAR);
&&& // Add exit button to command bar. &&& CommandBar_AddAdornments (hwndCB, 0, 0);&&& return 0;}//----------------------------------------------------------------------// DoPaintMain - Process WM_PAINT message for window.//LRESULT DoPaintMain (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& PAINTSTRUCT&&& RECT rect, rectC &&& HBRUSH hbrO&&& HDC&&& INT i,&&& DWORD dwColorTable[] = {0xx, &&&&&&&&&&&&&&&&&&&&&&&&&&& 0x00cccccc, 0x00ffffff};
&&& // Adjust the size of the client rect to take into account&&& // the command bar height.&&& GetClientRect (hWnd, &rectCli);&&& rectCli.top += CommandBar_Height (GetDlgItem (hWnd, IDC_CMDBAR));
&&& hdc = BeginPaint (hWnd, &ps);
&&& // Get the height and length of the string&&& DrawText (hdc, TEXT ("Hello Windows CE"), -1, &rect, &&&&&&&&&&&&& DT_CALCRECT | DT_CENTER | DT_SINGLELINE);
&&& cy = rect.bottom - rect.top + 5;
&&& // Draw black rectangle on right half of window&&& hbrOld = SelectObject (hdc, GetStockObject (BLACK_BRUSH));&&& Rectangle (hdc, rectCli.left + (rectCli.right - rectCli.left) / 2,&&&&&&&&&&&&&& rectCli.top, rectCli.right, rectCli.bottom);&&& SelectObject (hdc, hbrOld);
&&& rectCli.bottom = rectCli.top +
&&& SetBkMode (hdc, TRANSPARENT);&&& for (i = 0; i & 4; i++) {&&&&&&& SetTextColor (hdc, dwColorTable[i]);&&&&&&& SetBkColor (hdc, dwColorTable[3-i]);
&&&&&&& DrawText (hdc, TEXT ("Hello Windows CE"), -1, &rectCli, &&&&&&&&&&&&&&&&& DT_CENTER | DT_SINGLELINE);&&&&&&& rectCli.top +=&&&&&&& rectCli.bottom +=&&& }
&&& SetBkMode (hdc, OPAQUE);&&& for (i = 0; i & 4; i++) {&&&&&&& SetTextColor (hdc, dwColorTable[i]);&&&&&&& SetBkColor (hdc, dwColorTable[3-i]);
&&&&&&& DrawText (hdc, TEXT ("Hello Windows CE"), -1, &rectCli, &&&&&&&&&&&&&&&&& DT_CENTER | DT_SINGLELINE);&&&&&&& rectCli.top +=&&&&&&& rectCli.bottom +=&&& }&&& EndPaint (hWnd, &ps); &&& return 0;}//----------------------------------------------------------------------// DoDestroyMain - Process WM_DESTROY message for window.//LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam, &&&&&&&&&&&&&&&&&&&&&& LPARAM lParam) {&&& PostQuitMessage (0);&&& return 0;}
嵌入式系统的实时性问题
随着后PC时代以及网络、通信技术时代的到来,大量的计算机专业人员进入了嵌入式应用领域;然而,有大量的嵌入式系统应用是以的形式,应用在传统的技术领域中。因此,以计算机领域人员为主体的,远离对象系统的嵌入式系统的计算机工程应用模式,和以电子技术领域人员为主体,与对象系统紧耦合的电子技术应用模式产生了概念上的碰撞。许多电子技术应用模式熟视无睹、习以为常的概念,在计算机工程应用领域中作为一个新概念提出时,常常使电子技术应用领域中的人员感到莫明其妙。以前的“嵌入式系统”概念是其一,而今“嵌入式系统的实时性”又是一例。
1 什么是电子系统的实时性
任何一个电子系统都可看成是一个激励-响应系统。每个特定的电子系统都有一个从激励输入到响应输出的时间,即激励-响应周期T,它表现为系统的响应能力。如果系统的响应能力T能满足嵌入对象所规定的响应时间ta要求,即T≤ta,这个系统便是实时的电子系统。
那末,什么是嵌入对象所要求的响应时间ta呢?通常,不论哪一种电子系统,实现对象体系的控制管理要求,这些控制管理通常都会有一定的时间限制。例如,一个振动,对振动波形的检测周期必须满足采样定理要求;饮料生产线上的计量、馐,必须在一个工位的移动周期里完成秤量、封口的控制输出;对于超市中使用的电子秤,在秤量时,希望能立即显示出重量和计价金额;我们日常使用的计算机,在敲击键盘时,也要求在上快速地出现键盘输入结果。因此,几乎所有的电子系统都有一个客观的响应时间ta要求。这就电子系统普遍存在的实时性问题,即要求T≤ta。
2 三类电子应用系统的实时性
ta是电子系统具体应用时,客观应用环境提出的具体响应时间要求;不同类型电子系统的激励 -响应时间T的不同,形成不同的实时性问题。我们可以按不同的激励-响应时间T的特点,将电子系统分为经典电子系统、通用计算机系统与嵌入式系统,来讨论不同类型的电子应用系统不同的实时性特点。
①经典电子系统:不含计算机的纯电子系统,例如,测量、电子、温度(由ADC、译码器、构成)等,电路的动态特性决定了系统响应能力T的大小。经典电子系统是一个激励-响应系统,从激励到响应的时间完全取决于电子在电路中的运动过程,因而,它具有极短的、相对固定不变的,从激励到响应的时间周期T。在大多数经典电子应用系统中,由电路的动态特性决定了T值的大小。一般情况下,应用系统的T远小于嵌入对象系统的响应(ta)要求,因此,在经典电子应用领域中,应用工程师的头脑中没有“实时性”名词的概念,而对一些极快速响应要求的应用系统,如振动测量系统,它的实时性要求常常反映为电路系统的“频率响应”要求。
②通用计算机系统:是一个人机交互的激励-运行-响应系统。它的激励-响应时间T表现为电路系统的激励-响应时间tc与软件运行时间ts,而电路系统的激励-响应时间与软件运行时间相比为高阶小量,因而软件运行时间形成了T的主要成份,T= tc+ts≈ts。由于通用计算机系统只使用在人机交互环境中,对象(人)提出的响应时间ta要求,只是一个期望值(尽量快),而这种欲望一方面表现为永无止尽,另一方面又表现出现实的可容忍性。因此,通用计算机系统是一个非实时的电子系统,而快速性成为通用计算机系统发展的永恒主题。
③嵌入式系统:由于计算机的嵌入,嵌入式系统也是一个激励-运行-响应的电子系统。但是,它与嵌入对象体系交互时,要满足事件交互过程的响应要求。一方面,由于计算机的嵌入,嵌入式应用系统有十分可观的激励-响应时间ts,导致系统实时能力的降低;另一方面,由于嵌入对象体系的多样性、复杂性,不同的对象体系会提出不同的响应时间ta要求。因此,在嵌入式应用系统的具体设计中,必须考虑系统中每一个任务运行时,能否满足ts≤ta的要求,这就是嵌入式系统的实时性问题。
综上所述,经典电子系统应用中,没有显出实时性的概念,是因为电子系统的激励-响应时间T 极短,绝大多数电子系统都能满足T≤ts要求;通用计算机系统应用中,没有实时性概念,是因为ta只有期望要求;而嵌入式系统应用中,必须考虑实时性问题,是因为软件运行的时间耗费ts,会使系统的激励-响应时间T巨额增加,而不能满足嵌入对象系统提出的响应时间ta要求,现了嵌入式系统的实时性问题。
3 嵌入式系统的实时性分析
3.1 嵌入式系统实时性的出发点
嵌入式系统由于是嵌入到对象体系中的一个电子系统,与对象系统密切相关。而形形色色的对象系统会有不同的响应时间ta要求,如动态信号的采集系统、生产线的等,有严格的响应时间要求;超市的秤重、计量、收银机只要求有尽快的响应时间;在同样的动态信号采集系统中系统的响应时间与信号的动态特性有关。这些不同的嵌入式应用系统的不同响应要求,表现了嵌入对象响应要求(ta)的多样性。
嵌入式应用系统的激励-运行-响应特性,形成了以软件运行时间ts为主要内容的系统响应能力T。而软件运行时间ts与指令速度、编程技巧、程序优化等有关,是一个在应用系统设计中可以改变的参数,它表现了嵌入式应用系统实时能力的可变更性。
因此,ta的多样性要求与响应时间ts的可调整性,是嵌入式系统的实时性分析的基本出发点。根据嵌入对象ta的不同要求,调整、变更ts大小,以实现ts的最佳化,是嵌入式系统实时性设计的一项重要内容。
3.2 嵌入式系统的实时性分析
(1)实时性与快速性
嵌入式系统的实时性不是一个快速性概念,而是一个等式概念,即能否满足ts≤ta的要求。因而,快速系统不一定能满足系统的实时性要求,而某些情况下满足实时性要求时,系统的运行速度并不高。例如,满足温度采集实时性要求的嵌入式系统,运行速度并不高;而许多高速运行的系统,未必能满足冲击振动的信号采集的实时性要求。快速性只反映了系统的实时能力而已。
(2)系统的最佳实时
快速性是系统实时能力的表现。当系统不能满足实时性要求时,必须提高系统的运行速度,然而,运行速度的提高必然带来系统的一些负面效应,如导致系统功耗加大、电磁兼容性下降。因此,在设计一个具体的嵌入式系统时,在保证能满足实时性要求的条件下,应使系统的运行速度降到最低,以满足系统在功耗、可靠性、电磁兼容性方面获得最佳的综合品质。
(3)系统的实时性分配
在一个嵌入式应用系统中,有许多过程环节。例如,一个典型的就有信号采集、数据处理、结果显示、键盘输入等过程。这些过程往往是在不同的时间与空间上进行,而且不同过程的实时性要求是不同的。键盘输入、结果显示是与人交互的,要满足人机交互的实时性要求;信号采集与对象系统领带的动态性密切相在,必须满足由动态信号采集的实时性要求;而数据处理则会形成从动态信号采集到结果显示的时间延迟,影响到结果显示的实时性要求。因此一个优秀的实时系统设计,必须研究系统中的每一个过程环节,满足每一个过程环节和整个系统的最佳实时要求。
3.3 实时系统的动态误差
当我们研究嵌入式应用系统的实时性时,与对象系统相关的过程,必然是一个动态过程,否则便不存在实时性问题。对于任何动态过程,由于时间的滞后,都不可能完成重现原过程,这之间的差异便是动态过程的动态误差。例如,对于一个动态信号的数据进行采集时,在时间点t上启动采集命令,由于要执行一系列控制指令,产生Δtm滞后;另外,A/D有一个转换过程,产生Δtc滞后。由于这些时间滞后,致使在时间点t上采集的数据,实际上是时间点t+Δtm+Δtc上的信号数据,两者之差便是系统中数据采集的动态误差。在A/D转换中,常常会加入一个采样/保持电路,就是为了在Δtc窗口上,使动态信号值保持在Δtc的初始时间点上不变,便利信号值的变化只滞后t+Δtm,以减少动态误差。
由于系统在动态过程中控制的滞后,形成了某个任务环节上的动态误差,这个动态误差在对象系统的具体动态过程确定后,与动态过程的变化速率有关。在对象系统一个具体的动态过程确定之后,应根据对象动态过程的变化率和允许的动态误差值,估算出系统的允许滞后时间,这一时间就是应用系统中实现该动态过程实时性要求的响应时间ta。例如,在某一个动态电压信号数据采集中,信号的最大变化速率为 0.1V/ms,只考虑采集控制滞后的误差因素时,如该信号电压给定的误差应为1mV,就可以最粗略地估算出满足实练数据采集任务的响应时间ta要求, ta=1mV/(100mV/1ms)=0.01ms。如果系统的数据采集时间耗费ts能满足ts≤ta这一要求,系统就能实现数据的实时采集。
4 嵌入式应用系统的实时性设计
4.1 系统的实时性问题分析
由于嵌入式系统是嵌入到对象体系中的专用计算机应用系统,实现对象体系的智能化控制,因此,都存在着对象体系对控制过程的时间要求,与嵌入式系统能否满足这一要求的实时性问题。在很多情况下,应用系统设计中没有涉及实时性设计,这是因为目前计算机已有可观的运行速度,在大多数应用系统中,都能满足T≈ts≤ta,因此,在一般应用系统设计中,实时性设计并不突出。
通常,由于嵌入式系统实现的是对象系统的全面智能化控制,系统中会有许多相关的任务与过程。例如,一个数据采集系统不只是要实现对对象系统环境参数的采集,还要对采得的信号数据进行处理,对处理结果进行存储、显示,或实现对外部环境的控制输出,在这些进程中,还可能有人工的外界干预等。因此,一个实时的嵌入式应用系统,应该在所有的过程中都能满足T≈ts≤ta要求。由于系统中每个过程所要求的响应时间ta不同,例如,对对象系统环境参数采集时,时间响应要求决定于被采集参数的动态特性;控制输出时则取决了被控对象的控制品质要求;信号数据处理、存储,虽然表现为快速响应的期望要求,但占用了从激励输入到响应输出的中间环节。对这些环节的响应时间要求,必须纳入相关的任务中考虑。
因此,系统的实时性设计首先体现在应用系统总体设计中,要在总体设计中列出有实时性要求的任务,以及这些任务所要求的响应时间ta(如果所有任务的响应时间要求都是期望要求,则该应用系统不是一个实时的应用系统),然后考虑应用系统在实现这些任务时,必须耗费的时间ts。如果应用系统中所有的任务过程都能满足ts≤ta,则该应用系统是一个本质性实时系统。由于在考虑每个任务所必须耗费的时间 ts时,与使用的程序设计语言(是汇编还是高级语言)、程序应用环境(是否使用操作系统)、硬件环境(时钟系统、指令系统、时序等)有关,因此本质性实时系统的实时性与所系统使用的软硬件平台有关。
如果系统中有一些任务无法满足ts≤ta要求,则必须进行系统的实时性设计。
4.2 嵌入式系统的实时性设计
根据系统的T≈ts≤ta要求,在一个具体的有实时性要求的应用系统中,当系统的任务确定以后,就可以估算出每个任务的时间响应要求ta,在不考虑电路系统的中动态过程时,嵌入式系统的实时性设计的中心任务是通过软、硬件设计加快任务的运行过程,以达到ts≤ta要求。然而,加快系统的运行速度全带来其它问题,应在实时性设计中一并考虑。
嵌入式系统的应用领域十分广泛,并不是所有的应用系统都要求是实时系统,只有当系统中对任务有严格时间限定时,才有系统的实时性问题。例如,对这样一个嵌入式应用系统,人们并没有严格的时间限定,只有一个“尽可能快的”期望要求,因此,这样 的系统不是实时系统。
嵌入式系统的实时性设计通常会有以下几种情况。
①本质性实时系统。在这一类应用系统中,系统总体及任务的时限要求ta都不高,常规的软硬件技术都能满足ts≤ta要求。因此,这种应用系统往往不必要考虑系统的实时性设计。例如,一个温度测量系统,由于温度的大惯量特性,满足一定动态误差条件下的温度采集、数据处理、实时显示与打印的响应时间要求ta值很大,不必采取任何特殊的实时设计方法,就能满足ts≤ta要求,因此,它是一个本质性实时系统。
②通过实时性设计实现的实时系统。这种嵌入式系统在常规设计下,无法满足实时性要求,但通过实时性设计,可以满足实时性要求的系统。例如,一个仓储监测系统,要巡回监测100点的入侵事件。从应用要求的可靠性出发,要求系统对于任何一点入侵事件的响应速度(ta)不得大于1s;而系统对单个入侵事件的采集、处理、输出控制的实际激励-响应时间为0.2s。但在常规的巡回监测方式下,对某一点监测}

我要回帖

更多关于 给排水设计图例 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信