关键词: 编程
嵌入编程(精选九篇)
嵌入编程 篇1
随着控制技术向网络化、智能化和开放式发展,传统PLC逐渐暴露出其许多不足。主要表现为技术封闭,造成了各生产厂商的PLC产品互不兼容,且编程开发方法差别很大,技术专门性很强,用户必须经过长期培训才能掌握其中一种产品的开发方法,这些问题制约了传统PLC的快速发展[1]。随着计算机科学的发展和工业控制的IEC61131国际标准的制定,出现了用软件方式实现传统PLC控制功能的软PLC技术。
软PLC具有符合现代工业控制技术的优点,体系结构开放,支持多种硬件环境,解决了传统硬PLC互不兼容的问题。软PLC把控制运算的功能封装在软件中,具有传统PLC的功能,可在计算机操作系统中实现程序的编辑、运算、编译、存储等功能,具有编程语言标准化、控制功能模块化、硬件配置灵活等特点[2]。
本文介绍的嵌入式软PLC编程系统软件在Windows环境下引入VC++开发工具,利用VC++强大的软件功能,使人机交互界面更友好,由于VC++固有的面向对象机制,可方便地设计梯形图数据结构,并结合相应的算法,完成软PLC编程系统设计。本文主要给出编辑、编译和仿真模块。
2 嵌入式软PLC系统的总体框架
嵌入式软PLC主要由编程系统和运行系统组成。编程系统进行梯形图的编辑、指令的解析以及生产目标代码;运行系统执行目标代码,实现控制目的[3]。其总体架构如图1所示。
软PLC编程系统的编程语言基于国际电工委员会发布的IEC61131-3国际标准,是一个通用的开发环境,主要是由编辑、编译、仿真和通信四大模块组成[4]。其中编辑模块提供用户程序开发环境;编译模块实现对用户程序的扫描和编译;仿真模块用以离线模拟、调试用户程序;通信模块负责把编译后的用户程序目标代码下载到运行系统。
3 软PLC编程系统的界面设计
IEC61131-3国际标准(International Electro technical Commission)定义了5种PLC编程语言的规范:梯形图(LD)、顺序功能图(SFC)、功能模块(FBD)、结构化文本(ST)和指令表(IL)[3]。由于梯形图简单、直观,所以本编程系统主要采用梯形图作为用户程序的开发语言。
本软件采用VC++开发工具,并基于多文档的Document/View结构设计,以支持梯形图和指令表对应的格式—*.lad和*.txt。其界面由梯形图编辑区、指令表区和信息输出区三部分组成,如图2所示。
1)梯形图编辑区用于梯形图驻留和相关参数的设置;
2)指令表区用于显示梯形图对应的逻辑指令;
3)信息输出区显示梯形图可能的语法错误信息以及正确执行后的输出信息。
4 梯形图数据结构设计
4.1 梯形图元件类的继承关系设计
梯形图元件包括常开触点、常闭触点和输出线圈等简单元件和定时器、计数器、数据运算(包括加减运算、比较运算等)等复杂元件。由面向对象的继承特性,可以抽象出一个类作为梯形图元件的总体接口,再以这个类为基础,派生出具体的元件子类。梯形图元件的抽象类定义如下:
由此抽象类派生出简单元件类和复杂元件类,并扩充相应的属性和方法操作;再由这两类派生出具体元件类,如常开触点或定时器等。如图3所示为各元件类型的继承树示意图。
4.2 梯形图容器的数据结构设计
整个存储梯形图的容器选择用双向链表结构表示。其原因基于以下两点:(1)对梯形图的添加、修改、删除等操作,能够方便地运用链表的存储结构完成;(2)梯形图的编辑过程是动态的,梯形图的行数、列数和元件类型都是未知的,这种动态存储过程,用链表结构比其它的数据结构表达得更为清楚、有效。
存储梯形图的双向链表在文档类中定义为:CObList m_LADList,存储梯形图的容器。由此,添加梯形图元件,实质就是在内存中建立相应的对象,并调用链表的AddHead或AddTail函数加入该对象的指针;而删除梯形图元件,实质就是调用链表的RemoteHead或RemoveTail函数移除链表中对应对象的指针。下列代码表示生成一个常开元件对象,并把该对象的指针加入到链表中:
4.3 用户对梯形图元件的控制
用户通过与编程界面的交互,达到对梯形图元件的控制。为了缩小显示、控制和梯形图元件三者间的耦合性,可引入MVC(Model-View-Control)模式解决。其中,由VC++中的CView类充当显示部分,并设计CPLCEleController类用以控制梯形图元件。CPLCEleController类依赖于工厂类CPLCEleFactory类,通过简单工厂模拟以创建梯形图元件实体,并且针对编辑、编译和仿真的操作封装了相应方法。其定义如下:
5 梯形图的编辑
梯形图的编辑部分封装于视图类,能实现存储与显示分离,以有效降低代码的耦合性。
梯形图的编辑大体可分为以下步骤:(1)选择所要加载的梯形图元件类型;(2)用户在编辑区单击鼠标,扫描程序获取单击对应位置的笛卡儿坐标值;(3)添加该梯形图元件到存储链表中;(4)在窗口中显示该梯形图;(5)设置梯形图元件的其它参数。
5.1 梯形图的绘制
矢量图是计算机通过数学表达式解析的图形,具有内存消耗小,操作灵活的特点。因此,本软件按矢量绘制梯形图。
在VC++中,MFC类库中的CDC类封装了矢量图的相关操作,由此,对梯形图的绘制可以通过遍历链表,并调用CDC类对象指针的函数来完成。并基于面向对象的多态性调用各元件实际的绘制操作:
梯形图被绘制后,其类型、行号、列号信息均被确定。而其它的参数,如元件编号、定时器的时基,由用户输入确定,具体可以通过添加消息映射函数,扫描鼠标操作实现。当用户双击某梯形图元件时,弹出参数设置对话框,输入数据后,相关的参数就被绑定在该元件对象中。下面的代码片段表示对定时器设置参数。
5.2 梯形图的序列化
要实现梯形图的多次编辑,就要对梯形图实现序列化,将其保存为文件;而当再次调用时,需要把程序加载到内存。
对于Document/View结构,数据都存放于CDocument类里,将其中的变量写入文件,即实现了梯形图的序列化;打开文件时,通过动态创建机制,把其中变量导入内存,即实现了梯形图的反序列化。
由于梯形图元件类继承了CObject类,因此,运行时其自身具有类型识别和动态创建的功能,在CArchive类中调用重载的读写运算符">>"和"<<",就能执行相应文件缓冲区建立和数据读写。
6 梯形图的编译
梯形图的编译是编程系统的关键部分,因为编译的实质是把用户编辑的梯形图程序,经过语法分析和逻辑分析,循环扫描,最终生成运行系统可识别的目标程序。
按照梯形图编程语言规范,编译程序扫描梯形图,经过语法分析和逻辑分析后,若发现梯形图有错误,便生产相应的错误提示信息,并复制到用户界面。
6.1 梯形图的扫描
梯形图扫描和编译以梯级为单位,且梯级是由相互影响的行组成的最小单元,图4所示为一个梯级。对梯形图的扫描采用深度扫描算法,即以竖线元素作为逻辑区分,对梯形图网络自左向右,从上到下,逐个元素进行。
以图4为例,一个梯形图梯级的深度扫描过程为:(1)首先读取串联关系的元件X1和X2;(2)遇到并联接点A,从而转至下一行扫描,读取元件X4;(3)遇到并联接点B,转至下一行,读取元件X6;(4)回到并联接点B,读取元件X5;(5)回到并联接点A,读取元件X3;(6)读取输出元件Y1,则完成该梯级的扫描和编译。
实践证明,该扫描算法容易实现,能深入解析梯形图逻辑关系,占用存储空间较少,扫描效率较高。
6.2 梯形图数据信息的记录
为了提高移植性,降低运行系统程序与VC++程序的耦合度,本软件引入了生成相应配置文件技术,以记录梯形图的数据信息,供仿真模块或运行系统读取。
梯形图被扫描过程,程序自动生成梯形图相关的逻辑关系数据对应的配置文件,用四组数字分别代表梯形图的类型、连接关系,包括复杂元件中定时器的时基等数据信息,以备在运行系统加载。其梯形图数据信息存储结构示例如表1所示。
表1存储了一个梯形图的梯级信息,一个梯形图元件对应表中的一格,表中"X-X-X-X"的格式为简单的元件信息,分别表示“元件类型-连接关系-存储类型-对应存储类型数组的偏移量”。如表中第1行第1列的"1-0-0-25"数据,代表梯级中位于第1行第1列,无并联关系的常开触点,它在简单元件类型输入数组中的存储偏移量为25。
7 梯形图的仿真
为了判定被编译程序执行的正确性,本编程系统设计了仿真模块,以模拟现场梯图程序运行。仿真需要将梯形图程序转化为C程序,以实现逻辑控制。
仿真模块主要分为逻辑运算模块、算术运算模块和梯形图更新显示模块。其中,逻辑运算模块是仿真模块的核心,负责对梯形图数据信息的识别,以及逻辑状态的转移。
仿真程序通过读取存储梯形图逻辑信息的配置文件,并还原对应每个梯形图元件及相应的逻辑关系。以下的代码片段通过运行是类型识别,反映了当前读取的元件是常开/常闭触点或输出线圈时的逻辑运算:
动态仿真过程在梯形图编辑区实时显示方便用户进行错误定位、追踪。具体表现为梯形图元件能流导通时的变色反显,可通过重绘触发的方式实现。
8 结束语
本嵌入式软PLC编程系统实现了梯形图的编辑、编译和仿真功能。并基于VC++开发平台面向对象的封装、继承和多态性,通过编辑过程引入存储梯形图信息的配置文件,实现了编译与仿真的桥接,有效地降低了与VC++开发环境的耦合度,移植性强。
参考文献
[1]高金刚,陈建春,刘雄伟.数控系统的软PLC系统开发[J.]计算机测量与控制,2004,12(3):254-256.
[2]肖世广,李彦,吉华.Linux环境下基于Qt库的软件PLC编程系统[J.]计算机工程与设计,2007(4):1663-1666.
[3]黄延延,林跃,于海彬.软PLC技术研究及实现[J.]计算机工程,2004,30(1):165-167.
嵌入编程 篇2
1.1编辑器编程
为实现Flash编程,专门开发和设计了编辑器,通过配套使用,便能将指令或数据写入其中。该方式较老旧,对实施条件的要求也较严格,必须保障芯片在焊接到电路板之前进行,等到编程结束以后再进行焊接。目前,较常见的编辑器类型有LABTOOL-48、SUPERPRO/V等。编程器编程的主要优势在于使用较便利,且编程效率较理想,十分适宜DIP封装的Flash芯片。
1.2普通接口编程
在实际应用过程中,嵌入式系统为充分发挥作用,通常会在硬件设计中加入一些外围接口,这些接口包括串口、USB、网络接口等。而在Flash编程中,便可以借助这些接口、串口直接实现。接口编程的方式与JTAG编程相比,没有对特殊接口进行要求。
1.3JTAG编程
JTAG作为嵌入式调试技术,其接口标准为IEEE1149.1,主要应用于边界扫描与端口测试中。同时,采用JTAG接口不但能够完成测试操作,还可以实现对嵌入式系统中的`Flash编程。在实际应用过程中,对JTAG进行编程操作应借助接口仿真器,将目标机与宿主机联系起来。在目标机上,将处理器与Flash总线相互连接,再借助宿主机中的既定程序,将数据、指令与控制信号均传送到JTAG接口芯片中。这时,处理器中将会接收到JTAG传递过来的信息,并按照Flash芯片进行编程,将接收到的信息写入其中,完成最终编程操作。与编辑器编程、普通接口编程方式相比,JTAG编程技术更为简便,无需对芯片焊接流程进行严格规定,只需借助JTAG借口线与仿真器便能完成测试,因此,嵌入式系统中Flash编程得到了广泛应用[1]。
2通过JTAG接口实施Flash编程的实例分析
在某项目开发设计过程中,采用JTAG接口完成Flash编程。在该设计过程中,JTAG的电缆与主机并口相互连接,另一侧连接到电路板中的JTAG插座上,再与处理器PowerPC405EP相连,Flash需要经过总线与处理器相连。在上述连接完毕以后,Flash无需具备JTAG接口,使用范围也更加广阔。在对Flash进行编程的过程中,PowerPC405EP由主机软件进行控制,利用其模拟Flash的编程时序,便能对Flash进行编程。
2.1硬件配置
第一,JTAG下载电缆设计。在JTAG接口标准的基础上,对信号逻辑电平中传输要求、数据、传输方向等进行综合考虑,最终选择采用并口标准与接口并行的模式,二者间关系如下:PC并口中管脚2的功能为D0;管脚3的功能为D1;管脚4的功能为D2;管脚5的功能为D3;在JTAG接口中,管脚TDI的功能为数据输入;TCK的功能为时钟;TMS的功能为模式选择;TRST的功能为复位;TDO的功能为数据输出。第二,嵌入式处理器PowPC405EP。在本系统设计中,采用的处理器为IBMPowPC405EP,属于一款32位、RISC指令集处理器,其性能较为良好,集嵌入式软核、外围设备系统SOC于一体。通过数据手册进行描述,得知BSR的长度与指令代码等内容,具体如下:指令Bypass,代码1111111;指令Extest,代码0000000;指令Sample,代码1111010。第三,Flash。在本系统设计中,使用的Flash为富士通SPANSIONMBM29DL,工作电压为3V,用户在使用之前,需要将特定地址写入到对应的指令序列中,便可以将其启动,使其在自动化下完成指令,包括复位、自动选择、擦除、编程等[2]。
2.2软件配置
编程算法可以划分为两个内容,一是写入编程命令序列,二是数据验证,本文只对前者进行研究。写入编程命令序列需要经过四个周期完成,前两个周期属于解锁周期,将AAh写入到55h中,再将55h写入到地址2AAh中,在第三个周期中,将A0h写入到0555h中,在第四周期中对地址与数据进行编程,Flash将自动完成编程命令。在第一周期中,使用的Flash数据线为AAh,也就是与Flash相连接的PowerPC405EP中的AAh,这时PerData0位为“0”。从PowerPC405EP的描述中能够看出,与之相对应的BSC单元号为24,部分源程序为:#definepinTDI1//输出端口位地址UnsignedcharOutport_State=0xF5//保存并口输出端口状态的全局变量writePort(pinTMS,0x00);sclk;//进入Run-Test-Idle状态;writePort(pinTMS,0x01);sclk();//进入Select-IR-Scan状态;writePort(pinTMS,0x00);sclk();//进入Shift-IR状态;writePort(pinTMS,0x01);sclk();//开始数据串行输入,将“0”输入到24号BSC中;writePort(pinTMS,0x01);sclk();//进入Update-DR状态,在TCK的下降沿,对24号BSC中的“0”进行驱动,使其传输到PerData当中,同时//flash也为“0”。
3新型的Flash编程模式分析
在实际应用过程中,由于Flash芯片在很多场景中均可使用,因此,命令集往往不尽相同,对此通常将整个编程模式划分为四个部分:最下层为硬件适配层,能够为上层提供读与写等基本功能,能够有效解决软件程序与硬件总线协调问题。第二层属于Flash适配层,主要作用是为上层提供Flash支持命令集,并通过公共接口发出响应。该层能够良好解决与Flash相关功能的指令时序与支持作用问题,且还应实现对各类事件与模式的转移。第三层为功能适配层,具有数据或指令读写作用,能够对Flash命令集进行封装操作,还可与上层之间相互联系。最上层便是适配层,与用户端相互连接,为用户提供高级交互接口。此种分层方式能够为编程操作提供极大便利,通过多层结构使高层与底层应用相互隔离,极大提高了程序开发质量,也为用户带来了更多功能与丰富的体验[3]。
4结语
本研究对Flash编程方式进行分析,借助嵌入式系统对Flash进行编程,编程速度较快、操作简单、复用率良好,充分符合嵌入式系统的发展趋势,同时也使系统开发投入成本降低,系统价值得到显著提高。另外,本文还介绍了一种新型的Flash编程方式,希望能够使其在系统开发中获得更广阔的发展空间。
参考文献
[1]高辉辉.基于PC-MBI模块的Flash编程技术研究[J].单片机与嵌入式系统应用,,15(9):7-10.
[2]吴延军.基于FLASH芯片的加密存储技术研究[D].广州:暨南大学,.
嵌入编程 篇3
关键词 嵌入式SQL 预编译程序 动态连接库
中图分类号:TP312 文献标识码:A
0 引言
在通常的运用中,SQL语言是作为独立语言在终端交互方式下使用的,是非过程性的,其大多数语句都是独立执行,与上下文无关,称作自含式语言;而许多事务处理应用都是过程性的,需要根据不同的条件来执行不同的任务,如果把SQL语言嵌入到诸如C语言这样的过程化的编程语言中,程序开发人员就能设计出更加灵活的应用系统,具有SQL语言和高级编程语言的良好特征,它将比单独使用SQL或C语言具有更强的功能和灵活性,这种方式下使用的SQL语言称为嵌入式SQL语言。
在计算机专业课程《数据库系统概论》中有关于嵌入式SQL语言的内容,其教学手段一般都是理论讲述,教学效果不是十分理想。下面介绍一种在现有条件下都能办到的嵌入式SQL语言实现方法。
1 在VC中使用嵌入式SQL语言访问Microsoft SQL Server 2000
1.1 使用嵌入式SQL语言所采用的系统配置
①操作系统:Windows 2000 Professional
②Microsoft Visual C++ 6.0
③Microsoft SQL Server 2000
在安装Microsoft SQL Server 2000 时要注意选择安装Development Tools,为使用嵌入式SQL语言准备必要的头文件和库文件。
1.2 编辑嵌入式SQL程序
使用文本编辑器如记事本编辑嵌入式SQL程序,其存盘文件的扩展名为"sqc"。在嵌入式SQL程序中嵌入的SQL语句以EXEC SQL作为起始标识,语句的结束以";"作为标识。在嵌入的SQL语句中可以使用C语言的程序变量(即主变量),这时主变量名前加冒号(:)作为标志,以区别于字段名。主变量的声明必须包含在"EXEC SQL BEGIN DECLARE SECTION; "和"EXEC SQL END DECLARE SECTION; "之间。以下是一个嵌入式SQL程序demo.sqc:
#include
void main()
{
EXEC SQL BEGIN DECLARE SECTION;
char first_name[50];
char last_name[] = "White";
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO my_server.pubs
USER my_login.my_password;
EXEC SQL SELECT au_fname INTO :first_name
FROM authors WHERE au_lname = :last_name;
EXEC SQL DISCONNECT ALL;
printf("first_name: %s\n", first_name);
}
此C语言程序中嵌入了SQL语句,用来访问数据库服务器my_server中的数据库pubs,登录名my_login,口令my_password,在表authors中检索姓"White"的作者的名,并存入主变量first_name,然后通过printf函数输出结果。
1.3 预编译嵌入式SQL程序
Microsoft SQL Server 2000提供的预编译程序nsqlprep.exe,用于对嵌入式SQL程序进行预编译处理,生成C语言源程序。实际上就是将嵌入式SQL程序中的嵌入式SQL语句替换为对运行时库文件Sqlakw32.dll的函数调用,接着运行时库文件调用动态连接库Ntwdblib.dll通过网络来存取Microsoft SQL Server 2000数据库服务器。
预编译程序nsqlprep的常用语法为:
nsqlprep ESQL_File /SQLACCESS /DB server_name.database_name /PASS login.password
其中ESQL_File是要预编译的嵌入式SQL程序;/SQLACCESS通知nsqlprep 自动地为嵌入式SQL程序中的静态SQL语句创建相应的存储过程;/DB server_name.database_name指明要连接的服务器以及数据库名称;/PASS login.password给出登录名及相应的口令。对于demo.sqc的预编译命令为:
nsqlprep demo /SQLACCESS /DB my_server.pubs /PASS my_login.my_password
经预编译处理后即可产生C语言源程序demo.c
1.4 配置VC++ 6.0 中的Project Settings
为了编译、连接nsqlprep生成的C语言源程序,需要增加必要的访问路径到VC++ 6.0 的环境设置中:
①选择菜单Tools中的菜单项Options
②选择Directories标签页
③在"Show directories for"下拉框中选择"Include files",增加Microsoft SQL Server 2000 开发所需头文件的路径:C:\Program Files\Microsoft SQL Server\80\Tools\DevTools\Include
④在"Show directories for"下拉框中选择"Library files",增加Microsoft SQL Server 2000 开发所需库文件的路径:C:\Program Files\Microsoft SQL Server\80\Tools\DevTools\LIB
1.5 生成访问Microsoft SQL Server 2000数据库的可执行程序
在VC++ 6.0 中创建一个"WIN32 Console Application"类型的Project,选择菜单Project中菜单项Add to Project的子项Files,将第三步中生成的C语言源程序demo.c添加到此Project中,然后编译、连接即可生成访问Microsoft SQL Server 2000数据库的可执行程序:demo.exe,运行的输出结果为:Johnson;这与使用交互式查询工具Query Analyzer检索的结果是一致的。至此,一个在VC++ 6.0中使用嵌入式SQL语言访问Microsoft SQL Server 2000数据库的应用已经开发完成。
2 结束语
本文探讨了Microsoft SQL Server 2000中的ESQL/C编程,并介绍了在常用编程软件VC++ 6.0 中嵌入式SQL程序设计的实现方法。在嵌入式SQL语言的课堂教学中,使用该方法,获得了良好的教学效果。
嵌入编程 篇4
1 嵌入式SQL的处理过程
对于含有嵌入式SQL的主语言程序,一般是先经RDBMS的预编译程序对其进行扫描处理,生成不含SQL语句的主语言源程序,此主语言源程序再经编译程序生成目标代码程序,最后与相关的函数库、运行库等连接生成可执行程序。其关键之处:一是RDBMS的预编译程序及其使用,二是编译链接时需要的与SQL有关的链接库等文件。
2 Ms SQL Server 2000的预编译程序及其使用
下面以生成Windows95/98/NT及以上版本下的ES-QL/C应用程序为例,介绍ESQL/C应用程序的预编译、编译、链接处理。
2.1 预编译所需的处理程序
基于Windows95/98/NT及以上环境下的ESQL/C预编译程序是nsqlprep.exe,常用语法格式[2]是:
命令参数及选项说明:
ESQL/C程序文件名:为要预编译的ESQL/C程序文件名;/SQLACCESS:为程序中的静态SQL语句自动生成存储过程;/NOSQLACCESS:不为程序中的静态SQL语句生成存储过程;/DB[server_name.]database_name:指定为存取规划在其中放置存储过程的服务器和数据库名称;/PASS login[.password]:指定用于访问SQL Server和存储过程生成所用的用户标识和密码,用了/DB选项就必须同时使用/PASS选项;$INTEGRATED:对login[.password]参数强制使用Windows身份认证支持。
2.2 运行Nsqlprep.exe对ESQL/C源程序预编译的过程
对ESQL/C源程序预编译要经下面三步:
(1)将sqlakw32.dll动态链接库文件复制到windowssystem32或windowssystem文件夹下或Nsqlprep.exe所在的文件夹下。
(2)设置环境变量INCLUDE以包含Sqlca.h和Sqlda.h头文件所处的全部路径,设置环境变量LIB以包含相应库文件所在的全部路径。假定SQL Server 2000的安装路径为“C:Program FilesMicrosoft SQL Server”(如果SQL Server数据库服务器实例采用的是典型安装,可能找不到上述文件,这时需要自定义安装),则可通过在命令提示符下执行如下命令完成路径设置:
(3)ESQL/C源程序的预编译。在命令提示符下执行如下命令对ESQL/C源程序文件(本文中为myexample.sqc)进行预编译:
Nsqlprep myexample
上述命令执行完后,生成的c源程序是myexample.c。
3 程序的编译、链接与运行
在链接目标程序时,需要的库文件为:Caw32.lib和Sqlakw32.lib。在运行上面生成的应用程序时,要用到由Ms SQL server 2000提供的动态链接库文件Sqlakw32.dll,Ntwdblib.dll和Dbnmpntw.dll,将其放到应用程序所在文件夹下,或windowssystem32文件夹下。
4 程序实例
下面以在VC++6.0环境下编译生成WIN32控制台应用程序为例,以WindowsXP和Ms SQL Server2000为运行环境,说明生成应用程序的步骤。
4.1 ESQL程序代码
下面的ESQL/C程序的功能是按用户帐号:lulu,密码:lulu,登录到本地SQL Server服务器上的bookjy数据库,先将dzhmc表中szdw属性非空的记录读出并显示,然后通过键盘输入向表dzhmc中插入一条记录,待用户按任意键后退出程序。
4.2 程序的编译、链接
(1)按上面2.2中的步骤预编译myexample.sqc,产生myexample.c文件
(2)VC++6.0环境下新建立一个空的WIN32控制台应用程序项目example1。
(3)通过Project/Add to project/Files菜单命令将上面预编译生成的C源程序文件myexample.c添加到项目中。
(4)向VC环境添加SQL Server提供的支持ESQL/C头文件路径
通过tools/options菜单打开“options”对话框,单击“directories”选项卡,在“Show directories”下拉列表框中选择“Include files”,用鼠标双击“Directories”列表框底部的划线矩形区域,输入如上面“2.2”中所述的头文件所在路径。
(5)通过Project/Add to project/Files菜单命令将SQL Server提供的Caw32.lib和Sqlakw32.lib两个库文件添加到项目中。
(6)按F7键编译、链接生成应用程序文件example1.exe。运行此程序前,要为数据库bookjy创建用户,名为:lulu,密码为:lulu。
4.3 在VC++6.0环境下编写ESQL/C源程序的注意事项
(1)ESQL/C预编译程序不支持C++模块的预编译。
(2)ESQL/C不支持使用预编译头文件。
(3)若程序中含#include windows.h语句,则此语句前要加上下面两行语句:
(4)ESQL/C源程序文件的扩展名为.sqc。
(5)不要用#include显式地将头文件Sqlca.h和Sqlda.h包含到ESQL/C源程序中。
(6)ESQL程序中SQL关键字null必须用小写以避免与C关键字NULL冲突。同样,嵌入式SQL关键字delete和in也应小写。
(7)ESQL中指示变量的类型要说明为short int类型,否则会得到错误结果。
5 结束语
本文通过查阅Ms SQL SERVER2000联机文档资料和上机试验,找出了以Ms SQL SERVER 2000为RDBMS的嵌入式编程的实现方法,并结合实例介绍了在vc++6.0下ESQL/C应用程序实现的详细步骤。目前流行的大型RDBMS产品很多。以ESQL编程访问不同RDBMS平台下的数据库时,所用的预编译程序和支持库文件会各不相同,而这些文件一般是由相应RDBMS产品提供的。
参考文献
嵌入式多轴运动控制器编程系统设计 篇5
关键词:多轴运动控制器,机器人语言,示教编程
0 引言
工业机器人技术是一种融合了机械电子技术,计算机技术,自动化控制理论等多领域的新兴学科。系统的稳定、高效和精确是决定性能的关键。最早的机器人采用了多不具备扩展功能的封闭设计,随着工业技术的发展,具有控制系统构架可被生产厂商以外的任何人更改的的开放控制系统开始成为热门研究方向[1,2,3,4]。这种系统通常是PC加上DSP运动控制卡。
采用传统方式的优点是使用通用控制卡,具有极强的可扩展性,但控制卡的成本较高,配套搭载PC平台也有成本和灵活性的问题。因此,本文提出了一种基于嵌入式的控制器编程系统,以达到小型化和低成本化的目的。
与其他控制系统相比,本系统基于am3517构建Linux系统平台,具有很好的稳定性和开放性,采用QT/Embedded设计可触摸交互界面,能够实现离线和在线编程处理以及浮点数计算,嵌入式的引入使得上位机体积急剧减小,灵活方便,同时缩短开发周期,控制成本。
1 嵌入式控制器编程系统总体设计
控制器工作原理是以ARM作为上位机,编译用户代码,控制DSP通信进行插补计算,通过FPGA输出点击控制信号驱动机械臂运动。
ARM上位机系统由一个触摸屏LCD执行显示和输入操作,最小系统运行linux操作环境,同时具有和多种通信端口,通过一个串口可与计算机进行连接,另一个串口与DSP进行通信。包括以下总体功能。
显示从ARM的内存或USB存储器中已编辑好的程序,或者利用虚拟键盘在触摸屏上在线编写新程序,对文件进行存储修改,使用lex和yacc工具对程序进行编译,转换成特定的中间执行代码,供DSP解读执行,DSP对中间执行代码进行解释、执行。
通过串口将编译好的代码传送给DSP,对DSP的运行进行管理,控制程序执行与停止,监控机器人端点位置。
触摸屏示教功能包括端点的3个轴方向移动,以及多轴机械臂的单轴运动,监控显示端点运动状况,并可记录运行中的特定点的位姿,以实现特定点组成的路径运动。
根据功能要求,系统选用了TI公司的基于Cortex-A8构架的AM3517芯片,主频高达500 MHz,片内包含独立的SDRAM控制器,外部增加了2个128 MB DDR2芯片,满足大型系统需求和程序存储需求,同时片外还有一个128 MB的Nand Flash,作为内核以及文件系统的存储介质。ARM模块需要五种不同的电压,包括内核电压、外设电压、锁相环供电电压等,系统采用TI的集成电源模块TPS65023以满足am3517的供电要求。
系统有3个输入部分,第一个部分是计算机的接口,由串口和网口负责,作为调试控制台。第二个部分为可触摸LCD屏幕,QT控制界面作为操作控制台,在此操作界面上进行按键操作和虚拟键盘输入操作。第三个部分是USB和SD卡槽,可在存储介质中读取需要的程序等等。系统的输出部分为LCD屏幕内容和与DSP通信的UART接口。当数字逻辑电路有1/3以上的频率达到或超过50 MHz时,我们称之为高速电路,与一般电路相比谐波频率更高,干扰更明显[5],因此,系统采用了“控制盒+转接板”的构架,ARM系统部分单独制作8层小板以减小干扰,其中包括2个电源层和2个地层,此外的部分采用四层板的设计,彼此之间的数据交互通过插件来完成。系统结构功能图,如图1所示。
2 编程系统软件设计
本系统使用的linux内核版本是2.6.32.2,使用的交叉编译器是arm-linux-gcc。系统软件设计主要包括界面内容设计,机器人语言设计,编译设计。
界面内容设计包括编辑界面,运行界面和示教界面,是人机交互的实现界面。操作语言设计指定了合法的编程语法词法,可实现的命令种类和相应的功能。编译设计则是通过Lex和Yacc工具实现对程序的检查和转换,使之成为DSP解读的中间执行代码。
2.1 交互界面
人机交互界面设计采用的工具是QT/Embedded,QT可以利用C++语言开发框架,能够完美运行在多种系统平台上。与此同时,QT为嵌入式开发提供了一套较为完善的窗口系统[6]。根据功能需求划分,交互界面分为三个部分。
(1)编辑界面
在此界面上可以对程序进行一些基础操作,比如打开、新建、保存、关闭等等。在系统中设计了一个虚拟键盘来替代实体键盘,用于输入程序或对已有程序进行修改。虚拟键盘包括“0-9”数字、“a-z”字母、大小切换键、特殊符号、空格键、换行键、退格键、以及关闭虚拟键盘按键等。虚拟键盘仿照实体键盘的样式,便于操作者进行编辑处理。保存完程序之后可以点击按钮,使用自己设计的编译工具对程序进行分析编译,生成特定语言格式的文件。图2显示了编辑界面功能概貌。
(2)运行监控界面
选择编译之后生成的文件,将其下载到DSP中,通过按键控制程序在DSP中的运行,停止,监控当前机械臂端点的运行状态,包括坐标,姿态以及速度。所有的命令都将翻译成特定的机器码,通过串口传送给DSP,同时采用定时查询的方式,从串口中获取DSP传递回来的位姿数据,用于显示数字及图像以便监控当前的运行状态。
(3)示教界面
通过滑轮或者上下箭头选择示教时的运行速度,通过串口传送给DSP。示教包括针对端点的操作和针对不过关节的操作。端点操作包括3个轴的位移,关节操作包括6个关节的正负角度移动。根据按键按下时间的长短及时响应机械臂的运动。同时显示当前端点的位姿,并可在显示界面记录下一系列特定点位姿,以实现根据点列运动的路径规划。
2.2 机器人语言构架
随着工业技术的发展,机器人的操作环境越来越复杂,需要的功能涉及运动学,动力学以及传感器等多多方面的操作,因此,开始出现了不同于普通语言的专业机器人语言。根据作业描述水平的高低,机器人语言通常分为三级,动作级、对象级和任务级[7]。本系统开发的机器人语言是一种动作级语言,参考的是Unimation公司的VAL语言。
按照不同的功能需求,将机器人的基本行动表达为对应的行动符号[8],本系统编程语言被分为五种类型:基本指令、程序执行流程、动作参数设定、运动控制和输入输出信号。设计的机器人语言分类及部分实例见表1所示。
基本指令包括定义变量、变量赋值、数学运算等等。变量类型为int、char、float三种类型变量。数字运算则是加减法、乘除法的运算,还有判断条件中的大小比较。
程序执行流程控制包括跳转、重复执行、子程序调用和开始结束语句,其中跳转还包括无条件跳转和条件跳转指令。
动作参数设定可以对机器人的运动进行配置和约束,包括限定最大速度、负载约束、加速度约束、运动范围约束、动作流程约束等等。在机器人开始执行运动语句之前,必须对相关运动参数进行配置,一方面可以规范运动过程,另一方面可以保护机器人处于安全运转状态。
运动控制即为任务运动指令,包括直线控制、圆弧控制、转轴控制、抓取控制等等,不仅是动作轨迹指令,通常还带有一些参数,有时还带有电流电压设置。
输入输出信号直接告诉底层设备部分I/O口的信号设置,多出来的I/O口可以作为拓展接口使用,与其他硬件通信等等,也可以用来指示或观察机器人目前的运行状态,或者执行特定任务。
2.3 编译程序
参考VAL语言设计的机器人语言可以让编程工作变得简单明了,带有关键字的语言设计可以方便编程人员和操作人员进行设计和检查。实际上,编译结束之后,通过串口传递给DSP和FPGA的程序数据是二进制。将机器人语言转换为二进制代码就是编译程序要做的工作。在这里,我们使用的工具是Linux环境下的Lex和Yacc。
Lex和Yacc是由贝尔实验室提出的一种编译程序设计语言,目的是为了将编写的语言类程序转换为结构化的输入[9]。
(1)指令格式
用于传输的中间执行代码设计的格式是指令+数据,第一条为指令代码,后续为数据代码,指令和数据都采用16位表示。指令代码格式如图3所示。
指令代码13~16位表示指令类型,根据拓展需要划分了10类,9~12位表示每种指令类型下的具体指令代码,低8位1~8位表示这个指令后续附带的数据的个数。如指令代码0x200d,2代表指令类型为动作型,0代表具体动作为直线运动,低八位0x0d表示后续有13条数据代码。浮点数的数据代码格式如图4所示。
第16位为代表符号位,S=1为负数,S=0则为正数,第12~15位是二进制表示数E,第1~11位M则是采用了小数二进制表示的尾数部分。
机器人末端空间设为2米边长的立方体,坐标范围为[-200,200]。在应用中,源程序中的坐标数值和速度数值需要转换为16位表达,在监控运行状态时,串口得到的16位数又需要通过运算转换为浮点数。数据代码与十进制浮点数转换的计算方法为:
得到的绝对值范围是0.0078~308.4288,单位是毫米,能够满足设计需求。
编译的过程就是把源文件内容机器人语言语句解析翻译成以上设计的目标文件对应格式内容,程序流程如图5所示。
(2)词法分析
编译开始时,从文件内读取字符串,将其分割成独立的单词。机器人语言中最小的语义单位是单词,单词既可以是保留关键字,比如if、then,也可以是运算符常数等。
词法分析器的功能就是识别出单词,并根据特定的关系转换成某种内部格式以供其他部分调用。使用lex工具可以利用正则表达式对单词进行匹配,通过在词法定义文件中用正则表达式来定义词法,并指定标识符的返回码,我们就能实现可供调用的查找标识符的接口函数,返回码就能告诉语法分析器这个标识符的类型。Lex程序通常由定义段、规则段、用户子程序段这3部分组成[10]。
词法分析器读取程序字符,逐个匹配拼出单词,构造相应的内部token,同时检查词法错误。
(3)语法分析器
经过词法分析之后,源程序被拆分成单词符号,即返回码。语法分析器根据单词串以及预先设定的语法规则,分析源程序的语法结构,并解析语法错误。Yacc使用的方法是自顶向上的方法。Yacc语法分析器包含3个部分:声明段、语法规则段以及用户例程段[7]。
机器人语法分析器设计方法参考了Tiny编译器[11]。在此基础上还添加了空间位姿定义以及其他任务操作指令,还设定了自定义的目标代码格式。本系统设计的巴克斯范式(BNF)文法如下:
利用以上规则,Yacc按照移进-规约原理分析得到的标记,将源程序分为一棵一棵的语法树和子树。语法树的根节点为语句类型(statement),子树为语句类型或者是表达类型(expression)。举例来说,直线运动指令movl a,b 50(起点为a,终点为b,匀速速度为50的直线运动)这条指令语法树见图6所示。
(4)语义分析
通过遍历语法树,根据语法树中节点的不同类型,语法分析可以确定对应的编程语言语句以及其对应的语法意义。读取各个节点的类型,将其转换为对应的二进制编码。比如处理movl类型的语句时,语义分析出类型之后会产生相应的控制机器人直线运动的控制指令代码,调用目标代码生成模块生成相应的目标语句,先生成直线运动指令,再生成19个数据。语义分析程序主要调用了目标代码生成函数emit I_MD和emit Data子函数,与目标代码生成程序共同完成了从解析语义树到生成对应目标代码的工作。
2.4 逆运动学求解
机器人语言和编译系统的设计根据是机械臂模型对点进行逆运动学求解,由末端位置的空间坐标和姿态求取各个轴的扭角。本系统的研究对象为ABB公司生产的六自由度串联闭环机器人,后三轴汇聚于一点,所以我们使用D-H模型,将机械臂按照前后三轴划分,分别计算关节变量θ1-θ6。
假设后三轴相交于一点Oc(xc,yc,zc,),各连杆长度为ai,各连杆距离di,利用余弦定理可得到前三个轴的关节角度[12]:
求得前三轴的关节角度之后,根据姿态转移变换矩阵可以求得后三轴的关节角度[11]。由此可以实现机器人的逆运动求解,编程中的变量和编译要求都是基于此原理规划运动过程。
3 实验与测试
编程系统基于Linux系统的稳定性和安全性,利用Qt4开发友好用户界面,实现了代码编辑检验功能。本系统提供机器人程序文件选择、编辑、编译、出错信息处理、运行监控、示教等功能,使用户能更方便地操作,更直观地了解流程。
编辑界面中的虚拟键盘如图2所示,实际测试虚拟键盘能代替实体键盘完成编辑工作。编译程序链接于Compile按键上。当程序出现定义或者格式错误的时候,编译不通过将在编译信息窗口显示错误信息,包括错误所在的行数和错误类型,方便操作者修改。
为检验系统功能,设计了一条直线与一条圆弧组成的封闭图形路线,实验测试程序如下:
编译得到的目标文件如图7所示。
编译系统将机器人语言编写的程序语句解释成中间执行代码格式,通过串口将内容发送给DSP,DSP对其进行解读,和FP-GA利用运动学原理进行反解,控制电机运动。
实际测试中用am3517平台输入以上指令,编译得到中间码传送给下位机,TMS320F28335对其进行逆运动学求解和插补,测试中取最大进给速度位5 mm/s,插补周期5 ms。插补得到的路径如图8所示。
实际结果测量显示,末端轨迹偏差在0.1 mm以内,精度满足要求,同时圆弧插补需要17 429个时钟周期,最长需要的插补时间是116 us,直线插补所需代码比圆弧插补少,实际所需时间是105 us,两者都少于0.2 ms,速度远高于一般的PC和运动控制卡的方法。浮点计算使得插补运算能够有很高的精度,同时am3517、FPGA和DPS的应用,不仅减小了体积节约了缓存容量,更是满足系统整体实时性和高效性,应用效果良好。
4 结语
针对传统工业机器人控制器的成本和灵活性问题,本文提出了一种由嵌入式系统构成的机械臂控制编程系统。该系统可以实现机械臂控制程序的编辑编译工作,实时监控运行情况,以及末端点和各个轴的示教功能。自行设计的机器人语言简单易懂,使得操作人员能够快速掌握编程语言,直观有效管理机械臂的运行,提高效率。嵌入式am3517平台移植结果和仿真结果表明,该方法可以显现较好的路径规划,高速有效,具有灵活性,可移植性,开放性和稳定性,同时满足了小型化和经济性的需求,具有较高的实用价值。
参考文献
[1]徐小明,魏泽峰,胡立明,等.基于PC与运动控制器的开放式数控系统研究与开发[J].制造业自动化,2012,2(2):107-110.
[2]IFR.Executive Summary of World Robotics 2012 Industrial robot[R].World Robotics 2012,Statistical Department in International Federation of Robotics,2012.
[3]田茂胜,唐小琦,孟国军,等.基于嵌入式PC的工业机器人开放式控制系统交互控制的实现[J].计算机应用,2010,30(11):3087-3090.
[4]William E Ford.What is an Open Architecture Robot Controller?[J].Intelligent Control,1994:27-32.
[5]邹国平,崔翔,魏兴昌,等.高速电路电源/底层间阻抗参数计算与分析[J].电波科学学报,2011,4(2):394-399.
[6]彭均键,史步海,刘洋.基于Qt的嵌入式GUI开发平台的搭建[J].微型电脑应用,2010,26(2):40-42.
[7]韩建海.工业机器人[M].武汉:华中科技大学出版社,2006.
[8]靳国强,陈小平.面向智能服务机器人任务规划的行动语言扩展[J].软件学报,2013,24(7):1614-1625.
[9]刘丽娜,杨纯辉,张静.Lex和Yacc解释程序实现方法[J].微处理器,2013,2(1):38-40.
[10]黄鹏,王立平,关立文,等.基于Lex和Yacc的开放式并联机床后置处理系统开发[J].高技术通讯,2011,21(3):303-308.
[11]Kenneth C Louden.编译原理及实践[M].冯博琴,冯岚,译.北京:机械工业出版社,2000:97-100.
嵌入编程 篇6
对于利用LCD进行显示的系统,往往都存在交互的部分,尤其是一些智能系统。交互的主要硬件设备有键盘交互、显示驱动部分和系统控制器等几部分组成[1]。本文就对这几部分的软件设计上提出一些自己的想法。
1.1 系统控制器的软件运行环境建立
系统控制器,目前主要有51内核的单片机、ARM7、ARM9、DSP等处理器。软件运行环境的建立,对不同的处理器、不同的开发环境将有所不同。但主要内容包括:系统启动代码的编写、堆栈的分配、系统硬件环境的建立、中断系统的设置等内容。
1.2 显示驱动器
在嵌入式系统应用中,如果微控制器本身带有液晶驱动控制功能则可以直接连接控制点阵式液晶显示屏,如果微控制器本身没有液晶驱动控制功能则需要外扩液晶驱动板来连接液晶显示屏,或者使用点阵式图形液晶显示模块[3]。液晶显示模块简称LCM,是指将液晶显示器件,连接件,控制与驱动等外围电路,P C B电路板,背光源,结构件等装配在一起的组件。它提供用户一个标准的LCD显示驱动接口,用户只要将其与微控制器连接,即可进行图形的显示输出控制,使用上比较简单。对于显示部分在代码设计上先作如下说明:
(1)分层实现,即将显示部分的驱动分为硬件驱动层和应用接口层。硬件驱动层主要完成对显示屏的硬件操作(如:配置硬件驱动的接口、关闭显示、打开显示等);应用接口层主要是对显示部分的应用层提供接口,使显示部分的逻辑控制应用与硬件层的操作隔离,该部分应该实现基本的显示操作(如画点、画线、画域、提供写字母、汉字、图片的功能)。
(2)建立显示的字库,LCD在实际应用过程中可能需要大量的字库,不同大小的字体,这样字库对存储器的占用空间将会很大。具体字符的显示在编程时的技巧,见字库的编程技巧。
(3)确定界面中显示的变量的相关属性,变量的属性,在不同的显示系统中,所需的属性有所不同,后面将对变量的属性定义举例说明。
1.3 键盘部分
键盘是由若干个按键组成的开关矩阵,是实现简单的人-机通信部分,在软件设计上需作消抖处理。键盘的电路结构各有不同,有矩阵键盘、有CPU通过总线连接键盘管理器件对键盘电路进行管理或使用处理器的端口直接读取按键状态等常用的方式。对于不同的键盘结构,按键所产生的键值也有所不同,要保证键盘的操作不受键值变化的影响,按键值最好设置为预先定义的宏,具体详见后面的编程操作。
2 字库的编程技巧
在嵌入式系统中一般要使用的汉字数量是有限的,并不需要提供完整的汉字库,如一个消毒柜的LCD上没有必要显示"信息发送"的功能;但是一部手机、小灵通包含的信息量比较多,通常需要提供完整的汉字库[4]。
对于包括完整汉字库的系统而言,如以16*16点阵字库为例,可以依据汉字在汉字库中的具体位置计算公式(94*(区号-1)+(位号-1))*32计算出汉字字模在库中的位置。但是如果仅仅是提供少量汉字呢?具体操作如下所述:
3 显示变量的属性定义
对于带有LCD显示的系统,大多都存在变量的显示处理,对于显示变量的属性采用结构体定义比较直观且容易操作。结构体的成员包括:指向显示变量的指针、显示变量的显示宽度、显示变量的数据类型等。这些属性根据变量实际的交互方式和显示情况而不同,属性的成员也可根据具体情况增减。
变量属性的结构体定义:
通常情况下,显示界面中的显示变量不同,需要定义不同的s_Variable结构体数组,这样,每个显示页面均需建立参数属性的数组。因此当页面很多,显示变量数也很多时,变量属性定义的数组变量将占较大的内存空间,但这样可以使编程更加方便,同时可以具有较大的灵活性,方便了页面中变量的个数显示、位置调整和交互式的操作代码的编写,为后期的界面编程提供方便。
4 页面的操作编程方法
通常情况下,页面的显示包括如下的内容:
1)页面中不需实时刷新的固定字符显示,如界面中的固定字符图片等;
2)页面中的显示变量的数值显示;
3)根据系统的运行状态实时更新的数据;
4)人机交互时产生的显示,如光标的移动等。
对于上述的页面显示项,在实际应用中,每个页面中的显示各有不同,交互处理、按键功能等都有不同,因此,需要寻找一种合适的方法完成这种处理。在下面的内容中将针对这样的情况,阐述一种解决方法。
在面向对象的程序设计中,出现了“类”的概念。类是对特定数据的特定操作的集合体。类包含了两个范畴数据和操作。而C语言中的struct仅仅是数据的集合,我们可以利用函数指针将struct模拟为一个包含数据和操作的"类"。下面的C程序模拟了一个最简单的"类"
我们可以利用C语言模拟出面向对象的三个特性封装、继承和多态,但是更多的时候,我们只需将数据与行为封装以解决软件结构混乱的问题。C模拟面向对象的设计思想不在于模拟行为本身,而在于解决某些情况下使用C语言编程时程序整体框架结构分散、数据和函数脱节的问题,尤其在复杂的界面交互时,若继续使用C语言的过程处理方法去解决显示与交互的问题那么系统的编程将非常复杂,同时使界面编程中的灵活性和可维护性大大降低[2]。
通过如上论述,对于嵌入式的显示界面可以作为一个抽象类,在C语言中,对界面类的属性和操作定义为
有了上述页面操作的结构体后,根据页面的多少建立s_Page;类型的结构体数组,对不同页面分别定义属性和操作。在实际的交互中切换页面时,只要改变当前页面结构体中成员(属性成员和操作成员)的对应值即可,这样就可在不同的页面中实现不同的操作。对于前述的主页显示的变量数组,主页面的定义如下:
编程人员需要根据系统的显示需求,根据页面的多少,对不同页面建立如上的变量初始化,至于交互方面,用户只要实现页面的背景绘制程序(即绘制页面中的固定不变部分的显示)、显示刷新程序的处理以及不同按键按下时的操作,这样即可完成页面的交互与实时刷新工作。
5 结束语
LCD在嵌入式产品中的使用日益增加,对LCD的编程要求也越来也高。屏幕编程若处理不适当,将是软件中最不系统、最混乱的部分。采用C语言实现面向对象的思想和方法,将使软件的结构清晰,编程变得简单大大提高了系统的可扩展性和维护性。应用结果表明这种开发方法是很实用的,可以优化程序结构、缩短开发周期,实现快速开发又不降低程序的效率。
参考文献
[1]周立功.ARM嵌入式系统基础教程[M].北京:北京航空航天大学出版社,2005.
[2]刘维富等.C语言程序设计一体化案例教程[M].北京:清华大学出版社,2009.
[3]李维提等.液晶显示应用技术[M].北京:电子工业出版社,2006.
嵌入编程 篇7
在Linux中的网络编程是通过socket套接字接口来进行的,这一抽象的引入是为了方便联网应用程序的编程,在UNIX的BSD版本第一次使用了这种接口,因此他也叫做BSD套接字。应用程序可以使用这种统一接口收发网络上的数据,网络的socket数据传输是一种特殊的I/O口,socket也是一种文件描述符。套接字的设计符合Linux的习惯,在理想情况下,应将所有可读写访问的对象映射成文件,这样就可以用普通的文件读写操作来处理这些对象了,使通信中的收发可以很容易映射成读写操作。在传输协议的上下文中,由这类读写操作的对象就是通信关系的两端,他们表示成了套接字。
BSD套接字是一个通用接口,它支持不同的网络结构,同时也是一个内部进程间通信机制。当一个主机上同时有多个应用程序在运行,他们使用tcp和udp协议进行通信,则传输层协议收到数据后将根据端口和套接口区分数据是传给哪个应用程序。端口是标识传输层与应用程序的数据接口,每个端口有一个16位的标识符。套接口是IP地址与端口号的组合,用来标识全网范围内的唯一一个端口,在tep和udP协议中用来标识一个连接,网络应用程序之间通过套接口来实现通信。套接字是套接口描述字的简称,是整型数字,它与文件描述符共用一段数值空间O_65535。应用程序中使用套接字来调用套接口,套接字可认为是指向套接口的指针,就像文件描述符是指向文件的指针一样。一个套接字描述了一个链接的一个端口,一个socket端点可以用socket地址来描述,socket地址结构由正地址,端口和使用协议组成(TCPorUDP),因此两个互联的进程都要有一个描述他们之间连结的套接字。我们也可以把套接字看作为是一种特殊的管道,只是这种管道对于包含的数据量没有限制。套接字存在于特定的通信域(即地址族)中,只有隶属于同一地址族的套接字才能建立对话。Linux支持的协议族有AF_INET(IPv4协议)、AF_INET6(IPv6协议)和AF_UNIX(Unix域协议)。
Linux支持多种套接字类型,每种套接字类型对应于创建套接字的应用程序所希望的通信服务类型。同一协议簇可能提供多种服务类型,比如TCP/IP协议族提供的虚电路和数据报就是两种不同的通信服务类型。TCP/IP中常用的socket类型共有三种,一种是流式socket(SOCK_STREAM),另一种是数据报式socket(SOCK_DGRAM),还有一种是原始socket(SOCK_RAW)。流式socket是一种面向连结的socket,对应于面向连接的TCP服务应用。数据报式socket是一种无连接的socket,对应于无连接的UDP服务。原始套接字接口容许对较低层协议如IP、ICMP直接访问,常用于检验新的协议实现或访问现有服务中的新设备。
2 网络编程基本模式
2.1 客户机/服务器模式
网络编程的基本模式是Client/Serve:模式,该模式的建立基于以下两点:
1)非对等作用;2)通信完全是异步的客户机/服务器模式在操作过程中采取的是主动请示方式,首先服务器方要先启动,并根据请示提供相应服务。Server端首先调用socket创建一个一定类型socket,然后通过bind函数将这个socket绑定到一个client知道的端口上,接着server调用Listen函数设置倾听队列的长度,为了接收来自client端的请求做准备,然后server调用accept,开始在所绑定的端口倾听来自client端的连接请求。如果socket被设置成阻塞方式,accept调用将被阻塞,进程被挂起,直到server收到来自client的请求后,accept才返回。Client端通过socket调用创建一个一定类型的socket(应当和server的socket类型相同)。然后调用connect函数向server所在的主机发出连接请求,连接时,需要指定server所在主机的IP地址和server倾听的端口号,连接的报文包含了client端的初始的序号SYN a和MSS=1460信息(最大数据段的大小)。正在倾听来自client的连接请求的server收到client的连接请求后,server从accept调用中返回(通常socket是阻塞方式工作的)。server将会向client端发送server端的初始序号SYN b和对client端的SYN a的确认ACK=a+l,还有本端的最大数据MSS当client端接收到server端的回应时,将发出对server请求的ACK=b+1。然后client从connect中返回,返回值是一个打开的socket的描述符,这个描述符和文件的描述符类似,程序可以像使用文件的描述符一样使用它。稍后,在server端收到client端对其请求的回应时,server将从accept调用返回,返回值也是一个socket的描述符。
2.2 面向连接协议的字节流套接字编程
字节流socket采用的是传输控制协议TCP。TCP提供面向连接的流传输,面向连接对可靠性的保证首先是它在进行数据传输前,必须在信源端和信宿端建立连接。在面向链接传输的每一个报文都需要接收端确认,未确认的报文被认为是出错报文。字节流套接字的服务器进程和客户进程在通信前必须先建立连接,建立连接和通信的步骤如下:
1)服务进程首先调用Socket()创建一个字节流套接字,并调用bind()将服务器地址捆扎在该套接字上,接着调用listen()监听连接请求,随后调用accept()做好与客户进程建立连接的准备,无连接请求时,服务进程被阻塞;
2)客户进程调用Socket()创建字节流套接字,然后调用connect()向服务进程发出连接请求;
3)当连接请求到来后,服务进程被唤醒,生成一个新的字节流套接字,并用新套接字同客户进程的套接字建立连接,而服务进程最早生成的套接字则继续用于监听网络上的服务请求;
4)服务进程和客户进程通过调用read()和write()交换数据;
5)服务进程和客户进程通过调用close()撤消套接字并中断连接;当选择SOCK STREAM(字节流)类型的时,sock()系统调用中的参数protocol(协议)总会选中TCP,而UDP则一直用作SOCK DGRAM类型的传输协议。
2.3 非连接协议的数据报套接字编程
数据报式socket采用的是用户数据报协议UDP,它是建立在IP协议之上的,提供无连接数据报传输,主要应用在高可靠性、低延迟的局域网上,它的优点是高效率低开销,不用建立连接和撤销连接,缺点是不可靠,报文丢失后需重发。数据套接字的服务进程客户进程通信前不必建立连接,UDP则一直用作SOCKpGRAM类型的传输协议,通信的步骤如下:
1)服务进程首先调用Socket()创建一个数据套接字,并调用bind将服务器地址捆扎在该套接字上,然后调用recvfrom()等待客户进程发来的请求;
2)客户进程在调用SocketQ创建一个数据报套接字后,调用bindU将客户机地址捆扎在此套接字上,接着调用sendto()向服务进程发送请求,然后调用recvfrom()等待服务进程返回该请求的处理结果;
3)服务进程在执行客户进程所请求的任务后,调用sendto()将处理结果返回给客户进程;
4)服务进程和客户进程通过调用close()撤消套接字;
3 Linux内核对socket的支持
确切地说,Linux内核只提供了一个与套接字有关的系统调用,应用程序的所有套接字调用都会映射到这个系统调用上。在Linux内核中的net/socket.c中定义这个函数sys_socketcall(int call,unsigned long*args)。include/asm/unistd.h中会指派一个数字,该数字会和arch/i386/kernel/entry.s中的系统调用一起添加到表格中。通过调用中。all参数可以说明所指向的那个套接字函数,在include/linux/net.h中定义了可接受的参数SYS_SOCKET,SYS_IND,SYS_CONNECT,SYS_LISTEN等,在用户空间的函数库中,带有特定参数的sys_socketcall调用会映射成某个独立函数,在内核中若要选中希望调用的那个函数,需要在sys_socketcall函数中用到一条:witch命令如下所示,而在此之前首先要使用copy_from_user()命令将sys_socketcall()的函数复制到一个向量中,即ensign long a中。
与早期的内核相比,socket结构己经稍有简化。state中存储的是套接字状态可以取值如下(include/linux/net.h):SS_FREE(不忙)、SSes UNCONNECTED(未连通)、SS_ONNECTING(目前正在连接)、SS_ONNECTED(已连通)、SS_ISCONNECTING(目前正在断开连接)。flags用以同步访问,ops指针指向了连通协议(如tcp或udp)在初始化之后的协议运作。就像Linux中的每个文件都有一个mode一样,每个BSD套接字也分派了一个mode o file中存储了一个指向该文件结构的指针,这个结构连接了套接字,因此它可以用与指向套接字。如果有进程等待着这个套接字上的事件,也可以通过fasync_list找出该进程。通过sk指针可以使用一个匹配的sock结构。不过,这个sock结构是由BSD套接字之下、特定于协议的套接字初始化的,并且连通到这个指针。字段负责根据用户空间中的同名套接字调用存储第二个参数,在Linux内核include/asm/socket.h中定义了可接受的参数。
从上面分析可以看出任何时候通过一个socket来读写数据时,都是在使用一个系统调用(system_call)这个调用(例如read或write)跨越了用户空间应用程序与内核的边界。另外,在进入内核之前,您的调用会通过C库来进入内核中的一个通用函数system_call()。从system_call()中,这个调用会进入文件系统层,内核会在这儿确定正在处理的是哪种类型的设备。最后,调用会进入socket层,数据就是在这里进行读取或进行排队从而通过socket进行传输的。
4 总结
每种网络协议都提供网络应用开发接口,TCP/IP协议的应用开发接口的事实标准是socket套接口,开发socket的目的是隐藏网络底层的复杂结构和协议,使编程人员能够简单抽象的对网络进行操作。socket面向客户机/服务器模型,针对客户机/服务器程序提供不同的socket的系统调用函数,客户端随机申请一个socket,操作系统为之分配一个随机socket号;服务器端拥有全局公认的socket号,任何客户都可以向他发送连接请求和信息请求。进程通信以前,双方必须各自创建一个端口,否则是没有办法在通信前建立联系的,而socket提供了这种进程间通信的端口。从网络编程的套接字的分析来看,选择TCP套接字和选择UDP套接字编程,在传输数据时有着速度、效率和稳定性的差别。TCP编程拥有了可靠的数据连接,UDP不具有。但是在速度方面,UDP编程确优于TCP编程,特别是对于传输短消息。基于这两种通信方式优缺点的考虑,在后续编写IDU控制应用软件时,将UDP套接字用于硬件终端对外广播本地IP地址,使局域网内客户端软件识别某台终端设备,获取其MAC地址等硬件信息。将TCP套接字用于在客户端传输用户数据,对硬件终端上的硬件设备进行初始化设置。
参考文献
[1]Warren W Gay.Linux Socket Programming by Example.Que(R),April2000.
[2]Jonathan Corbet,Alessandro Rubini,Greg Kroah-Hartman.Linux Device Drivers3rd Edition.Reilly Media Inc,2005.
[3]孙琼,嵌入式Linux应用程序开发详解[M],北京:人民邮电出版社,2006.
[4]张斌,高波等,Linux网络编程[M],北京:清华大学出版社,2000.
嵌入编程 篇8
关键词:安全相关,软件故障,控制措施,算法
0引言
随着技术和材料工艺的发展,目前,越来越多的安全系统使用了嵌入式可编程电子装置,如MCU、PLC等等。他们减小了安全系统的物理尺寸,极大地提高了安全保护的主动性、可靠性和效率。与此同时,由于集成电路的复杂性,特别是软件的不可视特性,由他们带来的安全隐患的排查变得非常困难,特别是对高复杂性系统,如轨道信号系统、石化控制系统、核反应堆安全系统,这些安全隐患的爆发将是致命的。因此对于安全相关系统的软件的故障进行控制就是非常必要的[1]。
随着标准IEC-61508的普及,功能安全与软件故障防护的理念越来越被人重视。本文根据IEC-60335附录R中针对微控制器需测试的部件及要分析的故障,进一步描述了CPU、可变和不可变存储器、中断、时钟及I/O接口等测试技术的应用和实现[2]。
1 E / E / PE系统电路结构及故障
影响系统安全 的因素包 括硬件故 障和软件 偏差两方面[3,4,5,6]。硬件可靠性可通过现有的安全标准对产品进行结构检查和非正常试验来检测; 软件安全则需要安全相关软件具备故障/偏差控制措施,这是标准IEC-60335中的一项安全要求。如图1所示。
由于避免错误的措施通常在产品或设备的设计过程就已经基本考虑,因此,笔者开发E/E/PE安全相关系统软件故障防护的措施着重于控制故障 /错误的措施的研究,而这个方面也是现在功能安全领域研究的重点和难点。
2常见控制故障 / 错误的措施
基于IEC-60335的安全相关系统的软件防护措施及各种算法已经成为研究热点[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23]。表1列出了MCU控制系统常见的故障( 详见IEC - 61508附录R) 。
在此基础上按照表1的顺序,本文介绍了B类软件部份故障/差错控制措施的算法,这些措施适用于当有周期自检的单信道,以最广泛的8位机举例。
1组件: 中央处理单元1. 1寄存器
■故障: 滞位( stuck-at) 在“0”或“1”
■措施: H. 2. 16. 5功能检测/ H. 2. 19. 6. 1方格贮存器检测
■算法: 对于8位寄存器,顺序写、读、检查0x55和0x AA
■说明:
检测时应禁止中断;
破坏性检测,为了避免寄存器中的数据被破坏,应将数据先存入堆栈;
应先检查最先使用的寄存器,如堆栈指针寄存器→通用寄存器→状态寄存器,无论哪个寄存器存在故障,都会返回错误标志;
C语言不能直接读取寄存器,寄存器检测需要用汇编语言;
应在main函数展开之前进行寄存器检测,即利用头档预处理;
H. 2. 19. 8. 2带有一位冗余的字保护,此措施需要额外的硬件监测CPU,也需要额外的内存保存每个存储单元的奇偶数。
2组件: 1. 3程序计数器PC
■故障: 滞位( stuck-at) 在“0”或“1”
■措施: H. 2. 18. 10. 2程序顺序的逻辑监测
■算法: ROM中一般存放有多个函数,设定每个函数的特征值,如该函数的首地址,将这个数据存放在ROM的指定地址中;当PC启动这个函数时,读取特征值并与存放在ROM中的特征值比较。
■说明:
■检测时应禁止中断;
■PC检测依赖于MCU的结构和应用,有许多方法;
■看门狗只能处理PC滞位在一个不变的值时发生溢出; 如果是一位发生滞位,PC仍然可能计数,看门狗可能不发生溢出置位,因此看门狗必须与其它实时应用功能( 如实时中断) 联用。
3组件: 2. 中断处理与执行
■故障: 无中断或太频繁中断
■措施: H. 2. 18. 10. 4时隙监测
■算法: 在指定的时间间隔内,检查发生的中断。对于中断过多,在中断服务程序( ISR) 中使用一个计数器存放一个数字,每发生一个中断,计数器减1,如果中断过多,计数器将置0; 对于中断过少,在中断服务程序( ISR) 中使用一个计数器存放中断数目,每发生一个中断,计数器减1,如果中断过少,计数器将达不到某个数值。
■说明:
■需要事先计算中断数量的误差范围;
■如果没有使用中断,需要一个专用的函数来检测中断服务程序是否正常;
■中断检测依赖于MCU的结构和应用,可以用多种方法。
4组件: 3. 时钟
■故障: 错误频率
■措施: H. 2. 18. 10. 1频率监测
■算法: 双时钟比较,需要一个独立时钟做参考,与CPU的主频时钟比较。在独立时钟的一个或几个周期内,记录主频时钟周期数。
■说明:
■除了由晶振构成的时钟外,还可以用RC电路构成一个参考时钟;
■时钟检测依赖于MCU的结构和应用,有许多方法;
■需要设置误差范围;
■50 /60 Hz供电线频率可以用作参考时钟。
5组件: 4. 内存4. 1不可变内存
■故障: 所有一位故障
■措施: H. 2. 19. 3. 1周期修改的检查和
■算法: 故障涵盖率应高于99. 6% 。对不可变内存的存储数据逐位求和,使用循环冗余检查CRC计算标识字( 余数) ,与存放在ROM指定位置的标识字比较。
■说明:
检测时应禁止中断;
CRC的和是所检查的内存数据值和,需要列出地址表;
CRC除数( divisor) 的宽度决定了探测错误的能力,从8位到32位,通用的除数CRC-8 = 0x D5,CRC-16 = 0x8005,CRC-16-CCITT = 0x1021,CRC-32 = 0x04C11DB7
CRC的余数( remainder) 可以存放在ROM的最后区域。在CRC计算和时,不包括存放余数和其它专用数的地址,如果计算出来的余数与ROM中保存的参考数不一致,说明ROM存在故障。
6组件: 4. 2可变内存
■故障: DC故障
■措施: H. 2. 19. 6. 2进程贮存器检测
■算法: 可以选用March C/B/X[2]等算法中的一种,例如March B的算法:
{ Down( w0) ; /* 从最后一位到第一位,每位写“0”;
Up( r0,w1,r1,w0,r0,w1 ) ; / * 从第一位到最后一位,读“0”,写“1”,读“1”,写“0”,读“0”,写“1”,然后到下一位;
Up( r1,w0,w1) ; / * 从第一位到最后一位,读“1”,写“0”,写“1”,然后到下一位;
Down( r1,w0,w1,w0) ; / * 从最后一位到第一位,读“1”,写“0”,写“1”,写“0”,然后到下一位;
Down( r0,w1,w0 ) } / * 从最后一位到第一位,读“0”,写“1”,写“0”,然后到下一位。
■说明:
检测时应禁止中断;
启动时应检测完寄存器后就检测RAM;
破坏性检测。在周期检测时,为避免数据被破坏,可以分区检测,将数据暂存于一个分区,检测完后再写后来;
对于大容量RAM,分区检测能够提高效率。
如果RAM不能分区,可选用C类措施H. 2. 19. 7走块式贮存器测试检测,顺序写、读、检查0x55和0x AA,耗时但节约RAM空间。
7组件: 4. 3寻址( 与可变和不可变内存相关) 5. 内部数据路径5. 2寻址
故障: 滞位
■措施: H. 2. 19. 8. 2带有一位冗余的字保护
■算法: 在发送端,产生一位奇偶数; 在接收端,用同样的算法,产生一位奇偶数,与接收到的比较。
■说明:
需要在发送端和接收端具有计算奇偶数的硬件;
需要一位地址线用于传输奇偶数;
对于单芯片结构,内部存储器,4. 1和4. 2的检测涵盖了此项检测。
8组件: 6外部通信
■故障: 汉明距离3
■措施: H. 2. 18. 2. 2传输冗余
■算法: 传输冗余最经济,通过两次或多次数据传输,将数据进行比较。
模拟量需要设置数据误差;
H. 2. 19. 4. 1CR-单字可用检测数字传输,单字的产生需要传输端和接收端硬件支持
检测依赖于实际应用,根据情况选择不同的方式。
9组件: 6. 3计时
■故障: 错误的时间指针或错误顺序
■措施: H. 2. 18. 10. 4时隙监测
■算法: 利用实时时钟,如CPU时钟,记录外部输入数据的数目,如电磁灶的PWM信号,与存储的预期值比较。
■说明:
需要设置数据误差;
检测依赖于实际应用,根据情况选择不同的方式。
10组件: 7. 输入 / 输出外围7. 2模拟I / O 7. 2. 1 A / D和DA转换器
■故障: GB4706. 1 19. 11. 2条规定的故障条件
■措施: H. 2. 18. 13似真检查
■算法: 利用参考电平,检测A/D转换数据是否在预期范围内; 利用脉冲信号,如PWM,检测D/A模拟量是否在预期范围内。
■说明:
参考电平应能涵盖使用范围,如0 ~ 5 V,
需要对应的硬件支持;
需要设置边界条件,如误差;
检测依赖于实际应用,根据情况选择不同的方式。
11组件: 7. 2. 2仿真多重通道
■故障: 错误寻址
■措施: H. 2. 18. 13似真检查
■算法: 需要在每一道施加不同的电压,检测multiplexer是否正常; 或者使用同一个输入信号,如温度传感器信号,选择每一道进行测量,将数据进行平行比较。
■说明:
需要对应的硬件支持;
需要设置边界条件,如误差;
检测依赖于实际应用,根据情况选择不同的方式。
以不可变内存的措施算法为例,周期性利用CRC算法产生一个检查数,比对检测。Rom起始地址: E000h,结束地址FFFEh。除数: 1021,余数: 7BD6,地址: FFFFh。程序运行时间需: 9056个时钟周期( 8 MHz)
故障处理Power_offpanbie( ) : 27个时钟周期( 8 MHz) 。当余数不为7BD6时,调用关机程序来保护系统:
调用关机程序后系统停止工作,进入周期性自检,可以相对保证系统的安全。
3软件检测顺序
CPU寄存器、程序计数器、可变内存和不可变内存应在工作前进行系统检测POST( Pre-Operation System Test) ,所有组件需要进行周期检测,即嵌入自检BIST( Built-In Self-Test ) 。一个基本的例子,没有外部内存、外部通信及定制集成片,检测顺序如下:
堆栈指针寄存器→通用寄存器→ 状态寄存器→程序计数器→ 可变寄存器→不可变寄存器→ 时钟频率→中断功能→ 模拟多道开关→A/D、D/A转换器
同时需要注意的是,进行寄存器、内存检测时,必须先屏蔽中断功能,避免中断影响检测结果。
4实例
为了更加详细的展示上述控制故障 /错误的措施,现以GIC-CS28B电磁灶举例说明。
4. 1风险分析
系统有如下工作特征:
1) 当电压升高或降低时,功率能稳定在一定的范围内,当超压、欠压时,系统停止加热,并显示故障代码。
2) 热敏电阻如果存在开路、短路或者失效,系统停止加热,并显示故障代码。
3) 锅底温度超过安全值( 如烧油) ,系统停止加热,并显示故障代码。
4. 2安全功能解决方案
程序上电进行初始化,进入主程序中轮番调用各个功能子程序。
流程如下: 上电后,程序首先检查寄存器、RAM单元、ROM单元、时钟等,以保证CPU运行是正确的,然后检查电压、电流和热敏电阻各个参数数值,当以上任何一出现故障或不正常,系统就进入关机程序,不会加热,以保障安全。
掉电后,系统检测到进行低电压复位处理。程序运行中始终对RAM,ROM,PC等CPU内部系统以及电压电流,温度进行循环检测,一旦错误,系统进入关机状态。看门狗实时监测以保证程序的正常运行。
系统依靠电流、电压、温度等参数,以确保系统能安全稳定运行,而为了保证AD采样的精确度,程序采取了以下措施来降低风险:
1) 定时中断方式采样,以固定的间隔( 2毫秒) 周期进行采样。以保证得到的数据及时刷新。
2) 多次采样,累加后求取平均值作为目标值,以保证采样的稳定和真实性。程序中以2毫秒为间隔,连续采集50次,然后求得平均值作为参考值。
3) 为保证单片机运行,开启了看门狗实时监控。以便在程序被干扰的情况下及时复位。
主流程图如图2所示。
4. 3控制原理
本系统中采用的单片机为意法半导体公司生产的ST7系列单片机,型号: ST72F324K2B6。采用外部 晶振源,晶振频率4 MHz,经过内部PLL锁相环倍频后,CPU运行在8MHz频率下。所用到的综合开发环境为: ST7 Visual Develop。版本: Version: 3. 4. 0,此开发环境整合了编辑、编译、连接、DEBUG功能。
4. 4安全相关程序
4. 4. 1软件描述
本软件用C语言编写,使用的综合开发环境ST7 Visual Develop Version: 3. 4. 0整合了编辑、编译、连接、DEBUG功能。
软件采用主程序中按序周期调用子程序方式,各种功能在子程序中实现。程序运行后,在主程序函数main( ) 中循环调用各个功能子程序。
4. 4. 2相关安全措施子程序描叙
1) reg_chk( ) : 寄存器检查。功能描叙: 检查单片机内部寄存器,内部寄存器是,A、X、Y、CC、PC、SP。子程序中对A、X、Y分别写入0xaa/0x55,并读出后再与0xaa/0x55做比较,若有错误,进入关机程序。程序运行需183个时钟周期。
针对CC状态寄存器,运行3个算数运算:
1 0x08 + 0xf8运算结果影响半进位标志H = 1,借位 /进位标志C = 1,零标志Z = 1,符号位标志N = 0;
2 0x07 + 0x01运算结果影响半进位标志H = 0,借位 /进位标志C = 0,零标志Z = 0,符号位标志N = 0;
3 0x01 - 0x02运算结果主要影响符号位标志N = 1。
分别在三个运算结束时,对影响的每个位进行0 /1测试,若有错误,进入关机程序。
针对堆栈指针SP的检测方法是: 把数据0xaa,0x55,0xa5,0x5a分4次压入堆栈,然后在每次出堆栈时检测数据是否相同。若数据正确,意味着栈指标SP正确,否则栈指标SP错误则进入关机程序。
2) pc_chk( ) : 程序计数器检查。功能描述: 检查单片机程序计数器PC。此程序中,引入了10段子程序,占用了10段不同的程序空间,且每段子程序返回一个固定的值( 分别是1,2,3,…,10) 检查返回的值是否正确。若返回值正确,表示程序计数器PC正确,否则,进入关机程序。程序运行需267个时钟周期。
3) ram_chk( ) : RAM记忆体检查。功能描叙: 检查单片机内部RAM内存。RAM起始地址0080h结束地址00ffh。程序对待测RAM单元分别写入0xaa/0x55,并读出后与0xaa/0x55做比较,若相同,表示单元正确,否则进入关机程序。程序运行需21 632个时钟周期。
4) rom_chk( ) : ROM记忆体检查。功能描述: 检查单片机内部ROM内存。程序对单片的内部ROM空间( E000h-FFFEh)做CRC算法处理得到一检查数( 0x7BD6,地址FFFFh) ,对比此检查数与存储的数值,若相同表示ROM正确,否则进入关机程序。程序运行需9056个时钟周期。
5) clock_chk( ) : 时钟检查。功能描述: 检查单片机时钟频率。程序通过在固定的时间( 200 ms) 内读取工频( 50 Hz) 脉冲数,作为比较,若脉冲个数在7 ~ 13范围内,则认为时钟是正确的,此范围误差为: + / - 30% 。程序运行需48个时钟周期。
6) port_io_chk( ) : 输出I / O口检查。功能描述: 检查单片机关键输出口的逻辑正确性。程序针对关键输出控制口PC3( Denable) 在非加热状态下进行电平测试。非加热状态下,此口应该是电平0,若非0,则程序关闭加热板的电源后进入关机程序,以保障系统的安全。程序运行需36个时钟周期。
7) ad_chk( ) : AD转换器检查。功能描述: 在AD 13信道上输入一固定电压( 2. 5 V,最大采样电压为5 V) ,程序周期的对此电压进行采样,并比较采样值,若此值在120 ~ 134范围内,则认为AD转换器正确。误差范围: + / - 2. 7% 。程序运行需46个时钟周期。
8) ad_process( ) : 电流、电压、功率数据的处理子程序。功能描述: 程序周期性对采样的电压、电流、温度AD值进行比较,若超出规定范围,则设立一错误标志,主程序中检测到错误标志给予关闭加热或关机处理。电压范围: 180 ~ 260 V。电流下限( ad值) ≥90,温度值( ad值) ≤224。程序运行需1689个时钟周期。
9) temp_judge( ) : 热敏电阻故障及温度判别。功能描叙:程序周期的对热敏电阻的AD值进行采样比较,若AD值超过规定的范围则设置温度错误标志,主程序中检测到此错误标志,给予停止加热或关机处理,以保障系统安全。AD值范围:
1热敏电阻短路: ad≤5
2热敏电阻开路: ad≥240
3温度超标: ad≥224
程序运行需83个时钟周期。
10) power_offpanbie( ) : 故障类型辨别程序。功能描述: 程序对上述子程序ad_process( ) 及temp_judge( ) 所产生的故障标志进行检测,针对不同的标志,给予停止加热或停机的处理。程序运行需27个时钟周期。
上述具体程序省略。
5测试
由第三方认证机构测试,当试验对不同组件设置故障后,主程序中检测到错误标志,程序运行到故障组件检测段立刻停止加热并停机,同时程序段显示故障段,能立刻确定故障组件。充分保障功能安全的正确实施。
6结语
嵌入编程 篇9
可编程逻辑控制器(PLC)以其高可靠性和使用方便的特性,使其在现代工业控制中得到了广泛的应用。随着工厂自动化的进展,对PLC之间以及PLC同其他控制设备之间相互联系的要求也相应提高。由于PLC的通讯方式为串行通讯,受通讯方式的制约,传统的PLC(即外挂式PLC)难以胜任微机和PLC都必须参与实时控制和控制功能较为复杂的系统。当输入/输出点数多时,PLC体积会随点数的增多而增大,安装不太方便。此外,目前国内因没有自己的品牌,在应用PLC的场合仍多选用国外产品,品牌多,成本高,因此研制符合实际应用需求的国产化新型PLC系统及其通用开发平台具有重要意义和应用前景[1]。
为了提高速度,降低成本,可采用虚拟式PLC,即把PLC上的CPU和存储器等部件由微机的软件虚拟实现,再配合普通的开关量I/O卡实现对电气开关的控制。但此方案因主机要直接参与控制逻辑的运算过程,占用了主机的部分工作时间,会导致整机速度下降。另外,把过多的功能集中到主机使主机发生故障的风险加大[2]。因此,本文给出一种嵌入式PLC的设计方案,它可以看作是一种智能型I/O接口卡,在不增大系统体积的同时,使通讯速度大幅度提升,故障风险相对分散。
1 嵌入式PLC的硬件结构设计
嵌入式PLC是利用PC机开放式、模块化和可嵌入的特点,以及成熟的硬件及丰富的软件资源,尤其是开放式的PC总线而设计的。本项目总的设计思想是:设计一个嵌入式PLC卡,它可以插到主机底板的插槽上,因该卡直接与主机底板总线相连,通讯速度可以大大提高。卡上自带CPU,用以处理开关信号,开关逻辑处理不占用PC主机的时间,其输出经外接继电器以控制开关设备的开启与关闭、导通或截止。其软/硬件的分配是合理的,能有效解决PLC与主机通信和协调工作的问题,较好地满足控制系统实时性的要求。
嵌入式PLC是一个完全独立于PC机的完整的计算机系统,其硬件组成如图1所示,主要由单片机最小系统、程序存储模块、通讯模块及输入输出模块组成。嵌入式PLC的CPU采用了ATMEL公司推出的AT89S51单片机,该单片机是低功耗的、具有4KB在线可编程FLASH存储器。图1中双口存储器(双口RAM)用于完成PC主机与嵌入式PLC之间信息的交换,与采用并行口的方案相比,该方法简洁明了,无需复杂的通讯协议,PC主机可以随时了解外部设备开关状态而不需额外消耗时间,效率高于其它实现方式。目前,工控机的底板总线有两类:ISA总线和PCI总线。ISA总线的数据转输速率比PCI总线要低得多,但已完全能够满足一般工业控制的需要,而且ISA总线对工控机扩展卡的要求比PCI要宽松。从已有的工业应用经验看,ISA总线可靠性也比较高,因此仍选择ISA总线做为嵌入式PLC设计的基础。此外,图1中包括一片静态RAM芯片6264,主要用于存储PLC梯形图程序。在工控PC主机中对电气控制逻辑进行编程,编译后经双口RAM存入6264中,PLC运行这部分程序以完成电气控制。
1.1 通讯模块的设计
PC主机与嵌入式PLC卡之间可以采用并行口进行数据传输。这种通讯方式实现起来比较简单,成本低廉,一般又能满足大多数场合对速度的要求,目前己得到广泛的应用。另外,为了保证可靠地进行数据传输,通常在硬件设计上还要考虑握手信号。通讯双方进行应答的过程中,速度较快的一方将受另一方的制约。在通讯量比较大的情况下,这种交互过程将浪费相当多的CPU时间。因此在信息量比较大的场合,运用并行口进行通讯就受到限制。此外,还可以采用共用存储器的方法进行信息传输,它可以达到更高的传输速度。传统的共用存储器硬件设计比普通的并行口复杂得多,应用范围较小。最近几年出现的双口RAM芯片内含总线仲裁电路,提供两套相互独立的控制、地址和数据总线,可以大大简化共用存储器电路设计,使其应用日益增多。因此,在此采用双口RAM进行数据传输。嵌入式PLC卡通讯部分的设计如图2所示。
在图2中,IDT7132为IDT公司生产的双端口RAM芯片,容量2K字节,它有两套完全相同的地址、数据和控制总线,内部含有总线仲裁电路,允许两侧总线同时对它进行读写操作。当两侧同时对该芯片的同一单元进行读写时,内部仲裁电路会根据两侧读写控制信号微小的时间差,判决一侧正常读写,同时在另一侧给出BUSY信号(低有效),表示不能正常完成读写,它可用作等待信号来扩展读写周期,以保证正确读写。
图2中AT-BUS为PC机底板总线,也可称作ISA总线。虽然在通用PC行业,ISA有被其它更高速率的总线如PCI等替代的趋势,但高速率的总线同时也提高了对外围扩展线路板的要求,使可靠性有所降低,而且ISA总线己能满足绝大多数工控系统对传输速率的要求,因此在工控领域仍占据重要地位。
AT总线的地址信号A0-A10与IDT7132直接相连,A 1 1-A 1 9及A E N信号经通用可编程芯片GAL16V8,产生IDT7132的片选信号。这种做法可以简化译码电路的设计,且可以很方便地修改IDT7132的地址选择,以免与工控机中己有的扩展板发生冲突。一般地,PC系列机存储器空间的0A0000H-0EFFFFH区域为I/O扩展卡保留,且某些标准I/O设备如显示适配器己经占用了其中的一部分空间,因此本卡上IDT7132在工控PC机中占用存储器空间应提供多种选择。例如,欲使IDT7132占用的地址空间为0D800:1000-0D800:17FF,只需将GAL按以下逻辑编程:
1.2 输入/输出(I/O)模块的设计
嵌入式可编程控制器是一种工业控制计算机,控制对象是工业生产设备或工业生产过程,工作于工业生产现场,它与工业生产过程的联系就是通过输入输出(I/O)模块实现的。I/O接口模块的任务是将被控对象或被控生产过程的各种变量进行采集送入单片机处理,同时控制器又通过I/O模块将运算处理产生的输出信息送到被控设备或生产现场,驱动各种执行机构动作,实现实时控制。
在通常的PC工业控制中,需要用到多路输入,单片机上可用的I/O端口数量有限而且宝贵。在此系统中,根据设计要求的输入、输出点数,进行I/O端口的扩展。本次设计中所选用的I/O扩展芯片是8255A。由于输出模块另选了其他元件,不需要在8255A上另辟输出端口,因此8255A的3个端口全部都用作输入。出于对可靠性及抗干扰两方面的考虑,开关量输入信号经滤波及光电耦合器隔离后送入8255,然后由驱动器74LS245读入单片机。设计中采用的输出元件是德州仪器(TI)公司生产的逻辑功率器件TPIC6B273ND,该器件是一种单片、高电压、中等电流的功率逻辑8位D型锁存器,其将锁存器和驱动器做在单一芯片里,满足了输出模块的要求,先将信号锁存,而后在输出刷新时驱动负载,并且能提供150mA的连续电流驱动较大范围的负载。开关量输出信号经TPIC6B273ND锁存及功率放大后送至继电器板,由继电器控制外部开关设备的通断。经过这样的设计使得输出模块结构大大简化,一改传统模块体积大,电路连线复杂等缺陷。
2 嵌入式PLC的软件设计
软件设计有两部分内容,一个是工控PC机中相关程序设计(即上位机程序的设计或梯形图集成开发环境的设计),另一个是PLC卡自身所带程序设计(下位机程序的设计)。前者主要功能如图3所示,一般基于Visual C++或Borland C++平台进行开发。
在图3中,梯形图编程模块为用户提供方便的PLC电气控制逻辑编程手段,其结果生成梯形图文件。梯形图文件仅存储I/O点之间的逻辑关系,其格式与嵌入式PLC所用CPU类型无关,以提高编程模块的适应性及可重用性。梯形图编译模块则用于把该文件转化为一系列的8051机器指令,并加上一些必要的附加指令,产生二进制(BIN)指令码文件。此部分应当考虑到PLC中I/O点的资源分布情况,使最后生成的BIN文件的指令与实际I/O资源协调一致。通讯模块用于把BIN文件传输到双口RAM中,再由PLC卡自身所带的程序(下位程序)把它转储到静态存储器(6264)中。监控模块提供用户对I/O点监视与设置、PLC卡运行状态/编程状态设置等功能,方便用户现场调试。另外,为了使用户能够在自主开发的应用程序中对PLC卡进行有效的监控,此部分提供开放的用户接口。
嵌入式PLC卡自身所带程序(下位程序)主要实现以下功能:6264中逻辑处理程序(即由工控机传来的BIN文件)及运行状态的有效性检验,I/O点及双口RAM映射区域的周期性刷新,运行故障监测等。只有当6264中已存有有效的BIN文件,且已设置好有效的运行标志时,才能运行6264中的逻辑处理程序。另外在运行期间,运用看门狗(Watch Dog)对运行是否正常加以监视,防止并处理诸如运行6264中的程序时发生的超时错,6264中的逻辑处理程序出错等异常情况。
3 结论
本文设计的嵌入式可编程控制器系统采用了插卡式结构,利用总线技术及双端口RAM与工控PC机进行信息交换,速度快,可靠性高,实时性有保证。其可嵌入到工控PC机系统中,便于与用户的软硬件组合成更复杂的系统。此外,目前国内有关嵌入式PLC系统的研发不是很多,本文的研究工作对推动PLC控制系统国产化具有重要意义。
参考文献
[1]王善永,陈思宁,施冲,等.MB系列智能可编程逻辑控制器[J].电力系统自动化,2005,29(10):82-84.
[2]赵建东,王广炎,等.可编程控制器实现方式的研究与应用[J].组合机床与自动化加工技,2002(12):49-51.
[3]赵建东,王广炎,等.智能化嵌入式可编程控制器集成系统的研制[J].制造技术与机床,2002(12):41-44.
[4]吴宁,葛芬.可编程逻辑控制器通用开发平台的设计与实现[J].仪器仪表学报,2007,28(8):1486-1491.
[5]徐惠民,安德宁,丁玉珍.单片微型计算机原理、接口及应用[M].北京:北京邮电大学出版社,2007.