Real.docx
- 文档编号:11770770
- 上传时间:2023-04-01
- 格式:DOCX
- 页数:57
- 大小:1.33MB
Real.docx
《Real.docx》由会员分享,可在线阅读,更多相关《Real.docx(57页珍藏版)》请在冰豆网上搜索。
Real
“Real-TimeHandsonLab”
目的:
本次实验的目的是尝试在WindowsCE环境中开发real-time的应用程序,在过程中我们会探究interrupts、threads、quantums、priorities以及deadlockconditions。
本实验中Deadlockcondition是由外部interrupt所引发的。
我们将藉由发展此一程序的过程来认识关于deadlockcondition和priority的除错技巧。
概述:
本次实验的目的是探究real-time应用程序在WindowsCE环境下的撰写,real-time应用程序主要注重对于外部事件的响应,这些事件对于操作系统来说都被描述为一中断,我们将会了解WindowsCE如何处理中断,且将呈现以时间为主轴描述硬件、核心、ISR以及IST之间互动关系的图表,还有登录文件(registration)内容以及撰写ISR、IST的范例程序也都在此次实验内容中,实验还将藉由探究deadlockconditions来了解执行绪的互动及优先序(priority),deadlock执行绪将被用来示范在windowsCE环境real-time程序的除错技巧。
可针对real-time程序的现成除错技术有很多,其中之一是可将执行绪的优先序由平台的LED显示,此举可让我们了解deadlock时各执行绪的priority.
目的:
2
概述:
2
Agenda.3
LabPart1:
InterruptsandDeveloperTools3
Step1:
了解WindowsCE的中斷結構.3
Step2:
啟動硬體平台3
Step3:
以EmbeddedVisualC++發展IST7
Step4:
下載並測試中斷13
Step5:
UseRemoteToolstoexaminethechainofevents16
LabPart2:
DevelopaDeadlockThread21
Step1:
UnderstandingQuantums,Priorities,PriorityInversion.21
Step2:
Developastrategyfordeadlockthread.21
Step3:
DevelopaSimpleThreadInteraction21
Step4:
UseRemoteToolstoexaminethechainofevents23
Step5:
DevelopaDeadlockThreadInteraction27
Step6:
UseRemoteToolstoexaminethechainofevents29
LabPart3:
從IST當中載入遠端除錯器34
Step1:
開發會載入除錯器的IST.34
Step2:
UsetheDebuggertoexaminesystemstate.37
LabPart4:
開發PriorityRunner程式來找出deadlock的優先序.40
Step1:
對Real-time程式的除錯策略.40
Step2:
PriorityRunner採用的策略.40
Step3:
用EmbeddedVisualC++開發PriorityRunner40
Step4:
使用PriorityRunner來確知Deadlock優先序.45
.
Agenda.
此实验分为四个部份–约需时75分钟来完成整个实验。
LabPart1:
中断结构与开发工具
Step1:
了解WindowsCE的中断结构
请参考UnderstandingWindowsCEInterruptStructure。
Step2:
启动硬件平台
在你的计算机当中已安装了为此次实验所准备的专案檔及SDK。
∙点选桌面上的DEMO_REAL.pbw快捷方式以启动PlatformBuilder。
此平台已在事前建造完成,我们现在要将其下载并联机至目标机器。
∙点选Target->ConfigureRemoteConnection.
将Download及KernelTransport字段皆调整为Ethernet,接着点选Download的Configure按钮。
打开目标机器的电源,几秒后目标机器应该会出现在AvailableDevices清单列表当中。
选取你的目标机器并按下OK按钮。
点选TargetMenuandClickDownload/Initialize选项。
再将目标机器关掉,过了几秒后再次打开,接着下载程序应该就会开始了。
等待完成后点选Close。
若想得到remotedisplay,可以点选桌面上的RemoteDisplay快捷方式,你将得到如下的对话框。
按下ShowList钮。
你的机器将会出现在清单内,将其选取后按下Connect按钮,接着如下的远程机器桌面即会出现。
我们此后便利用这个窗口来操作机器。
你现在已经成功的联机到目标机器,接下来我们将使用EmbeddedVisualC++来开发应用程序。
Step3:
以EmbeddedVisualC++发展IST
我们将选用一DialogShell作为开始,并在其中加入InterruptServiceThread的程序代码。
点选桌面的Reset.bat来重设专案,再点选桌面的RealTimeLab.vcw来开启RealTimeLab专案。
选取Build->BuildReadTimeLab.exe,RealTimeLab即被编译并下载至机器上。
再选取Build->StartDebug->Go,EmbeddedVisualC++将联机至目标机器且确认执行文件及其所需的DLLs。
切换至CERemoteWindowDisplay来看看此程序的执行画面。
目前所有的选项都无法使用,我们会在稍后的步骤中启用他们。
点选桌面的IST.bat快捷方式来更新此专案,你将得到如下的对话框,选取Yes使加载新的RealTimeLabDlg.cpp
现在你己将IST程序代码加入了你的专案当中。
选取Build->BuildReadTimeLab.exe,你将会得到两个错误,这是因为此程序现在需要额外的函式库来执行一些硬件的操作,你将需要些许的修改来加入这些额外的函式库。
设备厂商若是希望独立软件开发商能够存取硬件的服务(如中断)也将必须更新他们的SDK。
选取Tools->Options,点选Directories标签。
加入两个新的目录到Includefiles清单中:
将ShowDirectoriesfor字段改选为Libraryfiles,并加入如下图所列的额外目录:
点选OK钮,再选取Project->Setting,加入ceddk.lib到Link标签当中的Object/Librarymodules字段,如下:
点选OK钮,选取Build->BuildRealTimeLab.exe来重新编译,你现在已将IST加入RealTimeLab专案当中了。
我们刚加入的程序代码中有两个criticalsections。
中断启始的动作是由InterruptHandlingEnable按钮触发,我们来看看其内容:
voidCRealTimeLabDlg:
:
OnIstEnableButton()
//Createanevent
//
g_hevInterrupt=CreateEvent(NULL,FALSE,FALSE,NULL);
if(g_hevInterrupt==NULL)
{
RETAILMSG(1,(TEXT("RTL-IST:
Eventcreationfailed!
!
!
\r\n")));
return;
}
//HavetheOALTranslatetheIRQtoasystemirq
//
fRetVal=KernelIoControl(IOCTL_HAL_TRANSLATE_IRQ,
&dwIrq,
sizeof(dwIrq),
&g_dwSysInt,
sizeof(g_dwSysInt),
NULL);
//Createathreadthatwaitsforsignaling
//
g_fRun=TRUE;
g_htIST=CreateThread(NULL,//CEHasNoSecurity
0,//NoStackSize
ThreadIST,//InterruptThreadNULL,//NoParameters
CREATE_SUSPENDED,//CreateSuspended
&dwThreadID//ThreadId
);
//Setthethreadprioritytorealtime
//
if(!
CeSetThreadPriority(g_htIST,m_nISTPriority))
{
RETAILMSG(1,(TEXT("RTL-IST:
FailedsettingThreadPriority.\r\n")));
return;
}
//Initializetheinterrupt
//
if(!
InterruptInitialize(g_dwSysInt,g_hevInterrupt,NULL,0))
{
RETAILMSG(1,(TEXT("RTL-IST:
InterruptInitializefailed!
!
!
\r\n")));
return;
}
//Updatethedialogwiththethreadnumber
//
m_szISTHandle.Format(L"0x%08X",g_htIST);
UpdateData(FALSE);
m_ISTEnableButton.EnableWindow(FALSE);
m_ISTDisableButton.EnableWindow(TRUE);
//Getthethreadstarted
//
ResumeThread(g_htIST);
启始中断的关键步骤如下:
∙建立一个事件(Event)
∙取得系统中断号码作为IRQ
∙建立一个suspended的interruptthread(IST)
∙呼叫InterruptInitialize来建立IRQ->Event的关连
o若是先前建立的IST不处于suspended状态将可能使InterruptInitialize执行失败,因为事件可能已经在等待。
∙重设IST
IST在ThreadIST函式当中:
DWORDWINAPIThreadIST(LPVOIDlpvParam)
{
DWORDdwStatus;
BOOLfState=TRUE;
//Alwayschectherunningflag
//
while(g_fRun)
{
dwStatus=WaitForSingleObject(g_hevInterrupt,INFINITE);
//Checktoseeifwearefinished
//
if(!
g_fRun)return0;
//Makesurewehvaetheobject
//
if(dwStatus==WAIT_OBJECT_0)
{
//Onlylookforbuttonups.Getgetaninterruptonupanddown
//
if(!
(READ_REGISTER_ULONG(g_pButtonPort)&BUTTON_MASK))
{
RETAILMSG(1,(TEXT("Buttonup...")));
g_dwInterruptCount++;
//StoreourcountoutthetheCELOG
//
CELOGDATA(TRUE,
CELID_RAW_LONG,
&g_dwInterruptCount,
(WORD)(sizeof(DWORD)),
1,
CELZONE_MISC);
RETAILMSG(1,(TEXT("RTL-IST\\ButtonCount:
%d!
\r\n"),
g_dwInterruptCount));
//FlashtheLED
LED(0,fState);
fState=!
fState;
}
//Finishtheinterrupt
//
InterruptDone(g_dwSysInt);
}
}
return0;
}
ISTinterrupthandlingthread当中的重要组件有:
∙等待InterruptEvent
∙确认OS所产生的事件
∙以尽可能短的时间处理中断
∙建立CELOGDATA好由KernelTracker显示
∙改变LED状态
∙回报InterruptDone()
oOS在得到InterruptDone之前,不会再发生另一个同样IRQ的中断
∙等后下一次的InterruptEvent
现在我们准备好执行并测试IST。
Step4:
下载并测试中断
选取Build->StartDebug->Go,此应用程序即被下载至目标,在CRealTimeLabDlg:
:
OnIstEnableButton()函式里的
(if(g_fRun)return;
那一行点一下,并按下F9来设下断点:
切换至CERemoteDisplay,将可以看到InterruptHandlingEnable按钮被启用了。
点选InterruptHandlingEnable按钮,在这边要注意到,IST执行绪的handler显示在对话窗口中,这样做是为了KernelTracker应用程序中做识别。
切换回RealTimeLabProject。
我们将单步执行启始部份的程序代码。
找到先前在CRealTimeLabDlg:
:
OnIstEnableButton()当中设定的断点
(if(g_fRun)return;
按下F9以取消断点的设定:
在ThreadIST函式中的
RETAILMSG(1,(TEXT(“ButtonUp…”)));
那一行按下F9来设下断点,这一行是放开按钮时产生中断所对应的部份。
按下F5使继续执行,然后按下目标机器上的白色按钮再放开,同一时间IST应会在RETAILMSG这一行停止执行,我们将以单步执行IST程序代码。
将光标移至RETAILMSG那行按下F9来取消断点的设定,再按下F5继续执行。
Step5:
使用RemoteTools来检视事件链
选取Tools->RemoteKernelTracker。
你将得到一个窗口要你选择装置,选取DEMO_REAL并按下OK钮。
将ZoomRange(ms)字段设为1000ms,展开左半部的Interrupts以及RealTimeLab.exe,你将会看到如下的画面:
中断以’i’符号表示,绿色的线代表执行绪的变化。
按目标机器上的白色按钮几下,将使得中断选项当中增加一行-Interrupt24.
察看Interrupt24这一行,可能要往回卷一些。
点选Interrupt24那一行当中的中断图示,按下
ISTthread延迟执行的部份为:
∙送出RETAILMSG
∙送出CELOG资料
选取View->EventFilter…。
在Synchronization标签内按下SelectNone按钮
现在我们建立的CELOG使用者数据能够被看见了,选取userdata来察看他的内容。
要移除事件过滤,可选取View->EventFilter…。
,在Synchronization卷标内按下SelectAll按钮。
要将目前的图表缩小,增加可视的时间轴,可按下
要重设记录则可按下
选取File->Exit即可关闭KernelTracker。
LabPart2:
开发一个Deadlock执行绪
Step1:
UnderstandingQuantums,Priorities,PriorityInversion.
请参考UnderstandingWindowsCEQuantums,PrioritiesandPriorityInversion。
Step2:
Developastrategyfordeadlockthread.
请参考StrategyforaDeadlockThread。
Step3:
一个简易的ThreadInteraction
点击桌面上的SimpleThread.bat快捷方式来更新专案。
切换至EmbeddedVisualC++的RealTimeLab专案,在如下对话框中选取Yes钮载入新的RealTimeLabDlg.cpp。
现在你已加入SimpleThread程序代码至专案当中。
选取Build->BuildRealTimeLab.exe来重新编译,你现在把SimpleThreadInteraction也加入了RealTimeLab专案当中了。
在我们刚加入的程序代码中有三个criticalsections,执行绪的启始动作是由ThreadViewEnable按钮触发,来看看这个函式内容:
voidCRealTimeLabDlg:
:
OnTvEnableButton()
//InitalizetheCriticalSection
//
InitializeCriticalSection(&g_csTVCriticalSection);
//CreatetheHighPriorityThread
//
g_htTVHigh=CreateThread(
NULL,//CEHasNoSecurity
0,//NoStackSize
TVThreadHigh,//InterruptThreadNULL,//NoParameters
CREATE_SUSPENDED,//NoCreationFlags
&dwThreadID//ThreadId
);
//Setthethreadprioritytorealtime
//
if(!
CeSetThreadPriority(g_htTVHigh,m_nTVHighPriority))
{
RETAILMSG(1,(TEXT("RTL-TV:
FailedsettingHighThreadPriority.\r\n")));
return;
}
//CreatetheMediumPriorityThread
//
g_htTVMed=CreateThread(
NULL,//CEHasNoSecurity
0,//NoStackSize
TVThreadMed,//InterruptThreadNULL,//NoParameters
CREATE_SUSPENDED,//NoCreationFlags
&dwThreadID//ThreadId
);
//Setthethreadprioritytorealtime
//
if(!
CeSetThreadPriority(g_htTVMed,m_nTVMedPriority))
{
RETAILMSG(1,(TEXT("RTL-TV:
FailedsettingMediumPriority.\r\n")));
return;
}
//Getthethreadsgoing
//
g_fTVRun=TRUE;
ResumeThread(g_htTVHigh);
ResumeThread(g_htTVMed);
其中关键的步骤为:
∙启始CriticalSection
∙建立一suspendedHighPriorityThread
∙设定HighPriorityThread的priority.
∙建立一suspendedMediumPriorityThread
∙设定MediumPriorityThread的priority.
∙重设这两个执行绪好让他们开始执行
highprioritythread在函式TVThreadHigh中:
DWORDWINAPITVThreadHigh(LPVOIDlpvParam)
{
while(g_fTVRun)
{
//GrabthecriticalSection
EnterCriticalSection(&g_csTVCriticalSection);
//WritetoCELogthatweownit
CELOGDATA(TRUE,
CELID_RAW_LONG,
&g_htTVHigh,
(WORD)(sizeof(DWORD)),
1,
CELZONE_MISC);
//Releasethecritic
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Real