南京邮电大学
毕业设计(论文)外文资料翻译
学院自动化学院
专业自动化
学生姓名周戎
班级学号B11050320
外文出处Pont M J, Mwelwa C. Developing reliable embedded
systems using 8051 and ARM processors: Towards a new
pattern language[J]. Viking PLoP, 2003, 3: 1-18.
附件:1.外文资料翻译译文;2.外文原文
指导教师评价:
1.翻译内容与课题的结合度:□优□良□中□差2.翻译内容的准确、流畅:□优□良□中□差3.专业词汇翻译的准确性:□优□良□中□差4.翻译字符数是否符合规定要求:□符合□不符合
指导教师签名:
年月日
附件1:外文资料翻译译文
基于ARM和51单片机系统的可靠的嵌入式处理器的开发:一个新的模式语
言
Michael J. Pont and Chisanga Mwelwa Leicester大学,机械系,嵌入式系统实验室
介绍:我们曾经将一个包括了80种模式的语言叫做PRE集合。这种语言被设计出来促进那些使用很少内存的微型控制器的发展,包括比如那些平均拥有数百字节内存的8051系列。
这些模式的第一批的应用大概在三年前,并且它们被应用于工厂的系统,大量的大学研究项目和大学课程中的本科和研究生教育。我们也开始准备去开发一个工具去帮助使用这些模式的嵌入式系统的发展(Mwelwa和Pont,2003)。
当我们对这些集成的经验不断增加,我们开始加入一些新的模式和修改一些现存的一些模式(例如see Pont和Ong,2003;Pont,2003;Key,2003)。必然的是,从定义上来说,一个语言应该包括一系列有着内部关联的模式:因此,不太可能出现缩小或延长这样的一个系统而不出现副作用的情况的。但是,因为我们使用过这个集成,我们感觉到我们可以搭建一个整体的架构来降低未来的影响。
这篇文章简略的介绍了一些我们对于重构原始模式集成所作的改变。接着说明了由这个处理器产生的新模式之一。
两个处理器系列
在我们看到这个集成的第一印象中,最重要的局限之一就是我们使用一个单一的硬件平台(8051)来阐述这些模式的使用。这个导致暴露了一个事实是:在绝大多数情况下,这些系统适用于一个广泛的不同的处理器与系统的范围。
在这些修改过的模式里,我们举了包括8051微处理器系列和ARM系列器件的例子(图1)。
这些器件都是这些嵌入式设计的一般选择,但是8051(8位处理器)更趋向于适用于―低端‖的情况,而ARM系列(16/32位处理器)更趋向于被应用于需要更大存储空间或者更好的CPU 性能的情况。这两个系列的覆盖应用帮助我们集中于这些被修改后的模式的―核心‖特征,并且我们提出了这些―例子‖部分被贯彻的特殊细节。
图1:被用于修改模式集成的两个嵌入式处理器的外观
Philips LPC932(左)是流行的8051系列设备中的一个8位设备。
Philips LPC2106(右)是基于16/32位ARM7TDMI处理器核心的设备。
个人电脑上的原型
除了之前部分里说到的8051和ARM处理器,修订后的设备也包括对在台式电脑上使用的一个创新的原型的讨论。我们可以看到这些例子将会对那些想要使用个人电脑平台来作为一个复杂的嵌入式系统原型,而不是采用一个微处理器的开发者来说极其重要。它们也将对那些想要找到一个高效的培训嵌入式系统的软件编程方式的公司,大学来说,也很重要。最后它们将被那些想要从使用低成本硬件的嵌入式系统获取经验的业余开发者使用。
一些陈旧的,一些崭新的……
我们在本文中提到了两个模块,第一个是PORT WRAPPER(一个新的模块);第二个是第一次在2001年出现在我们原始模块中的PORT HEADER。
请注意到PORT HEADER(基于PORT WRAPPER的模块)仅仅被用于参考,这是为了阐明我们在修改集成时做了什么样的改变(模块结构和内容上的)。
使用的工具
为了开发我们此文中提到的微处理器核心,我们使用了Keil C51和Keil/GNU ARM 工具。这些编译工具的评估版本从https://www.doczj.com/doc/667541053.html,中获得
为了开发个人电脑核心,我们使用了―Open Watcom‖编译器。这个编译器(免费下载)可以在https://www.doczj.com/doc/667541053.html,/获得
鸣谢
我们非常感谢为我们这篇文章的草案提供了很多细节上建议的VikingPLoP的Shepherd。
我们也非常感谢为参与了我们在VikingPLoP工作室并提供了很多有用建议的Neil Harrison,Klaus Marquardt,Bemhard Grone和Peter Tabeling。除此之外,会议结束后,Neil Harrison 还非常慷慨的审核了我们的修改稿。
我们还将感谢为本文中提到的工作做出卓越贡献的Chris Hills(Keil,UK)和Trevor Martin (Hiter,UK)。
最后也是最重要的是,我们将感谢为这个大工程提供了长久的信任的Simon Plumtree (Addison-Wesley,UK)。
版权
版权?2003Michael J.Pont和Chisanga Mwelwa。允许针对VikingPLoP2003的复印。其他权利将予以保留。
PORT WRAPPER
内容
你将开发一个使用8051,ARM或者相似处理器的嵌入式系统。
稳定性将是一个重要的设计考虑。
你的系统将会被很多人开发,移植,维护。这意味这个系统建设将牵涉一个开发团队。或者,这个可能意味着你的系统是被―一个人的团队‖开发的,并且将被其他人经常维护和移植。
你要保持开发成本(现在的和将来的工程)尽可能的便宜。因此,你需要将移植你现在的代码的一部分去一个新的工程或者移植一部分甚至所有你的系统去一个硬件平台这个行为很容易。
你要将内存以及处理器的要求降到最低,为了能够被允许使用更便宜的硬件平台,并因此将整个系统的成本降到最低。
你将用C语言编程。
问题
你怎么完成在这个工程中引脚的分配和初始化?
设计约束
在一个典型的嵌入式工程里,你将使用一个LCD,一个键盘,和一个乃至多个LED灯作为用户借口。也需要有一系列的线(比如,RS-485和CAN)连接到另一个微处理器板。这里可能需要一个或者更多的被你控制的元件。
典型的是,这个工程将用C语言搭建,LCD接口,键盘以及其他的元件都使用独立的文件。每一个文件都要求与微处理器的一些引脚相联系,然后代码就像图2所示
File:‖LCD.C‖ File:‖KEYpad.C‖File:―LED.C‖
Sbit Pin_A=P3^2; #define Port_B=P0; sbit Pin_C=P2^7
… ……
图2:一个在简单的嵌入式工程中控制引脚的非正式方法。这些工程中的文件直接链接着处理器中不同的引脚。因为文中讨论的原因这个途径不被推荐。
当使用这种编程代码,你将遇到下面的设计约束:
你需要确定没有―引脚冲突‖,比如你不希望出现人们在写LCD代码的时候使用人们写开关或者三相电动机时的引脚口是相同的。这可能是很危险的,如果你的系统涉及了高电的载入并且检查不充分的话。这个可能会导致代码的重新设计,和昂贵的PCB改变,如果没有在工程流程中较早的检测出来的话。
你得确定所有的引脚都初始化的正确,如果没有这样做,这个系统可能不会像要求的那样工作。假设你正确的在你的微处理器上配置了―X引脚‖来―输入‖,为了在紧急情况下切断开关。如果,在工程中反应迟了,一个新的部件被不经意间设置X引脚为―输出‖,系统的使用者将没有方法来停止紧急情况下的系统。
解决方法
创建一个合适的Port Wrapper可以帮助你成功在一个大工程中分配端口,并且从而满足前面部分标亮的设计缺陷。
一个Port Warpper是由以下部分组成:
一个端口头文件,最少包括你的工程中包括的所有端口。
一个端口初始化器,这是一个配置你系统包括输入输出等所有引脚的机制。
很多需要做的措施是很必要的:下面就是我们要讨论的一般方法。
实施
基础实施
在解决方法中提到的两个两个部件是容易被实施的,经常被使用的一对文件是―H端口‖和―C端口‖。
H端口
H端口可以简单的包含你工程中的所有的端口许可,并且连着它们和相对应的文件,比如,这有可能看上去像这样:
/*port.h/
/*File:lcd.c
This uses pins 0.0 to 0.4,as follows…*/
/*File:keypad.c
This uses pins…*/
必然的是,这样的文件可以―合拍‖并且对于所有的多发的原因—代码是―个人文件‖是被广泛需求的。可以使用#define和相类似的机制来确定头文件
一些完整的H端口文件被在下面给出
C端口
C端口经常包含一个功能就是要按照要求的配置来配置端口引脚,比如,考虑下面的例子:/*port.c*/
V oid PORT_Init(void)
{
/*Prepare for Icd(see lcd.c)*/
…
/*Prepare for keypad(see keypad.c)*/
…
}
一些完整的C端口在下表被列出来。
有多少wrapper?
如果你的开发是被一个团队做出来的,那么你将遇到困难,如果很多的团队想要做出改变来分享C端口文件和H文件。
最简单的解决方法是工作,最初的是,每一个部分都有不同的一对文件。比如,LCD端口有它自己的C端口和H端口文件,当这个工程阶段一体化的时候,所有的端口文件都要合在一
起。这是一个简单的解决方法,并且避免了一体化后工程中不同部分中的WRAPPER文件的参考量的改变。
一个替代的方法是为每一个部分创建一个不同的WRAPPER文件(比如,LCD.H端口)。当工程一体化时它们可以作为不同的的文件存在。这个方法有一个好处是这些WRAPPER文件不需要随着系统一体化而改变(也就是说,这个最终工程的每一部分都有相对应的不同的一对WRAPPER文件)。这样可以使得移植和维护更加的直接。
注意到在这两个案例中,我们要求一个规范来确保开发者使用的每一个引脚被其他开发者所知道。
可依靠性和安全含义:
我们确定一些重要的在这个部分里联系了端口的可靠性和安全性。
引脚复位值
不管你在使用哪一个处理器,你需要对引脚复位值多加以关注。
试想,比如,你连接了一个电动装置在端口处,并且这个装置是被―逻辑1‖输出使能的。如果,出现了错误,你的微处理器将引脚的复位值设置为―1‖。那么电动装置将会启动。即时在一开始你将你的程序的引脚输出设为0,这个装置仍将产生一个短暂的的脉冲。在一些系统里这个可以导致系统使用者或者旁人的受伤甚至死亡。
确定你的硬件和软件设计与复位值相适应是很重要的。最好试着或者确定你的微处理器引脚的复位值为―0‖和你的外部设备被引脚值―1‖使能驱动。
引脚冲突
除了它的简便,PORT WRAPPER可以提升系统的可依靠性,因为它避免了端口引脚的潜在冲突,特别是当开发者维护(他可能没有参加原始代码的编写)时可能造成的代码的改变。硬件要求
使用PORT WRAPPER有着最低的硬件要求。
成本含义
任意以文档为基础的技术都有一个最初的成本,因为任何形式的标志或注明都需要时间来完成。但是任何初始成本都会因为维护或移植的工作变得简单而得到偿还。
维护
PORT WRAPPER是一个基于代码约定的大型的手动资料技术。它需要整支团队对软件开发的在规定途径下的正确操作。有的时候,特别是最终期限催的比较紧的时候,文档会超前于系统。
如果你需要使用PORT WRAPPER来维护系统,在做任何改变之前检查信息记录是否正确是一个好主意。
可移植性
使用PORT WRAPPER可以帮助提升可移植性,从一个地方移植到所有允许移植的端口。请注意到,正如在―维护‖中讨论中的一样。在开始移植之前,检查WRAPPER文件与系统硬件是否匹配是一个很好的注意。
请注意到,如果你想移植应用程序的一部分(说的是RS-485端口),使用多重WRAPPER 方法将会使其更容易。
相关的模式和替代解决方案
硬件问题
这种模式不涉及硬件设计,see Pont,2001,A部分和C部分解决了这些问题。
代码库
在桌面的设计,“显而易见”的解决方案,是通过端口包装解决创建一个类或函数库,完全封装的端口引脚控制和初始化的问题。这样的库可以用来解决许多问题与端口的初始化或端口冲突。不幸的是,因为系统收到资源严重约束,库的使用经常需要避免,因为会产生超额费用。如果,你选择开发和使用这个数据库,您可能会限制你的代码架构的可移植性。
整体的优势和劣势
PORTWRAPPER可以在两个乃至更多的系统模块中帮助降低引脚冲突的可能性(使用相同的引脚,为了不同的目的)。
PORTWRAPPER可以帮助你的引脚正确初始化。
PORTWRAPPER只需要少量的CPU和内存需求。
PORTWRAPPER是一个基于代码约定的大型的手动技术,它依赖于一个有规则的软件开发方法来进行正确的操作。
PORTWRAPPER里面说到得技术在大型嵌入式工程中并不十分实用。这样的工程在这个模块中提到的资源限制的处理器中很少见,但是,如果你需要要开发这样的一个工程,你会发现这个更适合使用数据库。
例子:在LPC900系列上闪烁LED灯
我们通过举一个简单的例子来说明如何在LPC900系列上如何创建一个PORT WRAPPER 文件。
#Ifndef PORT_H
#define PORT_H 1
//Prototype for init function
V oid Port_Init(void);
//-------LED_Flas.C--------------------------------------------------------------------------
//Connect LED from +5V to this pin,via appropriate resistor
Sbit LED_pin=P2^0;
#endif
表一:一个在LPC900上的PORT wrapper例子(h端口)
V oid PORT_Init(void)
{
//Assuming Port 2 ,Pin 0 used for LED
//Set this pin to push-pull output
//[Relevant SFRs are not bit addressable]
P2M1=0xFE;
P2M2=0x01;
}
表二:一个在LPC900上的PORT wrapper例子(C端口)
Int main(void)
{
//Initialise the port pins are required
Port_Init();
//Prepare to flash LED
LED_FLASH_Init();
While(1)
{
//Change the LED state (OFF to ON,or vice versa)
LED_FLASH_Change_State();
//Delay for *approx*1000ms
LOOP_DELAY_Wait(1000);
}
Return 1;//Should never reach here…
}
}
表三:一个在LPC900上的PORT wrapper例子(C主函数)
例子:用LPC2100系列来控制LED灯
我们通过举一个简单的例子来说明如何在LPC2100系列上如何创建一个PORT WRAPPER 文件。
#ifndef PORT_H
#define PORT_H 1
//Prototype for init function
V oid PORT_Init(void)
//---------LED_Flas.C--------------------------------------
//Connect LED from ground to this pin,via appropriate resistor
//LED pin is GPIO pin 0.0
#define LED_pin 0x00000001
#endif
表四:一个在LPC2100上的PORT wrapper例子(h端口)
#include‖main.h‖
#include‖port.h‖
/*……………………………………………………………………*/
V oid PORT_Init(void)
{
//1.Set up LED pin as GPIO
//2.Set to output mode
//1.
//Just pin 0.0 as GPIO
PINSELO&=0Xfffffffe
//2.
IODIR=LED_pin;
}
表五:一个在LPC2100上的PORT wrapper例子(c端口)
#include‖main.h‖
#include‖port.h‖
#include‖led_flas.h‖
#include‖loop_del.h‖
/*………………………………………………………………………………………………………….*/
Int main(void)
{
//Initialise the port pins as required
PORT_Init();
//Prepare to flash LED
LED_FLASH_Init();
While(1)
{
//Change the LED state (OFF to ON, or vice versa)
LED_FLASH_Change_State();
//Delay for *approx*1000 ms
LOOP_DELAY_Wait(1000);
}
Return 1; //Should never reach here…
}
表六:一个在LPC2100上的PORT wrapper例子(c主程序)
例子:在电脑平行端口上闪烁LED
我们通过举一个简单的例子来说明如何在PC上如何创建一个PORT WRAPPER文件。
图三:连接LED到平行端口
//Setting for LPT1
//See paper for details
#define LPT1_DATA 0x0378
#define LPT1_STATUS 0x0379
#define LPT1_CONTROL 0x037A
//--------------------Public function prototypes-------------------------
V oid PORT_Init(void);
V oid PORT_Write_Bit(const tword PORT, const tWord PIN, const tword V ALUE);
例子七:一个在PC上的PORT wrapper例子(h端口)
#include ―Main.h‖
#include ‖Port.h‖
#include
#include < conio.h>
/*…………………………………………………………………………………………..*/
V oid PORT_Init(void)
{
/*
In the PC, the ports default to ―output‖ mode.
No initialization is therefore required in this simple example.
We simply record that Pin 0 on the data port (Pin 2 on the parallel port) is used to control the LED.
*/
}
/*------------------------------------------------------------------------------------------------------------------*/
V oid PORT_Write_Bit(const tword PORT, const tWord PIN, const tWord V ALUE)
{
tWord p=0x01;
tword old,New;
p<<=PIN;
//Read current port value
Old=inp(PORT);
//If we require a 1 at the pin
If(V ALUE==1)
{
New=Old;
}
Else
{
P=~p; //Complement
New&=p;
}
//Write the new value
Outp(PORT,NEW);
}
例子八:一个在PC上的PORT wrapper例子(c端口)。
#include ―main.h‖
#include ‖port.h‖
#include ‖led_flas.h‖
#include ―loop_del.h‖
/*…………………………………………………………………………………………*/
Int main(void)
{
//Initialise the port pins as required
PORT_Init();
//Prepare to flash LED
LED_FLASH_Init();
While(1)
{
//Change the LED stste (OFF to ON,or vice versa)
LED_FLASH_Change_State();
//Delay for *apprpx*1000ms
LOOP_DELAY_Wait(1000);
}
Return 1;//Should never reach here…
}
例子九:一个在PC上的PORT wrapper例子(c主程序)
背景材料,并进一步阅读
端口接头
内容
你使用一个或更多的8051系列的微处理器来开发一个嵌入式系统。
问题
你怎么在一个较大的项目中管理分配端口的访问?
背景
在一个典型的嵌入式项目,你可能必须使用LCD,键盘以及一个或一个或多个单个的LED 来创建一个用户接口。也许会有一系列的连接线到另一个微处理器。有可能是你的应用程序来控制一个或多个大功率器件。
每个应用程序中的这些部件需要独占访问的一个或多个端口引脚。这个工程可能包括10-20不同的源文件。你怎么确定一个部分端口许可的改变不会影响另一个?你怎么确定在一个不同的引脚必须得被使用的环境,我们能够容易的应用端口。
这些问题通过简单的端口接头的设计模式可以解决
解决方法
端口接头封装了一个简单而有效的设计指导,可以帮助你应付在一个较大的项目很多不同的组件将每个需要的端口访问的事实:具体而言,使用端口头,你会为整个项目的不同的端口访问功能集中到一个文件中。使用这个技术可以容易的开发,维护,移植工程。
端口接头是容易理解和使用的
考虑一下,比如,我们在一个工程中有3个C文件(A.B.C)每一个需要一个或更多的端口引脚,或者一个完整的引脚。
A文件可能包括以下内容:
//File A
Sbit Pin_A=P3^2;
…
B文件可能包括以下内容:
//File B
#define Port_B=P0;
…
C文件可能包括一下内容:
//File C
Sbit Pin_C=P2^7;
…
在这个版本的代码中,所有的端口接入的需求分布在多个文件中。通过整合所有端口的访
问于一个单一的H端口头文件中有许多优点:
//------Port.H---------------
//Port access for File B
#define Port_B=P0;
//Port access for File A
Sbit Pin_A=P3^2;
//Port access for File C
Sbit Pin_C=P2^7;
…
每一个保留的工程文件将有―#include Port.H‖.
表13展现了一个H端口的完整文件:
/*---------------------------------------------------------------------*/ Port.H(v1.00)
------------------------------------------------------------------------
?Port Header‘(see Chapter 10) for the project LCD_KEYP.PRJ //----------------Sch51.C--------------------------------------------- //Comment this line out if error reporting is NOT required
//#define SCH_REPORT_ERRORS
#ifdef SCH_REPORT_ERRORS
//The port on which error codes will be displayed
//ONLY USED IF ERRORS ARE REPORTED
#define Error_port P1
#endif
//-------------Keypad.C----------------------------------------------- #define KEYPAD_PORT P0
Sbit C1=KEYPAD_PORT^0;
Sbit C2=KEYPAD_PORT^1;
Sbit C3=KEYPAD_PORT^2;
Sbit R1=KEYPAD_PORT^6;
Sbit R2=KEYPAD_PORT^5;
Sbit R3=KEYPAD_PORT^4;
Sbit R4=KEYPAD_PORT^3;
//------------LCD_A.c---------------------------------------------------
//NOTE:Any combination of 6 pins may be used (any ports, any order)
//NOTE:Number in [] are pin numbers on *MANY* LCDs
Sbit LCD_D4=p1^0; //DB4 [11]
Sbit LCD_D5=p1^1; //DB5 [12]
Sbit LCD_D6=p1^2; //DB6 [13]
Sbit LCD_D7=p1^3; //DB7 [14]
Sbit LCD_RS=p1^4; //Display register select output [4]
Sbit LCD_EN=p1^5; //Display enable output [6]
//Connect Vss [1] on LCD to Gnd
//Connect Vcc [2] on LCD to +5v
//Connect V o [3] on LCD to Gnd
//Connect RW [5] on LCD to Gnd
//----------LED_Flas.C-------------------------------
//Connect LED from +5v (etc) to this pin, via appropriate resistor
//[see Chapter 7 for details]
Sbit LED_pin=p1^5;
/*---------END OF FILE------------------------------*/
表13:一个在端口上包含键盘和液晶屏中的工程包含端口头文件(H端口)的例子.
硬件资源的影响
没有硬件资源的影响。
稳定性和安全性
除了其很简单,端口头文件可以提升安全性和可依靠性,因为它可以避免潜在的引脚冲突,特别当工程的维护阶段里开发者被要求做出代码改变。
可移植性
端口头文件自己具有可移植性,它可以被用在各种微处理器,并且和8051系列没有联系,使用端口头文件还可以提升可移植性,通过使访问一个位置,可以使所有的应用程序的端口存取达到质量要求。
总体优点和缺点