2024年5月10日发(作者:)
基于Windows CE6.0的运动控制器指令衔接的实现
宋帅;李翔龙;龚波
【摘 要】采用Windows CE6.0作为运动控制器软件平台,以VDX-6353作为硬件平
台,开发了流驱动程序,采用定时中断方式实现运动指令之间的衔接.文章阐述了中断服务程
序的开发流程和详细步骤,开发出的驱动程序可有效地实现运动指令的衔接.
【期刊名称】《轻工机械》
【年(卷),期】2013(031)005
【总页数】5页(P51-54,58)
【关键词】运动控制卡;插补;指令衔接;看门狗;定时中断
【作 者】宋帅;李翔龙;龚波
【作者单位】四川大学,制造科学与工程学院,四川成都610065;四川大学,制造科学与
工程学院,四川成都610065;四川大学,制造科学与工程学院,四川成都610065
【正文语种】中 文
【中图分类】TP316.7
1 问题提出
在运动控制器完成某点的运动轨迹时往往不能严格地按照既定的曲线运动,只能用折
线轨迹逼近既定曲线,即所谓的插补(插补方式有:直线插补、圆弧插补、抛物线插补和样
条线插补等)[1]。所谓直线插补就是用逼近的方式把曲线用一段段线段去逼近,从而每
一段线段就可以用直线插补了(这样实际轮廓就由一段段的折线拼接而成,虽然是折线,
但是由于每一段线段都非常小,那么此段折线和实际轮廓还是可以近似地看成相同的曲线
的)。因此在用直线插补方式完成某个运动轨迹时,所实现的代码往往是由若干条直线运
动指令来完成的。这样便带来运动指令之间衔接的问题——后一条指令必须在前面一条指
令执行完成之后才可以执行,否则将导致运动轨迹混乱,无法完成既定的运动轨迹。因此
运动指令的衔接是运动控制器开发过程中必须要解决的问题。
2 解决方案分析
由于嵌入式系统的实时性与灵活性,使其在运动控制领域被越来越被广泛的应用。
WinCE操作系统是微软公司针对嵌入式系统领域推出的操作系统[2]。由于其支持基于
IRQ(物理中断请求)的中断处理机制,可以用中断触发IRQ绑定事件,而IRQ绑定事件进
一步触发中断服务程序,从而完成处理成衔接指令的功能。VDX-6353上具有两只看门狗,
可实现1~1 000μs定时[3]。看门狗本质上是一个定时器。定时器对时钟进行计数,
在程序或嵌入式系统中需要对看门狗定时器进行复位重新计数即所谓的喂狗。当定时器溢
出时,它就会产生复位或中断信号。工作原理如图1所示。
图1 看门狗的工作原理Figure 1 Operation principle of the watchdog
当看门狗中断产生时,会触发IRQ绑定事件,经由Windows CE6.0的中断机制转
向中断服务子程序的执行。在中断服务程序中去查询本条指令是否执行完毕,如果没有执
行完毕,则不做任何操作直接返回。直到查询到本条指令已经执行完毕,再去触发下一条
指令执行,依次类推直到代码执行完毕。采用这种方法不仅极大地释放了CPU资源,而
且简化了代码,提高了代码的运行效率。工作流程如图2所示。
图2 指令衔接工作流程Figure 2 Technological process of command connection
3 利用VDX-6353看门狗定时中断实现指令的衔接
3.1 VDX-6353内置看门狗概述
VDX-6353的处理器是台湾DM&P集团的DM&P Vortex86 DX。这款芯片以嵌入
式及工业应用为主要目标,采用X86兼容运算核心,运算速度可以达到800 MHz。
VDX-6353中内置两只看门狗,使用24位计数器,可以设置的时间范围是30.5μs至
512 s,它能够分辨的最小精度为30.5μs。其端口地址如图3所示[4]。
3.2 中断处理实现
3.2.1 安装 ISR
ISR的主要功能是把IRQ转换为一个逻辑终端号后(SYSINTR)返回。ISR返回的
SYSINTR会保存在在驱动注册表的某个键值中,当IST需要这个值时,直接从注册表中
读取就可以了。
示意代码如下:
图3 看门狗端口地址Figure 3 Port address table of watchdog
3.2.2 定义 IST 数据结构体[5]
在实现IST之前需要定义一个结构体来存放其处理过程中相关信息。
3.2.3 获取所设置的IRQ对应的逻辑中断号
从注册表中读取IRQ15对应的逻辑中断号。
//注册表中读取IRQ15对应的逻辑中断号
g_WdtIsTData.dwSysIntr=dwType //将其赋给dwSysIntr
3.2.4 创建一个事件对象用于关联IST
g_WdtIsTData. hEnent=CreateEvent(NULL,FLASE,_T(“Wdt Event”)); //创
建自动重置的事件对象。
if(g_WdtIsTData.hEnent==NULL)
{
DEBUG(ZONE_ERROR,(L(“创建事件失败rn”)));
Return FLASE;
}
3.2.5 断开此逻辑中断先前关联的一切事件
InterruptDisable(g_WdtIsTData.dwSysIntr);
3.2.6 创建IST线程
g_WdtIsTData.hThread=CreatThread(Null,o,WdtIST,& g_WdtIsTData,
CREATE_SUSPENDED,NULL);
if(g_WdtIsTData.hThread==NULL)
{
DEBUG(ZONE_ERROR,(L(“创建线程失败rn”)));
Return FLASE;
}
3.2.7 改变IST线程优先级
If(CeSetThreadPriority(g_WdtIsTData.hThread,151))
{
DEBUG(ZONE_ERROR,(L(“设置优先级失败rn”)))
}
3.2.8 启动IST线程
ResumeThread(g_WdtIsTData.hThread);
{
return TRUE;
}
3.2.9 实现IST线程
DWORD WINAPI WdtIST(LPVOID lParameter)
{
for(;;)
{
WaitForSingleObject(HEvent,INFINITE);
…… //在此线程中完成程序检测指令是否执完成,并触发下一条指令的功能
InterruptDone(g_WdtIsTData.dwSysIntr);
//结束中断线程
}
3.3 实现看门狗驱程序
为了方便地对看门狗的工作方式进行设置和更加灵活的使用它,需要实现看门狗驱动
程序[6]。WinCE下的驱动从实现方式上可以分为本地驱动和流式驱动。所谓本地驱动
也可以叫做专用驱动,是WinCE针对其本身使用的设备而设计的驱动程序,如网络接口
驱动程序、显示设备驱动程序及USB接口总线驱动程序等。而那些不是操作系统本身使
用的设备,就规定一个叫做流接口的标准形式,符合这个标准的接口的驱动程序叫做流接
口驱动程序[7]。流驱动适用于任何逻辑上认为是数据源或宿的I/O设备,也就是说任
何以接受或发送数据流为主要功能的外围设备,都可以用流驱动的形式来实现其驱动程序。
结合看门狗的硬件特点,适合用流驱动的形式来实现其驱动程序。
3.3.1 需要使用的CEDDK函数
在对看门狗进行设置时,需要对看门狗端口寄存器进行操作[8]。因为WinCE的
驱动程序是加载到内核的,所以不能直接使用in和out等指令对端口进行操作,而且在
WinCE驱动程序开发时尽量采用WinCE提供的资源,这样开发出的程序质量较高。因此
对端口进行操作时使用CEDDK提供的2个函数。
1)VOID WRITE_PORT_UCHAR(PUCHAR Port,UCHAR Value); //用于向指定端口
写入一个字符数据。
2)VOID READ_PORT_UCHAR(PUCHAR Port);
//用于从指定端口读取一个字符数据。
3.3.2 创建WinCE驱动子工程
看门狗的驱动程序是要加载到内核中的,因此看门狗的驱动子工程是以在WinCE镜
像工程中建立一个子工程的形式来实现的。在WinCE镜像中创建一个名称为
WDT_Driver动态链接库子工程,驱动程序的实现就在这个子工程中完成。
3.3.3 实现看门狗驱动程序的流接口函数
1)WDT_Init()。定义并初始化存放当前指定看门狗上下文的实例区域。
2)WDT_Deinit()。释放存放指定使用看门狗的上下文区域。
3)WDT_Open()。用于打开当前使用看门狗。示意代码如下。
VOID WRITE_PORT_UCHAR(0x37,0xhh);
//确保37h端口的第6位为1。
4)WDT_Close()。
VOID WRITE_PORT_UCHAR(0x37,0x00);
//确保37h端口的第6位为0。
5)WDT_Write()。
VOID WRITE_PORT_UCHAR(0x38,0xB0);
//设置看门狗触发IRQ15信号,确保38h端口的高四位为1011。
6)WDT_IOControl()。根据应用程序不同的操作码设置看门狗相应开关动作。
switch(dCode)
{
case IOCTL_WDT: //复位看门狗
break;
case IOCTL_WDT: //关闭看门狗
break;
case IOCTL_WDT: //使能看门狗
break;
case IOCTL_WDT: //触发相应的IRO中断IST事件
break;
case IOCTL_WDT: //触发NMI事件
break;
default
break;
}
3.3.4 修改.def文件
为了使动态链接库中导出的函数被其他代码用动态方法调用,要定义def文件。打开
WDT_Driver.def
EXPORTSWDT_Init
文件,在其中添加如下内容:LIBRARY WDT_Driver
WDT_Deinit WDT_Open WDT_Close WDT_Read WDT_Write WDT_IOControl
3.3.5 修改注册表
WinCE流式驱动的加载是通过搜索注册表中的指定项来实现的,因此想要成功的加
载驱动程序必须在注册表中注册驱动程序[9]。打开platform.reg文件,并在其中添
加如下内容:
[HKEY_LOCAL_MACHINEDriversBuiltInWDTO1]
“Dll”=“WDT_Driver.Dll”
“Prefix”=“WDT”
“Index”=dword:1
“Order”=dword:0
其中Dll为将要加载的动态链接库的名称,Prefix为源文件中实现的流接口函数的前
缀,两者必须一致,否则将导致驱动加载不成功。Index是组成设备名称的数字部分,这
个值可以根据需要进行设置。order是一个dword的类型值,提供支持顺序加载机制,
系统通过查找该值来先后加载驱动程序(值越小加载的越早)。
3.3.6 修改bib文件
为了使Dll加载到内核进程空间需要在platform.bib文件中添加如下内容:
WDT_Driver.dll $(_FLATRELEASEDIR)WDT_Driver.dll NK SHK
4 应用程序调用驱动程序设置看门狗
WinCE的流驱动程序被当成一个特定的文件设备,它提供的流接口函数通常跟文件
系统的API函数紧密联系。因此应用程序在设置看门狗工作方式时,是通过调用文件系统
API来实现的,对应流接口函数的文件系统API有如下几个:
1)m_hSdr=CreateFile(L"WDT1:",GENERIC_READ|GENERIC_WRITE ,0,NULL,
OPEN_EXISTING,0,0);该代码用来打开看门狗进行读写操作,得到文件操作的句柄名
m_hSdr。
2)ReadFile(m_hSdr,buffer,sizeof(buffer),&bytestRead,NULL);该代码用来
从指定端口读取数据,从而进一步判断看门狗的工作状态。
3)WriteFile(m_hSdr,buffer,sizeof(buffer),&bytesWrite,NULL);该代码用来
写看门狗端口,对看门狗的工作方式进行设置。
4)DeviceIoControl(m_hSdr,WDTO_INPUT_DIRECTION,&bufIn,
sizeof(BYTE),NULL,0,0,NULL);该代码调用文件API对设备发送操作命令。其中
m_hSdr用来指定端口;WDTO_INPUT_DIRECTION为发送数据的操作码,这必须与驱动
程序中有一致的定义,也就是让系统知道进行的是什么操作;&bufIn为发送的数据帧首地
址;sizeof(SendData)为发送数据的长度。
5 结语
文中介绍了Windows CE6.0系统流式驱动程序的开发流程,利用看门狗定时中断
方法解决运动指令衔接的问题[10]。其中中断频率的选择对运动控制系统的性能起着
关键作用,过低的中断频率会导致运动系统的实时性过低,从而延长代码执行时间。过高
的中断频率,则会导致查询过于频繁从而加重了CPU的负担。
参考文献:
[1]周建设.Window CE设备驱动及BSP开发指南[M].北京:中国电力出版社,
2009:1-102.
[2]徐成,秦云川,刘彦.Window CE内核定制与驱动程序开发[M].北京:中
国电力出版社,2011:192-225.
[3]汪兵.Windows CE嵌入式高级编程及其实例详解[M].北京:中国水利水电
出版社,2008.
[4]邱小平,李恬,雷群英.Windows CE 6开发经典[M].北京:电子工业出版
社,2009.
[5]倪旭翔,计春雷.ARM Cortex-A8嵌入式系统开发与实践WinCE与Android
平台[M].北京:中国水利水电出版社,2011:25-30.
[6]周建设.Windows CE项目开发实践丛书[M].北京:中国电力出版社,
2009:102-152.
[7]周毓林,宁杨,陆贵强,等.Windows CE Net内核定制及应用开发
[M].北京:电子工业出版社,2005:10-201.
[8]AXELSON J.嵌入式Ethernet和Internet通信设计技术[M].骆丽,张岳
强,欧小龙,译.北京:北京航空航天大学出版社,2006.
[9]洪家平,董武世.基于嵌入式系统的时分多址通信协议的实现[J].微计算机
信息,2005(7):32 -34.
[10]林凌,李刚,丁茹,等.新型单片机接口器件与技术[M].西安:西安电子
科技大学出版社,2005.
发布评论