Upload
vuonglien
View
225
Download
0
Embed Size (px)
Citation preview
RTX 5.0User’s Guide
VenturCom, Inc.Five Cambridge CenterCambridge, MA 02142
Tel: 617-661-1230Fax: 617-577-1607
[email protected]://www.vci.com
RTX User’s Guide
No part of this document may be reproduced or transmitted in any form or by any means,graphic, electronic, or mechanical, including photocopying, and recording or by anyinformation storage or retrieval system without the prior written permission of VenturCom,Inc. unless such copying is expressly permitted by federal copyright law.
2000 VenturCom, Inc. All rights reserved.
While every effort has been made to ensure the accuracy and completeness of all informationin this document, VenturCom, Inc. assumes no liability to any party for any loss or damagecaused by errors or omissions or by statements of any kind in this document, its updates,supplements, or special editions, whether such errors, omissions, or statements result fromnegligence, accident, or any other cause. VenturCom, Inc. further assumes no liability arisingout of the application or use of any product or system described herein; nor any liability forincidental or consequential damages arising from the use of this document. VenturCom, Inc.disclaims all warranties regarding the information contained herein, whether expressed,implied or statutory, including implied warranties of merchantability or fitness for a particularpurpose.
VenturCom, Inc. reserves the right to make changes to this document or to the productsdescribed herein without further notice.
RTX is a trademark and CENTer is a servicemark of VenturCom, Inc.
Microsoft, MS, and Win32 are registered trademarks and Windows, Windows CE, andWindows NT are trademarks of Microsoft Corporation.
All other companies and product names may be trademarks or registered trademarks of theirrespective holders.
RTX 5.0 User’s Guide
1-015-10
iii
Table of ContentsWELCOME TO RTX 5.0 ................................................................................................IXGetting Support.............................................................................................................. ix
Technical Support ........................................................................................................................ ix
VenturCom Web Site ................................................................................................................... ix
Documentation Updates.................................................................................................. x
About the User’s Guide ................................................................................................... xCHAPTER 1INTRODUCTION TO RTX............................................................................................... 1The RTX Architecture...................................................................................................... 1
Real-Time Inter-Process Communication .....................................................................................2
HAL Extension...............................................................................................................................2
Uniprocessor and Multiprocessor Systems...................................................................................2
The RTX Application Programming Interface (API) ......................................................... 3
Win32 and Real-Time API.............................................................................................................3
RTX Executable Images ...............................................................................................................3
Run-Time Libraries........................................................................................................................4
Unicode .........................................................................................................................................4
Designing and Developing RTX Applications .................................................................. 4
RTX Device Drivers.......................................................................................................................4
Testing Real-Time Applications ....................................................................................................5
Creating and Starting an RTSS Process ......................................................................................5
Stopping an RTSS Process ..........................................................................................................5CHAPTER 2USING SOFTWARE DEVELOPMENT TOOLS .............................................................. 7Using the RTX Utilities .................................................................................................... 8
Utility Task Table...........................................................................................................................8
RTSSrun Utility (Console and GUI) ..............................................................................................9
RTSSrun GUI ..............................................................................................................................10
RTSSkill Utility.............................................................................................................................11
RTSSview Utility..........................................................................................................................12RTSSview Example ...............................................................................................................................12
RTSS Object Viewer ...................................................................................................................13
RTSS Task Manager...................................................................................................................15
RtxServer ....................................................................................................................................16
Using the RTX AppWizard in Microsoft Visual Studio 6.0.............................................. 17
Creating a Project and Setting Options.......................................................................................17Setting Project Options ..........................................................................................................................18
Setting Program Options .......................................................................................................................19
Running an Image.......................................................................................................................20
Registering an RTDLL.................................................................................................................21
RTX User’s Guide
iv
Using Microsoft Visual Studio 6.0.................................................................................. 21
Setting up Microsoft Visual Studio ..............................................................................................21
Building and Running Images (Win32 Environment) ..................................................................21
Building and Running Images (RTSS Environment)...................................................................22
Building and Registering RTDLLs...............................................................................................23
Creating RTX Dynamic Link Libraries ........................................................................... 25
Building an RTDLL ......................................................................................................................25
Building an RTSS DLL ................................................................................................................25
Debugging an RTX Program......................................................................................... 26
Excluding debugging information................................................................................................26
Using Microsoft’s WinDbg 5.0 with RTSS...................................................................................29
Testing an RTX Program with Shutdown Handlers........................................................ 29
Shutdown Program .....................................................................................................................29
Gencrash Driver ..........................................................................................................................29Usage ....................................................................................................................................................30
Using the RTX Properties Contol Panel ........................................................................ 30CHAPTER 3USING THE RTX FUNCTIONALITY............................................................................. 33Process and Thread Management ................................................................................ 34
Processes and Threads ..............................................................................................................34Using Processes....................................................................................................................................34
Using Threads .......................................................................................................................................35
Thread Priorities ....................................................................................................................................35
System Memory Management ....................................................................................................37System Memory Allocation ....................................................................................................................37
System Memory Locking .......................................................................................................................38
Clocks and Timers ......................................................................................................................40Clock Services.......................................................................................................................................40
Timer Services.......................................................................................................................................41
Sleep Services.......................................................................................................................................42
APIs .......................................................................................................................................................42
Programming Considerations ................................................................................................................42
Programming Example (RTX Timer and Sleep Calls)............................................................................42
Inter-Process Communication ....................................................................................... 43
Object Names .............................................................................................................................43
Shared Memory...........................................................................................................................43Inter-Process Communication via Shared Memory................................................................................43
Environments.........................................................................................................................................44
Semaphores................................................................................................................................44Inter-Process Communication via Semaphores.....................................................................................45
Environments.........................................................................................................................................45
Event Objects ..............................................................................................................................46Using RtCreateEvent .............................................................................................................................46
Using RtPulseEvent...............................................................................................................................46
RTX User’s Guide
v
Mutex Objects .............................................................................................................................46Ownership .............................................................................................................................................46
Inter-Process Communication via Mutex Objects ..................................................................................47
Environments.........................................................................................................................................47
Device Management ..................................................................................................... 48
Interrupts .....................................................................................................................................48Interrupt Management ...........................................................................................................................48
APIs .......................................................................................................................................................48
General Programming Considerations...................................................................................................49
Win32 Environment Programming Considerations ................................................................................49
Using RtAttachInterruptVector ...............................................................................................................49
Using RtAttachInterruptVectorEx...........................................................................................................49
Using RtReleaseInterruptVector ............................................................................................................50
Programming Example (Interrupt Management and Port I/O Calls).......................................................50
Port IO .........................................................................................................................................50Port I/O Control APIs .............................................................................................................................50
Port I/O Data Transfer APIs...................................................................................................................51
General Programming Considerations...................................................................................................51
Programming Example ..........................................................................................................................51
Physical Memory Mapping ..........................................................................................................51APIs .......................................................................................................................................................51
General Programming Considerations...................................................................................................52
Win32 Environment Programming Considerations ................................................................................52
Programming Example (RTX Memory Mapping Calls) ..........................................................................52
Contiguous Memory Mapping .....................................................................................................52Programming Considerations ................................................................................................................52
Programming Example (RTX Contiguous Memory Allocation Calls) .....................................................53
Bus IO .........................................................................................................................................53Programming Example (Bus I/O) ...........................................................................................................53
File IO..........................................................................................................................................53File IO ....................................................................................................................................................53
CHAPTER 4DEVELOPING AN APPLICATION ............................................................................... 55Using the RTX Makefile ................................................................................................ 56
Variables .....................................................................................................................................56
Sample Makefile..........................................................................................................................56
Using RTX Dynamic Link Libraries................................................................................ 57
About RTSS DLLs and RTDLLs..................................................................................................57
C Run-Time Libraries: Programming Considerations for DLLs ..................................................57RTSS DLLs............................................................................................................................................58
RTDLLs .................................................................................................................................................58
RTSS DLL and RTDLL Code Examples ................................................................................................58
Using the C Run-time Library Functions........................................................................ 59
Using Floating Point ...................................................................................................... 59
Enabling Floating-Point Support in RTSS Programs ..................................................................59
RTX User’s Guide
vi
Running RTSS Programs Using Floating-Point ..........................................................................59
Writing RTSS Device Drivers ........................................................................................ 59
C++ and Structured Exception Handling ....................................................................... 60
C++ Support ................................................................................................................................60
Structured Exception Handling....................................................................................................60
Using SEH...................................................................................................................................61Differences Between Win32 and RTSS Exception Handling .................................................................61
UnhandledExceptionFilter......................................................................................................................61
Exception caused by a thread ...............................................................................................................61
Nested exceptions and collided unwinds ...............................................................................................61
Debugging .............................................................................................................................................62
General User Notes for Exception Handling ...............................................................................62
System Exception Handling .......................................................................................... 62
About System Exception Handling..............................................................................................62
RTX Handler................................................................................................................................62
Tables of Exceptions...................................................................................................................63RTX Exception Codes ...........................................................................................................................63
Intel Exception Codes............................................................................................................................63
RTX Exception Handling .............................................................................................................64Freeze or Terminate Processing............................................................................................................64
Alert User...............................................................................................................................................64
Generate Event Log Entries ..................................................................................................................65
About RTX and Windows NT / Windows 2000 Stop Messages .................................................65
Interpreting Windows NT Blue Screen Stop Messages..............................................................66Section 1 - Stop Message......................................................................................................................66
Section 2 - Driver List ............................................................................................................................66
Section 3 - System Stack Dump ............................................................................................................66
Section 4 - Communication....................................................................................................................67
Interpreting Windows 2000 Stop Screens...................................................................................68
Interpreting RTX Green Screen Stop Messages ........................................................................69Section 1 - RTSS-Specific Stop Message .............................................................................................69
Section 2 - HAL-Supplied Stop Message...............................................................................................70
Starvation Management ..............................................................................................................70Watchdog Management.........................................................................................................................70
Setting the Starvation Time Out Period .................................................................................................71
RTX Power Management for Windows 2000..............................................................................71CHAPTER 5PERFORMANCE OVERVIEW...................................................................................... 73Causes and Management of Interrupt Latencies ........................................................... 74
Software Causes.........................................................................................................................74
Hardware Causes .......................................................................................................................74
RTX Management of Interrupt Latencies ....................................................................................74
Reducing Your System’s Latencies: Tools Overview..................................................... 75
SRTM (System Response Time Measurement) and RTX Demo ...............................................75
KSRTM (Kernel System Response Time Measurement) ...........................................................75
RTX User’s Guide
vii
LTP (Latency Test Program).......................................................................................................75
Timer Latency Display.................................................................................................................75
KSRTM versus SRTM.................................................................................................................75
Using KSRTM (Kernel System Response Time Measurement)..................................... 76
Using SRTM (System Response Time Measurement) .................................................. 77
Using RTX Demo (Graphical version of SRTM) ............................................................ 78
Interpreting the Max Latency Plot ...............................................................................................79
Interpreting the Histogram Plot ...................................................................................................80
Using the Timer Latency Display Tool ........................................................................... 80
Interpreting the Histogram...........................................................................................................81
Interpreting the Latency display ..................................................................................................82
Using LTP (Latency Test Program) ............................................................................... 82APPENDIX ACODE AND FILE EXAMPLES...................................................................................... 83Bus IO Programming Example...................................................................................... 83
Interrupt Management and Port IO Calls Programming Example .................................. 88
Makefile Sample ........................................................................................................... 90
Nmake Input File Example ............................................................................................ 91
RTDLL Code Example .................................................................................................. 92
RTDLL Part 1: sampleRtdll.c.......................................................................................................92
RTDLL Part 2: usingRtdll.c..........................................................................................................92
RTDLL Part 3: rtdll.mak...............................................................................................................94
RTDLL Part 4: Register the rtdll ..................................................................................................94
RTSS DLL Code Example............................................................................................. 95
RTSS DLL Part 1: dll.c ................................................................................................................95
RTSS DLL Part 2: dll.def.............................................................................................................95
RTSS DLL Part 3: dll-test.c .........................................................................................................96
RTSS DLL Part 4: dll.mak ...........................................................................................................97
RTSS DLL Part 5: runtest.c.........................................................................................................97
RTSS DLL Makefile Example........................................................................................ 99
RTSSkill Examples...................................................................................................... 100
RTSSkill Example 1 ..................................................................................................................100
RTSSkill Example 2 ..................................................................................................................100
RTSSview Example .................................................................................................... 101
RTX Contiguous Memory Allocation Calls Programming Example .............................. 102
RTX Kernel Memory Locking Calls Programming Example......................................... 103
RTX Locked Memory Allocation Calls Programming Example .................................... 104
RTX Memory Mapping Calls Programming Example................................................... 105
RTX Process Memory Locking Calls Programming Example ...................................... 106
RTX User’s Guide
viii
RTX Timer and Sleep Calls Programming Example .................................................... 107INDEX......................................................................................................................... 109
ix
Welcome to RTX 5.0
Document ID: 1-015-10
© 2000 VenturCom, Inc. All rights reserved.
VenturCom’s Real-time Extension (RTX) adds real-time capabilities to Windows NT andWindows 2000 that are unparalleled in the industry. It offers developers a rich and powerfulreal-time feature set — all in a familiar Win32-compatible interface. It also provides toolsand utilities for building and executing real-time programs, along with tools for measuringand fine tuning the performance of both hardware and software.
In addition to using the real-time interfaces and tools provided by RTX, developers cancontinue to take advantage of the abundance of products available for Windows NT andWindows 2000. And, with the RTX inter-process communication features, the Win32 run-time environment works seamlessly with the RTX real-time subsystem — enabling theintegration of Win32 and real-time functionality.
Experienced real-time developers will value the power of the RTX interface; we suggest thatyou refer to the topics in the RTX Overview for a more detailed description of RTX and adiscussion of important design decisions that need to be made in order to fully take advantageof RTX features.
Getting Support
VenturCom offers a number of support options for RTX users, including technical supportand the VenturCom Web site.
Note: If you are a customer who purchased direct support, you would have received aSupport ID# in the letter that comes with the software. Please have this number available forreference when contacting VenturCom. Users who purchased their product through thirdparties should contact those parties directly with their questions.
Technical Support
For technical support related to installing and using RTX, VenturCom offers several channelsof communication. You can:
� Call technical support at 800-334-8649 between 9:00 AM and 6:00 PM (Eastern Time)
� Email your questions to [email protected]
� Fax your questions to 617-577-1607
VenturCom Web Site
The VenturCom Customer Support Web page is located at:
RTX User’s Guide
x
http://www.vci.com/tech_support/support_description.html
If you are a customer with a current support contract or a member of the Real-time andEmbedded Partner Program, then you should bookmark to the Web page in the TechnicalSupport Area located at:
http://www.vci.com/tech_support/support_login.html
These pages provide electronic access to the latest product releases, documentation, andrelease notes. With a valid Support ID#, you can access the online problem report database tosubmit new issues, or to obtain the status of previously reported issues.
Documentation Updates
VenturCom is committed to providing you with the information you need to use our products.From time to time, we may provide documentation updates for our products. Check ourCENTer page for updates. While visiting CENTer, check out the various white pages andpresentations. CENTer also provides access to several newsgroups. You’ll also find freeutilities and extensions that you can download.
About the User’s Guide
The RTX User’s Guide describes the RTX product and explains how to use its features; it isintended for users who are familiar with developing applications in a Win32 environment.
The following list introduces the chapters in this guide.
RTX Overview — Describes the RTX architecture, discusses how to design programs usingRTX.
Using Software Development Tools — Explains how to use RTX programs, utilities, andtools to develop real-time applications. It also contains procedures for building applicationsand dynamic link libraries as well as procedures for debugging and testing your application.
Using the RTX Functionality — Presents the RTX functionality, discusses important real-time programming issues, and provides references to real-time code examples that illustratethe implementation of real-time programming techniques.
Developing an Application — Explains how to use dynamic link libraries, C run-timelibrary functions, and floating point when developing an application. It also describesexception handling in the RTSS and Win32 environments and techniques for managingstarvation conditions.
Performance — Discusses key real-time performance issues, such as latency metrics andtiming factors, and provides programming approaches for ensuring good response times inyour applications. It also explains how to use the RTX performance tools.
1
CHAPTER 1
Introduction to RTXToday’s real-time and embedded applications contain a broad range of functionality, such asGUI-based operator interfaces, communication with other information systems, and time-critical monitoring and control of equipment. For both developers and end users of theseapplications, Windows NT and Windows 2000 — with their advanced features, range ofsupported hardware configurations, and availability of off-the-shelf add-on components —are the the operating system platforms of choice. However, since their functionality was nottargeted for "hard" real-time applications, the use of Windows NT and Windows 2000 aresignificantly restricted, and often prevented, for these applications. VenturCom's RTXproduct bridges this gap by adding "hard" real-time capabilities to both Windows NT andWindows 2000.
By extending the Windows NT and Windows 2000 operating systems, RTX enablesapplication components or modules that require deterministic and high-speed response times,along with other non-real-time application components, to work together on a commonWindows system. With RTX, you can use a single, low-cost platform to satisfy a full range ofreal-time and embedded application requirements.
While RTX brings superior real-time capabilities to Windows NT and Windows 2000, thereare two areas in which real-time application developers must take active responsibility tofully realize its benefits. First, because worst-case response times vary significantly amongsystems, developers and their end users must carefully select their systems. Different boardvendors, especially video card vendors, make different tradeoffs between price, throughput,and deterministic behavior. With the help of VenturCom's RTX performance analysis tools,developers and their users can select systems that ensure their real-time requirements are met.Second, developers must properly implement RTX in their applications. RTX provides rawpower that can, if implemented in applications improperly, adversely impact other Windowsapplications and might even compromise overall system stability. The User’s Guide can assistyou in implementing RTX.
The RTX Architecture
RTX adds a real-time subsystem, known as RTSS, to Windows NT and Windows 2000 (seethe figure below). RTSS is conceptually similar to other Windows NT subsystems (such asWin32, POSIX, WOW, and DOS) in that it supports its own execution environment and API.RTSS differs in one important area, though: Instead of using the Windows NT or Windows2000 scheduler, RTSS performs its own real-time thread scheduling. Furthermore, in auniprocessor environment, all RTSS thread scheduling occurs ahead of all Windowsscheduling, including Windows-managed interrupts and Deferred Procedure Calls (DPCs).
RTX User’s Guide
2
57;�DQG�:LQGRZV�17�:RUNLQJ�7RJHWKHU
Real-Time Inter-Process Communication
RTSS also supports Inter-Process Communication (IPC) objects that can be manipulated byeither RTSS or Win32 processes; this enables simple and standard communication andsynchronization between real-time and non-real-time programs. Finally, RTSS provides othertime-critical services — such as clocks and timers and interrupt management — to RTSSprocesses.
HAL Extension
RTX includes a real-time enabled Hardware Abstraction Layer (HAL) extension. Thisextension maintains interrupt isolation between RTSS and Windows NT or Windows 2000.Windows cannot mask (at the interrupt controller level) interrupts managed by RTSS.Windows interrupts are masked during RTSS processing. The real-time HAL extensionsupports high-resolution clocks and timers for RTSS, while it also supports non-real-timeclocks and timers for Windows NT and Windows 2000. Other real-time HAL extensionfeatures include a software interrupt mechanism between RTSS and Windows; basicexception management; and various enhancements for determinism.
Uniprocessor and Multiprocessor Systems
RTX supports both uniprocessor and multiprocessor Windows NT and Windows 2000systems. The run-time version of RTX, which supports multiprocessor systems, provides allof the features of the uniprocessor version, plus it exploits the features of Intel MPS-compliant multiprocessor systems to provide improved performance in both Windows andRTX environments.
Run-time RTX, for multiprocessor systems, implements a dedicated processor model. In thismodel, RTSS runs on one processor, while the remaining processors continue to run onWindows. The multiprocessor HAL acquires control of the last logical processor during theWindows boot sequence and it is reserved for RTSS. RTSS programs can then be loaded and
Chapter 1: Introduction
3
executed on the dedicated processor.
The RTX Application Programming Interface for Win32 and RTSS processes, includingFloating-Point Unit (FPU) and structured exception handling, is used for both uniprocessorand multiprocessor systems. This eliminates the need to recode RTX (uniprocessor)applications for a multiprocessor platform.
The RTX Application Programming Interface (API)
The RTX API is based on the Win32 API, using the same API already familiar to Windowsapplication developers. This approach allows developers to draw upon their Win32experience, code base, and development tools, thus expediting hard real-time applicationdevelopment. Both Win32 and RTSS processes support the full RTX API — albeit withdifferent response times and performance characteristics — allowing developers toeffortlessly share or move code between environments.
This topic discusses:
Win32_and_Real-Time_API
RTX_Executable_Images
Run-Time_Libraries
Unicode
Win32 and Real-Time API
RTX supports a subset of Win32 API functions, plus it provides a special set of real-timefunctions, known as RTAPI (Real-Time API). RTAPI functions are identified by an "Rt"prefix in their names. Some RTAPI functions are semantically identical to their Win32counterparts, while others are unique to RTX (i.e., there are no similar Win32 calls). Forexample, RTAPI real-time IPC functions differ from Win32 IPC functions only in the IPCname space in which they operate and in the determinism possible with real-time IPC objects.On the other hand, the Win32 API does not include any functions related to interruptmanagement; therefore, unique interrupt management functions are defined in RTAPI.
The RTX API was carefully selected to promote efficient development of real-timeapplication components. RTX intentionally does not include Win32 functions, such as theGUI-related calls, that are normally used by the less time-critical components of anapplication. In fact, Win32 functions that are not essential to real-time programming, andimpractical to implement with deterministic behavior, are not included in the RTX API. It isexpected that most applications will consist of at least two processes working together-oneWin32-based process (to take advantage of GUI and other Win32-only functions) and anRTSS-based process to perform time-critical processing.
RTX Executable Images
RTX provides three types of executable images: RTSS applications, RTSS DLLs, andRTDLLs. RTSS applications are the real-time analogues of Win32 applications. RTSS DLLsare RTSS applications that have been linked to provide an export library that RTSS and otherapplications can use to call functions within an RTSS DLL. RTSS DLLs are full RTSSprocesses and must be launched manually prior to their use by RTSS applications. RTDLLs
RTX User’s Guide
4
are passive code containers, similar in functionality to Win32 DLLs, which run in RTSS. Fordetails about how to choose, design, and build appropriate combinations of these types ofimages, see the chapters Using Software Development Tools and Developing an Applicationin this guide.
Run-Time Libraries
RTX also supports various run-time libraries, and provides a ’C’ run-time library based on MSVisual C++. RTSS processes can be statically linked to include these libraries, provided theydo not attempt to link to unsupported Win32 functions. RTSS processes can also be linkedagainst specialized versions of dynamic link libraries (DLLs), which can be used tomodularize real-time application code or provide run-time customization of real-timesoftware environments.
Unicode
RTX supports Unicode applications. An RTSS process can use the wmain() function andaccept wide character input arguments. Support for the WCS family of functions is includedas part of the RTX-supported C run-time library.
Designing and Developing RTX Applications
To ensure successful development of a real-time application, designers and developers mustcarefully analyze how to efficiently partition the application. They must also establish thecorrect balance between non-real-time (Win32) processes and real-time (RTSS) processesand determine the interface between them. If, for example, there is time-critical processing inWin32 processes, too much non-time-critical processing in RTSS processes, or too muchsynchronization or data flow across the process interfaces, the application’s performance,usability, and overall ease of development and maintenance will be jeopardized. An initialinvestment of time spent analyzing the various tradeoffs and designs in this criticalarchitecture area will be worthwhile to both developers and their users.
This topic discusses:
� RTX_Device_Drivers
� Testing Real-Time Applications
� Starting an RTSS Process
� Stopping an RTSS Process
RTX Device Drivers
Some designs call for application components that act as device drivers to other applicationcomponents, or board vendors may want to provide real-time device drivers for their boardsthat can be used by a variety of real-time and non-real-time applications. The device driverdesigner can use either DLLs or real-time IPC mechanisms to connect drivers andapplications together. The real-time IPC offers the most flexible option because Win32 andRTSS processes can both access a common real-time driver using the same interface, even atthe same time. The sample directory includes an RTX library for device drivers based onreal-time IPC that provides a traditional device driver interface (e.g., open, close, read, write,
Chapter 1: Introduction
5
and control) to either Win32 or RTSS applications.
Testing Real-Time Applications
In most cases, the initial development and testing of real-time application components,including device drivers, is most easily done in the Win32 environment. The Win32environment provides the widest range of development, debug, and test tools, and the bestdetection of misbehaving applications. After all non-time-critical testing is completed, thereal-time application component is simply re-linked as an RTSS process for final testing inthe deterministic RTSS environment. If extensive debugging of RTSS processes is necessary,you can use Microsoft’s WinDbg.
Creating and Starting an RTSS Process
Several methods are available for starting RTSS processes. During development and testing,you will typically start RTSS processes from the command prompt with optional commandline arguments or by clicking on the RTSS executable file icon in Windows Explorer. Forfinal applications, you will generally use either the feature that starts specified RTSSprocesses at boot time (i.e., when the "blue screen" starts), or you will launch RTSS processesdirectly from a Win32 process. To create and launch the RTSS process directly, you will usethe Win32 RTCreateProcess call to ceate and start the specified RTSS process.
Stopping an RTSS Process
An RTSS process stops when:
� The process calls the ExitProcess function
� A user or a Win32 process runs the RTSSkill utility
� A user terminates the process through the RTSS Task Manager
The process generates an exception
A Windows NT or Windows 2000 system shutdown occurs (either a normal shutdownsequence or an exception-initiated Windows NT "blue screen" stop or Windows 2000 stopscreen)
RTSS processes can register shutdown handlers that are called when Windows is shut downor stopped to allow the final sequencing of equipment and cleanup prior to full system stopand possible reboot.
RTX User’s Guide
6
7
CHAPTER 2
Using Software Development ToolsThis chapter discusses the RTX programs, utilities, drivers, files, and RTX control panelsettings that you work with when developing and testing your real-time programs. It containsprocedures for using Microsoft Visual Studio, by itself or with the RTX AppWizard, forbuilding RTSS images and dynamic link libraries. This chapter also contains instructions ondebugging your programs using Microsoft’s WinDbg and testing programs with shutdownhandlers.
This chapter contains information on:
n Using the RTX UtilitiesUtility Task TableRTSSrun UtilityRTSSkill UtilityRTSSview UtilityRTSS Task ManagerRTSS Object ViewerRtxServer
n Using the RTX AppWizard in Microsoft Visual Studio 6.0
n Using Microsoft Visual Studio 6.0
n Creating Dynamic Link Libraries
n Debugging an RTX Program
n Testing an RTX Program with Shutdown Handlers
n Using the RTX Properties Contol Panel
RTX User’s Guide
8
Using the RTX Utilities
Utility Task Table
The table that follows shows which utility to use to perform a particular task.
,I�\RX�ZDQW�WR��� 8VH���
5XQ�DQ�5766�SURFHVV 5766UXQ��FRQVROH�RU�IURP�WKH�57;�6WDUWPHQX�
/RDG�DQ�5766�'// 5766UXQ��FRQVROH�RU�IURP�WKH�57;�6WDUWPHQX�
5HJLVWHU�DQ�57'// 5766UXQ��FRQVROH�RU�IURP�WKH�57;�6WDUWPHQX�
7HUPLQDWH�DQ�5766�SURFHVV 5766NLOO��FRQVROH��RU
5766�7DVN�0DQDJHU�RQ�WKH�57;�6WDUWPHQX
8QUHJLVWHU�DQ�57'// 5766NLOO��FRQVROH��RU
5766�7DVN�0DQDJHU�RQ�WKH�57;�6WDUWPHQX
9LHZ�D�OLVW�RI�DOO�SURFHVVHV�DQGUHJLVWHUHG�57'//V
5766NLOO��FRQVROH��RU
5766�7DVN�0DQDJHU�RQ�WKH�57;�6WDUWPHQX
9LHZ�LQIRUPDWLRQ�DERXW�5766�SURFHVVHVDQG�WKHLU�DVVRFLDWHG�REMHFWV��LQFOXGLQJ7KUHDG��7LPHU��6HPDSKRUH��0XWH[�6KDUHG�PHPRU\��DQG�/RDGHG�57'//
5766YLHZ��FRQVROH��RU
5766�2EMHFW�9LHZHU�RQ�WKH�57;�6WDUWPHQX
Chapter 2: Using Software Developmen Tools
9
RTSSrun Utility (Console and GUI)
Use the RTSSrun utility to run an RTSS process in the RTSS environment, load an RTSSDLL, and register an RTDLL.
When you use RTSSrun to run an RTSS process, it scans the RTSS process service slots for afree slot. It copies the RTSS executable image to the target directory for the process slot andestablishes a pointer to the path. It then copies the command line to the registry and starts theservice for this RTSS process. If successful, the slot number of the new process is returned;otherwise, RTSSrun returns -1.
RTSSrun Console
Each time you use this utility with the /b or /d switch, the current version of the .rtss or .rtdllfile is copied to a location in the %SystemRoot% directory. Thus, whenever you rebuild aboot-time RTSS application or an RTDLL, you must rerun RTSSrun in order to access thenew version.
Usage
RTSSrun file [arguments]
Format
To run an RTSS process: RTSSrun [ /b ] <filename>[.rtss] [ arguments ]
To register an RTDLL: RTSSrun /d [/s] <filename>[.rtdll]
where
/q = Disables messages indicating success or failure to start the RTSS process.
/b = Runs the RTSS process early in the system boot sequence.
/d = Loads an RTDLL and adds entries to the registry.
/s = Allows an RTDLL to be loaded by several processes at the same time. Otherwise,only threads within a single process can simultaneously load a particular RTDLL.
/t = Tests loading and unloading of RTDLLs. This switch must be used in conjunctionwith the /d switch.
filename = Name of the file to be run.
arguments = Command line arguments passed to the process.
RTX User’s Guide
10
RTSSrun GUI
Usage
On the VenturCom RTX SDK Start menu, choose RTSSRun.
or
On the RTSS Task Manager window, click the Start Task button.
Results
The RTSSrun window, shown below, opens.
5766UXQ�:LQGRZ
Special Mode Options
Run RTSS process — When running an RTSS process, you can elect to start the processearly in the system boot sequence by selecting Register to run at boot time, however RTXmust be set at boot time for this to take effect.
Register RTDLL — When registering an RTDLL, you can elect to:
Share Between Processes — Allows an RTDLL to be loaded by several processes at thesame time. Otherwise, only threads within a single process can simultaneously load aparticular RTDLL.
Perform Load\Unload Test — Performs test loading and unloading of RTDLLs.
See Also
RTSS Task Manager
Chapter 2: Using Software Developmen Tools
11
RTSSkill Utility
Use the RTSSkill utility to terminate a particular RTSS process or unregister an RTDLL thatis not loaded. You cannot unregister an RTDLL if any RTSS process currently has it loaded.You can also use this utility to view a list of all RTSS processes, including registeredRTDLLs that have not been loaded, by omitting the process number or filename.
Usage
To view processes and registered RTDLLs: RTSSkill
To terminate process 001: RTSSkill 001
To unregister an ˆ ¯ DLL: RTSSkill myfile.rtdll
Format
To terminate a particular process: RTSSkill [/b] [process number]
To unregister an RTDLL: RTSSkill filename.rtdll
where
/b = Undoes the RTSSrun /b action. The program will not start automatically at boot time.
RTSSkill Examples
See the RTSSkill Examples in Code and File Examples in Appendix A.
RTX User’s Guide
12
RTSSview Utility
Use the RTSSview utility to view information about RTSS processes and their associatedobjects, such as events, semaphores, and loaded RTDLLs.
Usage and Format
RTSSview /A (provides internal system processes and WIN32 proxy processes
Results
RTSSview lists each type of RTSS object, followed by its memory address in the kerneladdress space and the process id. It also lists information specific to each particular object:
Process — Gives the name or type of process, followed beneath the listing by each threadobject owned by that process.
Thread — Provides the priority and state of the thread, plus the value of the flag settingswhich indicate certain thread behaviors. RTX assigns a priority value to each thread in theuser's process, with values ranging from 0 to 127 (see Thread Priorities on page 35). Threadsthat have negative priority numbers belong to system processes. The thread flags have thefollowing assignments:
9DOXH 0HDQLQJ
�[�� 'R�QRW�GHDOORFDWH�PHPRU\
�[�� 'R�QRW�IUHH�WKH�WKUHDGV�VWDFN
�[�� 7KUHDG�WHUPLQDWHG
�[�� 7KUHDG�FDQQRW�EH�UHVXPHG
�[�� ,QWHUUXSW�WKUHDG
�[�� )ORDWLQJ�SRLQW
Timer — Provides the clock number, the remaining time, and the timing interval.
Semaphore — Provides the count, maxcount, and the object name (if there is one).
Mutex — Lists the count, the address of the owner, and its object name (if there is one).
Shared memory — Gives the base memory address, the size of the shared memory, and theobject name.
RTDLL — Lists the count, address of the owner, and the object name.
Event — Provides the state of the event, whether the event is reset manually or not, and thename of the event.
File — Provides the Windows NT handle for the file and the filename.
RTSSview Example
See the RTSSview Example in Code and File Examples in Appendix A.
Chapter 2: Using Software Developmen Tools
13
RTSS Object Viewer
When you start RTSS Object Viewer, it displays an explorer that allows you to navigatethrough all the active objects found in the Real-Time Subsystem (RTSS). The tree view (leftpanel) displays all active RTSS objects, while the list view (right panel) displays extendedinformation on the items checked in the tree view.
Usage
On the VenturCom RTX SDK Start menu, choose RTSS Object Viewer.
Results
The RTSS Object Viewer window, shown below, opens.
5766�2EMHFW�9LHZHU
RTX User’s Guide
14
Menu
The RTSS Object Viewer window contains the following menus. For additional information,refer to the online help that is included in the application.
File — Provides standard exit option.
Options — Provides extra display options:
Always On Top — Keeps the RTSS Object Viewer window on top.
Check All/Uncheck All — Causes all object to be displayed/removed from the list view.
View — Lets you specify how the information is displayed:
Refresh Now — Refreshes the Explorer view.
Refresh Rate — Lets you specify a Refresh Rate of high (one second), normal (twoseconds), low (five seconds), or Paused (turned off). The default is for automatic refresh tobe turned off.
Compact style — Allows for a more condensed view of object attributes. Objectattributes are displayed in one column instead of each attribute in its own column.
Select Columns — Allows you to select which columns to display and their order. Thisoption is not available if Compact style is selected.
Help — Provides information about RTSS Object Viewer:
Help Contents — Opens the help contents.
About RTSS Object Viewer — Opens a pop-up with copyright information.
Chapter 2: Using Software Developmen Tools
15
RTSS Task Manager
RTSS Task Manager lets you view and control all active RTSS Processes and registeredRTDLLs on your system.
Usage
On the VenturCom RTX SDK Start menu, choose RTSS Task Manager.
Results
The RTSS Task Manager window, shown below, opens.
5766�7DVN�0DQDJHU
Buttons and Options
The RTSS Task Manager window contains the following buttons and options:
Always On Top — Keeps the RTSS Task Manager window on top.
Start Task — Starts up the RTSSrun graphical user interface.
End Task — Stops/unregisters the selected process or RTDLL.
RTX User’s Guide
16
RtxServer
The RtxServer handles RTSS output and enables the user to view the output in the RtxServeroutput window and/or log the output to a file. The RtxServer is an RTX service that starts upat boot time if RTX is set to run at boot time or at runtime when an RTSS application is runor from the RTX control panel. Since the RtxServer is a service, it can not be started up bydouble clicking on its icon.
The service can run in GUI mode or in non-GUI mode. The GUI is brought up by defaultwhen the first printf or RtPrintf in an RTSS application is encountered. The GUI can also bemanually brought up by double clicking on the RtxServer notification icon in the Taskbar’sStatus Area. The RtxServer notification icon is visible when the RtxServer is running anddisplays the state of the service and show error messages. Fatal error messages are areflagged with the notification icon and logged to the Event Viewer.
The RtxServer allows for the storing and viewing of RTSS output through the screen and logfile. When the GUI is exited, the display buffer is purged. Because logging is independent ofthe GUI, the logging will continue even if the GUI is exited. Some options for writing to thescreen are saving the screen buffer to a file, clearing the display, changing screen buffer sizeand font settings of the output. You can also write to a log file, clear it, change its path, andput a banner containing RTX version information and start time in it. You can use appendmode or clear mode for logging.
See the online help for additional information on using RtxServer.
Chapter 2: Using Software Developmen Tools
17
Using the RTX AppWizard in Microsoft Visual Studio 6.0
Use the RTX AppWizard in Microsoft Visual Studio 6.0 to create a project workspace for thedevelopment of RTX applications and dynamic link libraries. The RTX project workspacecontains four configurations: Win32 Release, Win32 Debug, RTSS Release, and RTSSDebug. The wizard sets the Project Settings for each configuration according to the programand project options selected from its dialogs. It can also provide a basic C programframework with which to work. This program framework can include RTX programelements, which contain C code to create RTX objects and demonstrate their use.
The topic explains how to:
Create a project and set options using the RTX AppWizard and then build an image (Win32or RTSS) or build a dynamic link library (RTDLL or Win32 DLL)
Run an image
� Register an RTDLL
Creating a Project and Setting Options
Use the procedure that follows to create an RTX project using the RTXAppWizard inMicrosoft Visual Studio.
To create an RTX project1. On the Visual Studio menu bar, select File | New.
2. On the Projects tab, select RTX AppWizard from the list box. The New dialog boxopens, as shown below.
57;$SS:L]DUG���1HZ�3URMHFWV�'LDORJ�%R[
3. On the right side of the dialog, complete the following fields:
Project name — Enter the name of the project.Location — Enter the directory in which to build the workspace.
RTX User’s Guide
18
Platforms — Select the platform for which RTX AppWizard will buildconfigurations (WCE emulation mode is not supported).
4. Click OK to save the settings.
5. Complete the steps of the RTX AppWizard by selecting the appropriate options in theRTX AppWizard dialog boxes. See the following instructions, Setting ProjectOptions and Setting Program Options.
Setting Project Options
57;$SS:L]DUG���6WHS���RI���'LDORJ�%R[
1. The RTX AppWizard sets the Project Settings in each configuration for compilingand linking programs. Choose whether to build an RTX application (default) or aDLL by clicking the labeled radio buttons.
2. RTX supports either UNICODE (default) or ASCII string types in RTSS programs.Select which type of string format to use.
3. Some programs need support for C run-time functions. If your project needs thissupport, select either the single-threaded library or the multi-threaded library. If anRTDLL needs C run-time support, you must use the multi-threaded library. Thedefault is no C run-time library support.
4. If these are all the options needed, click Finish. Otherwise, click Next to open thesecond dialog box, shown in the figure below.
Chapter 2: Using Software Developmen Tools
19
Setting Program Options
57;$SS:L]DUG���6WHS���RI���'LDORJ�%R[
1. The wizard can provide a basic C program framework by inserting some files into theproject. The framework consists of a C source file that contains basic C constructioncalls and a C header file that contains #include and #define statements. The default isNo program framework, just Set Project Setings. Select an option by clicking onthe appropriate radio button.
2. RTX program elements can be included in the C program framework. Theseprogramming elements are code segments that create each RTX object anddemonstrate its use. Areas in the element code that need to be customized by the userare indicated by "TO DO" comments. You can select more than one type ofprogramming element for a single project. The default option is that no programmingelements are to be included.
3. Click Back to return to the first dialog in order to modify or review selections.Otherwise, click Finish. The RTX AppWizard displays a New Project Informationconfirmation box, such as the one in the figure below, indicating the choices.
RTX User’s Guide
20
1HZ�3URMHFW�,QIRUPDWLRQ
4. Click OK. RTX AppWizard generates the RTX workspace and project according tothe options you selected.
Running an Image
After you have built your Win32 or RTSS image, you can run it from:
n A command prompt,
n Windows NT Explorer, or
n Visual Studio (See the procedure that follows for special instructions on changingVisual Studio settings for RTSS Debug and Release images. You do not need tochange any setting to run Win32 images.)
To run an RTSS image in Visual Studio
Use this procedure to run an RTSS image from within Visual Studio.Modify project settings for Win32 RTSS Release and Win32 RTSS Debug
1. Select Project | Settings | Debug tab.
2. In the Program Arguments field, copy the executable into the arguments sectionbox and then add any other arguments.
3. Replace the text in Executable for debug session with:
rtssrun.exe
4. Click OK to save the settings.
Run the RTSS image
5. Choose Build | Execute (or click the exclamation point on the toolbar).
Chapter 2: Using Software Developmen Tools
21
Registering an RTDLL
After you have built your RTDLL, you can register it using the RTSSrun utility.
Using Microsoft Visual Studio 6.0
This topic explains how to:
Set up Microsoft Visual Studio
Build and run Win32 images
Build and run RTSS images
� Build and register RTDLLs
Note: The RTX AppWizard utility provides an easy-to-use alternate for creating a projectworkspace for the development of RTX applications and dynamic link libraries
Note: Some projects created for Microsoft Developer Studio 5.0 will have /GZ specified as acompiler option. This option is incompatible with RTSS and Microsoft Visual Studio 6.0.Simply remove this option from your project settings in order to migrate a Developer Studio5.0 project to a Visual Studio 6.0 project. All the link options described in this topic forVisual Studio 6.0 are appropriate for Developer Studio 5.0 as well.
Setting up Microsoft Visual Studio
Use the procedure that follows to direct Microsoft Visual Studio to the RTX include andlibraries files.
To set up Microsoft Visual Studio1. On the Visual Studio Tools menu, choose Options and then choose the Directories
tab.
2. In the Show Directories For box, select the following file types and enter their pathsin the Directories box. The following assumes that it was installed with the defaultpaths. If you changed the default path during installation, specify that path below.
Include files — c:\program files\vci\rtxsdk\include
Library files — c:\program files\vci\rtxsdk\lib
3. Click OK to save the settings.
Building and Running Images (Win32 Environment)
Use the procedures that follow to build and run a Win32 image.
To build a Win32 imageCreate a new RTX Win32 project workspace1. On the File menu, choose New and then choose the Projects tab.
2. Choose Win32 Console Application, enter a name, and then click OK.
Specify the project settings
RTX User’s Guide
22
3. On the Project menu, choose Settings to open the Project Settings dialog box.
4. In the Settings For box, select All Configurations.
5. On the Link tab, add this library to Object/Library Modules:
rtapi_w32.lib
6. Click OK to save the settings.
To run a Win32 imageAfter you have built your Win32 image, you can run it from:
A command prompt,
Windows NT Explorer, or
� Visual Studio (you do not need to change any settings).
Building and Running Images (RTSS Environment)
Use the procedures that follow to build and run an RTSS image.
To build an RTSS imageCreate a new RTX RTSS project workspace1. On the File menu, choose New and then choose the Projects tab.
2. Select Win32 Console Application, enter a name, and then click OK.
Specify the project settings3. On the Project menu, choose Settings to open the Project Settings dialog box.
4. In the Settings For box, select either Win32Release or Win32Debug based on theversion you are building.
5. On the Link tab, delete all Project Options and replace them with one of thefollowing option sets.
1R�&�5XQ�7LPH�6XSSRUW��5HOHDVH Versionrtapi_rtss.lib rtx_rtss.lib /NODEFAULTLIB /INCREMENTAL:NO /PDB:NONE /NOLOGO /driver /align:0x20 /subsystem:native,4.00 /RELEASE /entry:_RtapiProcessEntry@8
�1R�&�5XQ�7LPH�6XSSRUW��'HEXJ Versionrtapi_rtss.lib rtx_rtss.lib /NODEFAULTLIB /INCREMENTAL:NO /PDB:NONE /NOLOGO /driver /align:0x20 /subsystem:native,4.00 /debug:notmapped /debugtype:both /entry:_RtapiProcessEntry@8
�6LQJOH�7KUHDGHG�&�5XQ�7LPH�6XSSRUW��5HOHDVH�9HUVLRQ startupCRT.obj RTXlibc.lib oldnames.lib rtapi_rtss.lib rtx_rtss.libw32_dll.lib /NODEFAULTLIB /INCREMENTAL:NO /PDB:NONE /NOLOGO /driver /align:0x20 /subsystem:native,4.00 /RELEASE /entry:_RtapiProcessEntryCRT@8
�6LQJOH�7KUHDGHG�&�5XQ�7LPH�6XSSRUW��'HEXJ�9HUVLRQ startupCRT.obj RTXlibc.lib oldnames.lib rtapi_rtss.lib rtx_rtss.libw32_dll.lib /NODEFAULTLIB /INCREMENTAL:NO /PDB:NONE /NOLOGO
Chapter 2: Using Software Developmen Tools
23
/driver /align:0x20 /subsystem:native,4.00 /debug:notmapped /debugtype:both /entry:_RtapiProcessEntryCRT@8
�0XOWL�7KUHDGHG�&�5XQ�7LPH�6XSSRUW��5HOHDVH�9HUVLRQ startupCRT.obj RTXlibcmt.lib oldnames.lib rtapi_rtss.lib rtx_rtss.libw32_dll.lib /NODEFAULTLIB /INCREMENTAL:NO /PDB:NONE /NOLOGO /driver /align:0x20 /subsystem:native,4.00 /RELEASE /entry:_RtapiProcessEntryCRT@8Multi-Threaded C Run-Time Support: Debug Version startupCRT.obj RTXlibcmt.lib oldnames.lib rtapi_rtss.lib rtx_rtss.lib32_dll.lib /NODEFAULTLIB /INCREMENTAL:NO /PDB:NONE /NOLOGO /driver /align:0x20 /subsystem:native,4.00 /debug:notmapped /debugtype:both /entry:_RtapiProcessEntryCRT@8
6. Change the file extension in the Output File Name field from exe to rtss.
7. Click OK to save the settings.
To run an RTSS imageAfter you have built your RTSS image, you can run it from:
A command prompt,
Windows NT Explorer, or
� Visual Studio (see the procedure that follows for instructions on changing Visual Studiosettings).
To run an RTSS image in Visual StudioUse the procedure that follows to run the image from within Visual Studio.
Specify the project settings1. On the Project menu, choose Settings to open the Project Settings dialog box, and
then choose the Debug tab.
2. Complete the following fields:
Settings For — Select either Win32 Release or Win32 Debug, based on the versionyou plan to run.
Executable for Debug Session — Enter the path to RTSSrun.exe. For example:c:\program files\vci\rtx\bin\rtssrun.exe
Program Arguments — Enter the path to your .rtss image. For example: c:\programfiles\microsoft visual studio\myprojects\rtsstest\release\rtsstest.rtss
3. Click OK to save the settings.
Run the RTSS image4. On the Build menu, choose Execute RTSSrun.exe.
Building and Registering RTDLLs
Use the procedures that follow to build and register an RTDLL.
To build an RTDLLCreate a new project workspace1. On the File menu, choose New and then choose the Projects tab.
RTX User’s Guide
24
2. Select Win32 Console Application, enter a name, and then click OK.
Specify the project settings3. On the Project menu, choose Settings to open the Project Settings dialog box.
4. In the Settings For box, select either Win32Release or Win32Debug, based on theversion you are building.
5. On the Link tab, delete all Project Options and replace them with one of thefollowing option sets.
Project Options on the Link Tab for an RTDLL
�1R�&�5XQ�7LPH�6XSSRUW��5HOHDVH�9HUVLRQ rtapi_rtss.lib rtx_rtss.lib startupDll.obj /NODEFAULTLIB /INCREMENTAL:NO /PDB:NONE /NOLOGO /driver /align:0x20 /subsystem:native,4.00 /RELEASE /entry:_RtapiDllEntry@8
�1R�&�5XQ�7LPH�6XSSRUW��'HEXJ�9HUVLRQ rtapi_rtss.lib rtx_rtss.lib startupDll.obj /NODEFAULTLIB /INCREMENTAL:NO /PDB:NONE /NOLOGO /driver /align:0x20 /subsystem:native,4.00 /debug:notmapped /debugtype:both /entry:_RtapiDllEntry@8
�&�5XQ�7LPH�6XSSRUW��5HOHDVH�9HUVLRQ�startupDllCRT.obj RTXlibcmt.lib oldnames.lib rtapi_rtss.lib rtx_rtss.libw32_dll.lib /NODEFAULTLIB /INCREMENTAL:NO /PDB:NONE /NOLOGO /driver /align:0x20 /subsystem:native,4.00 /RELEASE /entry:_RtapiDllEntryCRT@8
�&�5XQ�7LPH�6XSSRUW��'HEXJ�9HUVLRQ startupDllCRT.obj RTXlibcmt.lib oldnames.lib rtapi_rtss.lib rtx_rtss.libw32_dll.lib /NODEFAULTLIB /INCREMENTAL:NO /PDB:NONE /NOLOGO /driver /align:0x20 /subsystem:native,4.00 /debug:notmapped /debugtype:both /entry:_RtapiDllEntryCRT@8
6. Change the file extension in the Output File Name field from exe to rtdll.
7. Click OK to save the settings.
To register an RTDLLAfter you have built your RTDLL, you can register it using the RTSSrun utility:
RTSSrun /d <filename>.[rtdll] [/s]
For further details, see RTSSrun Utility on page 9.
Chapter 2: Using Software Developmen Tools
25
Creating RTX Dynamic Link Libraries
This topic explains how to:
Build an RTDLL — This type of real-time dynamic link library is an RTSS object whichcan be dynamically loaded and unloaded using the LoadLibrary and FreeLibrary calls.
Build an RTSS DLL — This type of real-time dynamic link library is an RTX process thatcan be loaded either at boot time or through a call to Windows NT or Windows 2000 fromwithin a C/C++ program.
For further details about the two types of real-time DLLs, see Using RTX Dynamic LinkLibraries on page 57.
Building an RTDLL
There are two ways to build RTDLLs. You can create them through:
Appropriate compile and link options in a Microsoft Visual Studio project. To build anRTDLL using this method, follow the applicable procedures in Using the RTX AppWizard inMicrosoft Visual Studio 6.0 on page 17 or Using Microsoft Visual Studio 6.0 on page 21.
� Command line invocation of nmake using special rules. This method is illustrated below.
Building an RTDLL through command line invocation
The following is an example of an nmake input file which will build an RTDLL and Win32DLL from a single source file, thandler.c.
!include <rtx.mak>
all: thandler.dll thankler.rtdllclean: -del thandler.obj thandler.dll thandler.rtdll
Building an RTSS DLL
You create an RTSS DLL with a 'main' entry point that performs any required initializationroutines. The two required files are listed below (see the RTSS DLL Code Example in Codeand File Examples in Appendix A for an example of each file).
dll.c — Defines the source call for the library
dll.def — Defines the DLL name and exported functions
Once executed in the RTSS environment, RTSS programs can use the RTSS DLL. Note thatthe entry point into the RTSS DLL for starting the process is MAIN.
RTSS DLL Makefile Example
The following example shows a typical RTSS DLL makefile for dll.c.
NODEBUG = 1
!include <rtx.mak>
RTX User’s Guide
26
all: dll.rtss
dll.rtss: dll.obj lib -nodefaultlib -machine:$(CPU) -out:dll.lib -def:dll.def dll.obj link $(rtsslflags) -out:dll.rtss dll.exp dll.obj $(rtsslibs) del dll.exp
clean: -del *.rtss -del *.obj -del *.exe -del dll.lib
Debugging an RTX Program
Each makefile should include the master makefile, rtx.mak, which builds programs with fulldebugging information in a format compatible with Microsoft’s WinDbg.exe. See theMakefile Sample in Code and File Examples in Appendix A.
This topic explains how to:
Exclude debugging information from a release version
Use Microsoft’s WinDbg 4.0 with RTSS
� Use Microsoft’s WinDbg 5.0 with RTSS
Excluding debugging information
You can exclude full debugging information from your release version by using theprocedure that follows.
To exclude debugging information from release version filesAt a command prompt, enter:
Set NODEBUG=1 nmake -nologo -f MyProgram.makorAdd NODEBUG=1 to MyProgram.mak (as illustrated in the Makefile Sample forsrtm.mak in Code and File Examples)
Using Microsoft’s WinDbg 4.0 with RTSSIn order to debug using Microsoft’s WinDbg 4.0, you need two systems: a host system onwhich to run WinDbg and a target system on which to run your driver. WinDbg 4.0 candebug Windows NT systems only. The procedures that follow show how to:
Prepare the host and target systems for WinDbg
Prepare the program for debugging
Set up the WinDbg environment on the host system
� Start the debug session
Chapter 2: Using Software Developmen Tools
27
To prepare the host and target systems for WinDbgConnect the host system to the target system1. Connect the two systems by inserting a null modem cable into the corresponding
serial ports on each (COM1 or COM2).
2. Test the connection using an available serial communications package (such asterminal.exe) to ensure that data is transmitted and received on both sides. For moreinformation on null modem cables and testing a serial connection, refer to the sectionon using a serial cable for kernel debugging in the Microsoft Windows NT DDKdocumentation.
Set up the target system3. Ensure that the target system has free builds of Windows NT and RTSS installed. If
any of one of these is not installed on the target, install it according to its installationinstructions.
Modify the boot.ini file to enable kernel debugging4. Change the attributes of boot.ini to permit editing.
5. Open the file in an editor and locate the line under the "[operating systems]" sectionthat contains the operating system on which you run. Modify this line to contain oneof the following lines of information:
/DEBUG [ /BAUDRATE=<baud rate> ]
/DEBUGPORT=<com port> [ /BAUDRATE=<baud rate> ]
where com port = Serial port through which the host and target are connected. baudrate = Highest rate used by the machines.
Note: Using /DEBUG assumes that the default serial port is COM2. Using/DEBUGPORT allows you to specify which serial port to use. If baud rate is notgiven, the system uses a default rate. For example, the line "multi (0) disk (0) rdisk(0) partition(1) \WINNT="Windows NT Version 4.00" /DEBUGPORT=COM2"/BAUDRATE=19200" sets the communications port to COM2 and the baud rate to19200. For more information on using these switches, refer to the section onenabling kernel debugging on the target in the Microsoft Windows NT DDKdocumentation.
6. Save the file and exit the editor.
7. Reset the file attributes in boot.ini to their original states: > attrib +r +s +h boot.ini
8. Reboot the target system.
To prepare the program for debugging1. At the start of the source code, insert a hard break instruction: _asm int 3
2. To include debug information in the program, perform one of these steps:
3. In the program’s makefile, comment the line NODEBUG=1 (if it is there).
4. At a command prompt, enter: Set NODEBUG=
5. Run NMAKE with your program’s makefile to create an .rtss file. For example, thefollowing line creates the file srtm.rtss: nmake -f srtm.mak
RTX User’s Guide
28
6. If the program was built on the host system, copy the .rtss file into a workingdirectory on the target system.
7. Copy the symbol file (.rtss) to the %SystemRoot%\symbols directory on the hostsystem. For example, at a command prompt, enter: >copy srtm.rtss c:\winnt\symbols
8. On the host system, ensure that the following files are in their correct locations. Ifthey are not present, copy them from your RTX installation disks.
9. RTX debug information files in %SystemRoot%\symbols\ rtx_halext.dbg inSystemRoot%\symbols\ rtx_rtss.dbg in %SystemRoot%\symbols\ hal.dbg in%SystemRoot%\symbols\
To set up the WinDbg 4.0 environment on the host system1. On the Start menu, choose Programs | Win32 SDK Tools | WinDbg.
2. On the File menu, open the program’s source file.
3. On the View | Options tab, set the following options.
Workspace Tab — Set the Logging option, if desired.
Symbols Tab — In the Symbol Search Path text box, enter the location of the .rtssfile (this is required only if the file is not in the %SystemRoot%\symbolsdirectory). In the Load Time box, select the Defer radio button.
Kernel Debugger Tab — Select the Enable Kernel Debugger check box. UnderCommunications, ensure that the values for Baud, Port, Cache, and Platform arecorrect.
Debugger Tab — Select the desired Radix and Registers settings and other desiredoptions. This set of options is recommended: Ignore Case, Disconnect on Exit, Goon Thread Terminate, Debug Child Process, Verbose Output, and AbbreviatedContext.
4. Click OK to save the options.
To start the debug session1. On the host Run menu, choose Go (or press F5).
2. On the target system, run the application. For example, at a command prompt, enter:> RTSSrun srtm
The following message appears in the WinDbg command window.
Thread Create: Process 0 Thread 0Kernel debugger waiting to connect on com2 @ 19200 baudKernel Debugger connection established on com2 @ 19200 baudKernel Version 1381 Free loaded @ 0x80100000Module load: NT (symbols loaded)Hard coded breakpoint hit
3. At this point, the target system will not respond until WinDbg receives a "GO"command. Add breakpoints, as desired.
4. To continue the debugging session, choose Go on the Run menu (or press F5). Referto the Microsoft WinDbg documentation for details on using WinDbg.
Chapter 2: Using Software Developmen Tools
29
5. To close the debugging session, cancel from the target system program and then exitfrom WinDbg on the host system.
Using Microsoft’s WinDbg 5.0 with RTSS
Microsoft’s WinDbg 5.0 can debug both Windows NT and Windows 2000 systems. In orderto debug using Microsoft’s WinDbg 5.0, you need to install WinDbg 5.0, i.e., the Windows2000 debugger, on your host system. Your host and target systems can be either a Windows2000 or Windows NT machine. The procedures for using WinDbg 5.0 with RTSS are thesame as those described above for WinDbg 4.0.
Testing an RTX Program with Shutdown Handlers
This topic describes the:
Sample shutdown program that you use to test an RTX program with shutdown handlers byforcing a Windows NT stop
� Gencrash driver which demonstrates RTSS shutdown management
Shutdown Program
Use the shutdown program to see a demonstration of RTSS shutdown handlers. You mustfirst build this program using the RTX makefile. This program attaches a shutdown handler toa process and generates a continuous tone. If a Windows NT stop or system shutdown occursduring this time, then the shutdown handler prints out a message and sleeps for 10 seconds.The tone will then stop.
Note: The message is visible only for unexpected NT stops (RT_SHUTDOWN_NT_STOP).For an orderly NT shutdown (RT_SHUTDOWN_NT_SYSTEM_SHUTDOWN), themessage is not visible.
Usage
RTSSrun "c:\program files\vci\rtx\bin\samples\shutdown\shutdown"
You can view the shutdown process or stop the shutdown program and its tone withoutshutting down Windows NT by using RTSSkill:
7R�YLHZ�WKH�VKXWGRZQSURFHVV
5766NLOO
7R�NLOO�WKH�VKXWGRZQSURFHVV�Q
5766NLOO�Q
Optionally, you can call the gencrash driver discussed next.
Gencrash Driver
Use the gencrash driver to see a demonstration of RTSS shutdown management.
The gencrash driver provides a pop-up warning window and then bug checks (i.e., STOP 0)the Windows NT system to demonstrate RTSS shutdown management.
RTX User’s Guide
30
Usage
net start gencrash
Caution: Please close all applications before using gencrash. A FAT file system willgenerally require checking after a Windows NT stop.
Using the RTX Properties Contol Panel
You use the RTX Properties control panel to set configurable RTX registry parameters. Itcontains four tabs: About, Settings, Debug, and Control.
To set RTX properties1. In the system Control Panel, double-click the RTX Settings icon to open the RTX
Properties control panel.
2. Specify the settings on each tab (see below) and then click Apply.
3. When finished, reboot your system to apply the change(s).
About tab
Displays RTX product and version information.
Settings tab
Startup — Specifies whether RTX is started at system Boot, or Demand. If set to Demand,RTX does not start until an RTSS process is run. If set to Boot, you cannot start or stop RTXmanually (see the Control tab section below).
Starvation Time Out — Controls the watchdog timer which monitors threads. If enabled,RTX stops the offending thread, issues a popup exception message, and then allows WindowsNT to resume normal operation. See Starvation Management on page 70.
Free Stack on Terminate Thread — Controls whether RTSS frees the memory used for anRTSS thread's stack when the thread is terminated via TerminateThread. When selected,RTSS frees the memory.
HAL Timer Period — Controls the real-time HAL extension timer period. When usingRtSetTimer and RtSetTimerRelative, the value must be a multiple of the HAL extensiontimer period.
Time Quantum — The value a thread will be given for its default time quantum. A value of0 (zero) means run to completion. See RtSetThreadTimeQuantum andRtGetThreadTimeQuantum in the RTX 5.0 Reference Guide.
RTSS Process Slots — The number of RTSS process slots that can be run on your system.Minimum value is 10, maximum 999.
Debug tab
Chapter 2: Using Software Developmen Tools
31
Process Exception Disposition — Controls the disposition of faulting RTSS processes.When Freeze the Faulting Process is selected, you can debug the process and then unload itusing RTSSkill.
Enter Kernel Debugger on RTSS Exception — Controls whether the RTX exceptionhandler initiates an interrupt to the debugger when a fault is raised. Caution: If selected whenno debugger is available, RTX raises a double fault.
Kernel Debugger — Specifies which debugger is used, Microsoft's WinDbg or NuMega'sSoftICE. See Debugging an RTX Program on page 26.
Control tab
Provides buttons for starting and stopping RTX. These are available only when the RTXStartup option (on the Settings tab) is set to Demand.
RTX User’s Guide
32
33
Chapter 3
Using the RTX FunctionalityThis chapter presents the RTX functionality along with references to real-time code examplesthat demonstrate the use of RTX functions (calls) and illustrates the implementation ofvarious real-time programming techniques. It also highlights key areas to consider, for boththe RTSS and Win32 environments, while developing your programs.
This chapter contains:
n Process and Thread Management
Processes and ThreadsSystem Memory ManagementClocks and Timers
n Interprocess Communication
Object NamesShared MemorySemaphoresEvent ObjectsMutex Objects
n Device Management
InterruptsPort IOPhysical Memory MappingContiguous Memory MappingBus IO
n File IO
RTX User’s Guide
34
Process and Thread Management
Processes and Threads
A process comprises an address space, object handles, and one or more paths of execution(threads). Threads are used, for example, to respond to interrupts and handle asynchronousprocess-related events in thread context. RTSS processes and threads function much like theirWin32 counterparts. RTSS and Win32 processes and threads can access processes andthreads only within their own environment.
This topic discusses:
Using_Processes
Using_Threads
� Thread_Priorities
Using Processes
The sections that follow describe how processes run in the RTSS and Win32 environments.
Processes in the RTSS Environment
A process running in the RTSS environment consists of a set of handles to objects, processaddress space, at least one thread, and an executable. When a process is created, RTSSperforms the following tasks:
Loads the executable as a driver
Allocates process heap from the non-paged pool
� Creates the primary thread
A process can be started by either one of these methods:
Loading it as a device driver during system boot (using the RTSSrun /b utility)
Running the RTSS executable from the command line
� Starting the RTSS process from Win32 applications
A process exits under one of these conditions:
The last thread has exited
One thread calls ExitProcess
� The process is killed with the RTSSkill utility or the RTSS Task Manager
The maximum number of processes that can exist concurrently in the RTSS environment isequal to the number of RTSS process slots in the registry (the default is 10).
Processes in the Win32 Environment
A process running in the Win32 environment starts interacting with RTX when it makes an
Chapter 3: Using Using the RTX Functionality
35
RTAPI call. RTX then may allocate resources for this process, alter its priorities, and performother operations related to its Win32 process status. The number of Win32 processes that caninteract with RTX is dynamic; it depends on your system’s configuration and resources.
Using Threads
The CreateThread function creates either an RTSS or a Win32 thread, depending on thecurrent execution environment of the process. You can specify the stack size of subsequentlycreated threads of that process using CreateThread. The returned handle and thread ID arevalid only in the CreateThread caller’s environment. For instance, a Win32 process cannotmanipulate the priority of an RTSS thread because the handle for the thread is valid only inthe RTSS environment. You can, however, use the RTX Inter-Process Communication (IPC)mechanisms (such as mutex objects, semaphores, events, and shared memory) to synchronizeand communicate between Win32 and RTSS processes and threads.
Timer and Interrupt Objects
Timer and interrupt objects derive from the threads; therefore, the handles for these objectsare valid only in their own (Win32 or RTSS) environment. Similarly, these objects can bemanipulated only by processes in their own environment.
RTSS Environment
An RTSS thread is the unit of execution in the RTSS environment. A ready-to-run RTSSthread is scheduled before all Windows NT and Windows 2000 threads. An RTSS thread runsuntil it gives up the CPU. A thread gives up the CPU when it:
Waits for a synchronization object
Lowers its own priority or raises another thread’s priority
Suspends itself
Returns from the timer or interrupt handler (applicable to timer and interrupt threads) routines
Calls Sleep with an argument of 0
Recevives a notification that a time quantum is set
� Is interrupted by a higher priority
The initial thread of a process has an 8 KB stack.
Thread Priorities
The sections that follow describe the priorities of threads in the RTSS and Win32environments.
RTSS Environment
The RTSS environment has no distinct priority classes, so the threads of all RTSS processescompete for CPU using the thread priority only. An RTSS thread runs at one of 128 distinctpriority levels. Threads execute in priority order and in "first in, first out" order within anysingle priority. If a time quantum is set to 0, the thread will run to completion. If the timequantum is set to another value, the thread will run for the specified time and then give up theCPU to another thread with the same priority. RTSS scheduling implements a priorityinversion and deferred priority demotion mechanism to eliminate unbounded priority
RTX User’s Guide
36
inversion.
For example, RTSS mutex objects support a level-one priority promoting mechanism. If ahigher priority thread calls WFSO on a mutex object that is owned by a lower priority thread,the priority of the mutex owner is promoted to the same priority as the higher priority thread.An attempt to demote the priority of a mutex owner thread will be deferred until the threadreleases the mutex.
Win32 Environment
A Win32 RTX program starts execution in the real-time priority class. RTX provides amapping between RTSS and Win32 subsystem priorities. However, Win32 scheduling mayexhibit unbounded priority inversion.
Table 1, RTSS to Win32 Thread Priority Mapping, shows how RTSS symbolic prioritynames translate to requests for a particular Windows NT or Windows 2000 priority whenRtSetThreadPriority is called by a Win32 program.
Table 1. RTSS to Win32 Thread Priority Mapping
5766�6\PEROLF�3ULRULW\1DPH
57669DOXH
:LQGRZV�17���:LQGRZV�����6\PEROLF�3ULRULW\�1DPH�IRU�5HDO�7LPH�3ULRULW\�&ODVV
:LQ��9DOXH
57B35,25,7<B0,1 � 7+5($'B35,25,7<B,'/( ��
57B35,25,7<B0,1���� � 7+5($'B35,25,7<B/2:(67 ��
57B35,25,7<B0,1���� � 7+5($'B35,25,7<B%(/2:B1250$/ ��
57B35,25,7<B0,1���� � 7+5($'B35,25,7<B1250$/ ��
57B35,25,7<B0,1���� � 7+5($'B35,25,7<B$%29(B1250$/ ��
57B35,25,7<B0,1������������ ������� 7+5($'B35,25,7<B+,*+(67 ��
57B35,25,7<B0$; ��� 7+5($'B35,25,7<B7,0(B&5,7,&$/ ��
Table 1 shows, for example, that RtSetThreadPriority(Thread, RT_PRIORITY_MIN+1)will result in a call to SetThreadPriority(Thread, THREAD_PRIORITY_LOWEST) by theWin32 version of the RTX interfaces.
Any value from RT_PRIORITY_MIN+5 to RT_PRIORITY_MIN+126 will set the thread atTHREAD_PRIORITY_HIGHEST and RT_PRIORITY_MAX will result inTHREAD_PRIORITY_TIME_CRITICAL priority. These mappings are fixed and designedto preserve relative ordering among thread priorities.
If a Win32 program calls RtGetThreadPriority, the real-time priority specified in the call toRtSetThreadPriority returns. There are some restrictions, however. The most likely sourceof confusion is when calls to RtSetThreadPriority and SetThreadPriority are mixed. Thelibrary may not always understand the RTSS priority when a duplicated thread handle is used,and it will return RT_PRIORITY_MIN+5 instead of RT_PRIORITY_MIN+6 throughRT_PRIORITY_MIN+126. Threads that set and get their own RTSS priorities (such asspecifying the thread with GetCurrentThread), will always get the RTSS priority that wasset.
Win32 programs should use the Rt priority calls for the Win32 thread to claim other than thelowest RTSS scheduling priority when waiting on an RTSS synchronization object. Forinstance, a Win32 thread with an RTSS priority of RT_PRIORITY_MAX will own a mutex
Chapter 3: Using Using the RTX Functionality
37
before an RTSS thread waiting for the same mutex with a priority less thanRT_PRIORITY_MAX.
Table 2, Win32 to RTSS Thread Priority Mapping, shows what callers of the Win32 "set" and"get" thread priority calls should expect in the RTSS environment. This table describes theinverse of the mapping shown in Table 1.
Table 2. Win32 to RTSS Thread Priority Mapping
:LQGRZV�17���:LQGRZV�����6\PEROLF�3ULRULW\�1DPH�IRU�5HDO�7LPH�3ULRULW\�&ODVV
9DOXH 5766�6\PEROLF3ULRULW\�1DPH
9DOXH
7+5($'B35,25,7<B,'/( �� 57B35,25,7<B0,1 �
7+5($'B35,25,7<B/2:(67 �� 57B35,25,7<B0,1���� �
7+5($'B35,25,7<B%(/2:B1250$/ �� 57B35,25,7<B0,1���� �
7+5($'B35,25,7<B1250$/ �� 57B35,25,7<B0,1���� �
7+5($'B35,25,7<B$%29(B1250$/ �� 57B35,25,7<B0,1���� �
7+5($'B35,25,7<B+,*+(67 �� 57B35,25,7<B0,1���� �
7+5($'B35,25,7<B7,0(B&5,7,&$/ �� 57B35,25,7<B0$; ���
There are no additional priorities between THREAD_PRIORITY_IDLE andTHREAD_PRIORITY_HIGHEST. If you need finer grain priorities, you should use theRTSS priority spectrum instead. Just as in Win32, this value specifies a thread priority that ishigher than all other priorities.
Win32 Environment Programming Considerations
WIn32 RTX program starts execution in the normal priority class, then calls the firstRtGetThreadPriority, RtSetThreadPriority, or any other real-time priority function. This is thedesired behavior for most applications because it gives the process the best possible real-timeperformance. This does, however, cause problems when the Win32 threads have GUIcomponents. When a thread in the REALTIME_PRIORITY_CLASS interacts with the GUIside of Windows NT and Windows 2000, slowdowns and lock-ups occur. You can avoid thisproblem when writing a Win32 application that has a GUI component (and links tortapi_win32.lib), by making sure that your program first makes this call: SetPriorityClass( GetCurrentProcess(), NORMAL_PRIORITY_CLASS)
System Memory Management
This topic discusses:
System memory allocation
� System memory locking
System Memory Allocation
A process frequently must allocate additional memory to perform its operations. The RTXmemory allocation routine always allocates memory that is locked, thus eliminating anychance of latencies due to page faults.
Memory Allocation APIs
RTX User’s Guide
38
The following APIs are available to access RTX system memory allocation services:
RtAllocateLockedMemory allocates memory that is backed by physical memory andlocked, then maps the memory into the virtual address space of the process.
RtFreeLockedMemory frees a previously allocated locked memory region.
RTSS and Win32 Programming Considerations
Locked memory is always allocated from a non-paged pool of memory that is maintained byWindows NT and Windows 2000. This pool of memory is relatively small and is rapidlyfragmented by the allocations of other drivers and subsystems in Windows NT and Windows2000 shortly after system boot. To avoid failure of large allocations, you should minimizetheir use and/or ensure that they are accomplished shortly after system boot.
Programming Example (RTX Locked Memory Allocation Calls)
See the RTX Locked Memory Allocation Calls Programming Example in Code and FileExamples in Appendix A. It demonstrates the use of RTX locked memory allocation calls.
System Memory Locking
To prevent page faults, and hence unpredictable delays in critical sections of code, real-timeapplications need to lock data and code in memory, including code and data in the operatingsystem itself.
Process Locking APIs
The following APIs are available to access RTX process memory locking services:
RtLockProcess locks all pageable sections of a process into physical memory.
RtUnlockProcess unlocks sections of a process’s virtual address space previously lockedinto physical memory.
RtCommitLockProcessHeap commits and locks the process’s heap.
RtCommitLockHeap commits and locks the specified heap.
RtCommitLockStack commits and locks the specified stack.
RTSS Environment Programming ConsiderationsBy default, all process and memory objects in the RTSS environment are locked into physicalmemory to avoid page faults in RTSS processes. The Rt*Lock (Process, Heap, Stack)functions will always complete with success in the RTSS environment but will perform noactual operations.
Win32 Environment Programming ConsiderationsUnless explicitly locked into physical memory, all Windows NT and Windows 2000processes and services are paged. In the Win32 environment, the RtLockProcess functionshould be utilized to prevent your real-time process from incurring page faults.
Chapter 3: Using Using the RTX Functionality
39
Programming Example (RTX Process Memory Locking Calls)
See the RTX Process Memory Locking Calls Programming Example in Code and FileExamples in Appendix A. It demonstrates the use of RTX process memory locking calls.
Kernel Locking APIs
The following APIs are available to access RTX kernel memory locking services:
RtLockKernel locks pageable sections of the Windows NT and Windows 2000 kernelinto physical memory.
RtUnlockKernel unlocks sections of the Windows NT and Wndows 2000 kernelpreviously locked into physical memory.
RTSS Environment Programming ConsiderationsBy default, all processes and memory objects in the RTSS environment are locked intophysical memory.
Win32 Environment Programming ConsiderationsCertain Windows NT operating system components are paged, including most of the kerneland the Win32 subsystem. In order to prevent delays of your real-time processes due tokernel page faults, use the RtLockKernel function.
Windows` NT device drivers geneˆ ally do not page; device drivers loaded at boot timenever page. In order to make drivers pageable by the system, the developer of that drivermust carefully structure the driver and manually mark the code sections that are to be paged.Given the complexity, f˘ w drivers are structuˆ ˘ d in this way.
Locking the Windows NT or Windows 2000 kernel and processes reduces the pool ofavailable physical memory. This can have a detrimental effect on the performance of non-real-time system operations. Adequate memory should be included in any system toaccommodate the desired performance of any non-real-time operations. For information onnon-paged pool size, go the Microsoft Knowledge Base or MSDN Web site.
Programming Example (RTX Kernel Memory Locking Calls)See the RTX Kernel Memory Locking Calls Programming Example in Code and FileExamples in Appendix A. It demonstrates the use of RTX kernel memory locking calls.
See Also
Contiguous Memory Management
RTX User’s Guide
40
Clocks and Timers
Real-time systems require a number of operating system timing services. The operatingsystem must be able to keep an accurate accounting of the passage of time, schedule threadsat precise times, and suspend threads for precise intervals.
The RTX clock and timer facilities provide the services necessary for threads to performperiodic tasks that correspond with the external passage of time.
This topic discusses:
Clock services
Timer services
� Sleep services
Clock Services
The RTX clocks are counters of specified intervals that measure the passage of time.
APIs
The following APIs are available to access RTX clock services:
RtGetClockTime delivers the current value of the specified clock.
RtSetClockTime sets the value of the specified clock.
RtGetClockResolution delivers the resolution of the specified clock.
RtGetClockTimerPeriod delivers the minimum timer period for the specified clock.
The clock values are delivered and set in 100ns units (ticks) and are reported as the number ofticks since 12:00 AM January 1, 1601.
Clock Types
The RTX clocks, available in the Win32 and RTSS environments, are:
CLOCK_1 (alias CLOCK_SYSTEM) — CLOCK_1 services are provided by the real-timeHAL extension and have a resolution of 1 ms. Threads in both the Win32 and RTSSenvironments may schedule timers with periods in increments of ´ ms on this clock.
CLOCK_2 (alias CLOCK_FASTEST) — CLOCK_2 services are provided by the real-timeHAL extension and have a resolution of 1 µS. The period for timers scheduled on this clockis variable and can be set to 100, 200, 500, or 1000 µS.
You can set the HAL extension timer period using the RTX Settings control panel.
Relationship to Win32 Clocks
The RTX clocks are updated by services provided in the real-time HAL extension. The RTXclocks are synchronized with the RTX timer services. However, the RTX clocks are notsynchronized with either the Windows NT or Windows 2000 system clock or the battery-backed time-of-day clock.
Chapter 3: Using Using the RTX Functionality
41
RTX and Windows NT / Windows 2000 Clock Accuracy (UP Systems Only)
The interval timer hardware (8254 based) on standard PCs cannot be programmed to run at aneven division of seconds (the fundamental interval period is 838.095344 nanoseconds). Thismeans that the actual timer period is always somewhat different from the specified HALextension timer period (the HalTimerPeriod setting in the registry).
In addition, the interval timer is used to update the clock and every interval tick adds a fixedtime increment to the clock. Windows NT and Windows 2000 maintain an internal timeincrement resolution of 0.1 microseconds, which leads to an accumulation of rounding errorsand results in a small clock drift relative to the "true" time-of-day. Because of this drift,Windows NT and Windows 2000 periodically read the CMOS time-of-day clock on the PCand applies a drift correction.
The RTX clock also has drift, but at a different rate from the Windows NT and Windows2000 clocks. The RTX clock is designed to run at a rate that maintains synchronization withthe specified timer period (that is, the timer is known to expire at fixed clock times). Thisallows a straightforward calculation of timer expiration values and timer response latencies.
The table that follows provides the actual timer periods and associated clock drift rates for theeach of the possible timer periods.
Note: This does not apply to MP systems because they work on different processors.
6SHFLILHG�7LPHU3HULRG
$FWXDO�7LPHU�3HULRG :LQGRZV�17��:LQGRZV�����&ORFN�'ULIW
57;�&ORFN�'ULIW
�����6 �����������6 ���������� ���������
�����6 ������������6 ���������� ����������
�����6 ������������6 ���������� ���������
������6 �������������6 ���������� ����������
General Programming Considerations: The RTX clock should not be used as a time-of-day clock, unless the application is aware of these drift issues.
Timer Services
An RTX Timer is an implicit handling thread that receives notification from RTSS of a timerexpiration and calls the handling routine specified when the timer was created.
Timers are associated with a clock in the system—against which its expiration is measured—when it is created. A timer begins to count down to its expiration after having been set. Oncethe timer has expired and the handling routine returns, the timer can be automaticallyrearmed. Timers that have their repeat interval set to zero execute their handling routine onlyonce and are referred to as "one-shot" timers. Timers that have their repeat interval set to avalid value will execute their handling routine on an ongoing periodic basis and are referredto as "repeat" or "interval" timers.
APIs
The following APIs are available to access RTX timer services:
RtCreateTimer creates a timer associated with a specified clock.
RTX User’s Guide
42
RtDeleteTimer deletes a previously created timer.
RtCancelTimer cancels the expiration of the specified timer.
RtSetTimer sets the absolute expiration time and repeat interval of the specified timer.
RtSetTimerRelative sets the relative expiration time and repeat interval of the specifiedtimer.
Relationship to Windows NT Timers
RTX timers are not synchronization objects which means threads cannot wait for singleobjects with an RTX timer handle. This is in contrast to the Windows NT waitable timer,which is an object on which a thread can wait, or against which a thread can receivenotification.
Win32 and RTSS Programming Considerations
If your application needs to inform other threads of a timer expiration, you should use theappropriate notification object in the handling routine to indicate the event.
Sleep Services
The sleep services let you suspend the current thread for a specified period of time.
APIs
The following APIs are available to access RTX sleep services:
Sleep suspends the current thread for the specified number of milliseconds.
RtSleepFt suspends the current thread for the specified period of time in 100 nanosecondunits.
Programming Considerations
RtSleepFt is not supported for use within a Win32 timer thread. The rounding policy ontimer expirations including timers, wait functions, and sleep functions is to truncate thespecified interval down to the timer tick count. If the count is zero, then the count is set toone.
Programming Example (RTX Timer and Sleep Calls)
See RTX Timer and Sleep Calls Programming Example in Code and File Examples inAppendix A. It demonstrates the use of RTX timer and sleep calls.
Chapter 3: Using Using the RTX Functionality
43
Inter-Process Communication
Object Names
Named objects provide an easy way for processes to share object handles. The name specifiedby the creating process is limited to RTX_MAX_PATH characters, and can include anycharacter except the backslash path-separator character (\). Once a process has created anamed event, mutex, semaphore, or shared memory object, other processes can use the nameto call the appropriate function (RtOpenEvent, RtOpenMutex, RtOpenSemaphore, orRtOpenSharedMemory) to open a handle to the object. Name comparison is case-sensitive.
The names of event, mutex, semaphore, and shared-memory objects share the same namespace. If you specify a name that is in use by an object of another type when creating anobject, the function succeeds, but GetLastError returns ERROR_ALREADY_EXISTS.Therefore, when creating named objects, use unique names and be sure to check functionreturn values for duplicate-name errors.
For example, if the name specified in a call to RtCreateMutex matches the name of anexisting mutex object, the function returns a handle of the existing object. In this case, the callto RtCreateMutex is equivalent to a call to RtOpenMutex. Having multiple processes useRtCreateMutex for the same mutex is therefore equivalent to having one process that callsRtCreateMutex while the other processes call RtOpenMutex, except that it eliminates theneed to ensure that the creating process is started first. When using this technique for mutexobjects, however, none of the calling processes should request immediate ownership of themutex. If multiple processes do request immediate ownership, it can be difficult to predictwhich process actually gets the initial ownership.
Shared Memory
The RTSS shared memory object is a region of non-paged physical memory that can bemapped into the virtual address space of a process. When a shared memory object has aname, additional processes may map the region of memory. A shared memory object isaccessed with both a handle and a virtual address. In order for a process to completely end itsaccess to a shared memory object it must close the handle. When all processes end theiraccess to a shared memory object, the following occur:
The memory region is returned to the pool of non-paged kernel memory.
� The object ceases to exist.
Inter-Process Communication via Shared Memory
RTSS shared memory objects allow you to share blocks of data among multiple processes,including RTSS processes and Win32 processes. To do this, a thread in each process musthave its own process-relative handle to a single RTSS shared memory object and its ownprocess-relative pointer to a location where the virtual address of the mapping will be stored.These handles and pointers can be obtained by calling either RtCreateSharedMemory orRtOpenSharedMemory.
Using RtCreateSharedMemory
In order for several processes to use a shared memory object, the object must be first created
RTX User’s Guide
44
using RtCreateSharedMemory. Other processes can then use the shared memory object’sgiven name to map the shared memory object. RtCreateSharedMemory returns a handleand sets a location to the base address of the shared memory.
RtCreateSharedMemory fails if the amount of memory requested cannot be allocated or ifthe named shared memory object already exists. When RtCreateSharedMemory fails, nomemory is mapped and no handles are returned. RtCreateSharedMemory does not defaultto RtOpenSharedMemory if a shared memory object of the same name already exists. Onlyone process can successfully create the shared memory object.
Using RtOpenSharedMemory
RtOpenSharedMemory maps an already created shared memory object. After the sharedmemory object has been created by a process, additional processes may map the sharedmemory into their address spaces by calling RtOpenSharedMemory.RtOpenSharedMemory will fail if the named shared memory object does not exist.
RtOpenSharedMemory returns a handle to the shared memory object and sets a location tothe base address of the shared memory. When a process is finished with the shared memory itshould close the handle to the shared memory object.
Environments
The RTSS shared memory object is always maintained in the RTSS environment. However,Win32 processes may create and open RTSS shared memory objects.
The RTSS shared memory object is its own named object. The RtCreateSharedMemoryand RtOpenSharedMemory calls implicitly map the shared memory; this eliminates theexplicit Win32 call to the MapViewOfFile call. When the shared memory object is created,RTSS backs the shared memory object with non-paged memory.
Semaphores
The RTSS semaphore object is a synchronization object that maintains a count between zeroand a specified maximum value. The count is decreased by one each time a thread completesa wait for the semaphore object; the count is increased by a variable amount at the semaphorerelease. When the count reaches zero, the semaphore object’s state is no longer signaled andno more threads can complete a wait on the semaphore object until some thread increases thecount.
Like usual semaphore objects, the RTSS semaphore objects are used for resource counting.They give a thread the ability to query the number of resources available; if one or moreresources are available, the count of available resources is decreased. RTSS semaphoresperform this test-and-set operation atomically; that is, when you request a resource from anRTSS semaphore, the operating system checks whether the resource is available anddecrements the count of available resources without letting another thread interfere. Onlyafter the resource count has been decreased does the system allow another thread to request aresource.
Because several threads can affect an RTSS semaphore’s resource count, an RTSSsemaphore, unlike an RTSS mutex, cannot be owned by a thread. This means that waiting forsemaphore objects:
Chapter 3: Using Using the RTX Functionality
45
Will never return WAIT_ABANDONED
� May lose semaphore resources if threads are terminating
However, unlike the usual semaphore objects, the RTSS semaphore objects support thewaiting priority. That is, when there are several threads with the different priority waiting foran RTSS semaphore object, the system guarantees that the order of thread obtaining thesemaphore object is the order of thread priority when the RTSS semaphore object is signaled.
Inter-Process Communication via Semaphores
To synchronize threads running in multiple processes, including RTSS processes and Win32processes, a thread in each process must have its own process-relative handle to a singleRTSS semaphore object. These handles can be obtained by calling eitherRtCreateSemaphore or RtOpenSemaphore.
Using RtCreateSemaphore
The first and most common way is for one thread in each process to callRtCreateSemaphore, passing the identical string for the parameter of RTSS semaphorename. The first thread to call RtCreateSemaphore will cause the system to create the RTSSsemaphore object. As additional threads call RtCreateSemaphore, the system determinesthat an RTSS semaphore object with the specified name already exists; as a result, it does notcreate a new RTSS semaphore object but returns a process-relative handle identifying theexisting RTSS semaphore object.
A thread can determine whether RtCreateSemaphore actually created a new RTSSsemaphore object by calling GetLastError immediately after the call toRtCreateSemaphore. If GetLastError reports ERROR_ALREADY_EXISTS, a new RTSSsemaphore object was not created.
Using RtOpenSemaphore
Another method for obtaining the handle of an RTSS semaphore object involves a call toRtOpenSemaphore. The dwDesiredAccess parameter is ignored. The lpName parameter isthe zero-terminated string name of the RTSS semaphore object. When the call toRtOpenSemaphore is made, the system scans all existing RTSS semaphore objects to see ifany of them have the same name indicated by lpName. If the system finds an RTSSsemaphore object with the specified name, it creates a process-relative handle identifying theRTSS semaphore object and returns the handle to the calling thread. Any thread in the callingprocess can now use this handle in any function that accepts an RTSS semaphore handle. Ifan RTSS semaphore object with the specified name cannot be found, null is returned.
Environments
The RTSS semaphore object is always maintained in the RTSS environment. However,Win32 programs may create, open, release, and wait for RTSS semaphores. This allowscooperation between RTSS and Win32 processes. The semaphore name space is separatefrom the Win32 semaphore name space.
RTX User’s Guide
46
Event Objects
An event object is a synchronization object whose state can be explicitly set to signaled byusing RtSetEvent or RtPulseEvent. The two types of event objects are:
Manual-reset event — An event object whose state remains signaled until it is explicitlyreset to nonsignaled by RtResetEvent. While it is signaled, any number of waitingthreads, or threads that subsequently specify the same event object in a call toRtWaitForSingleObject, can be released.
Auto-reset event — An event object whose state remains signaled until a single waitingthread is released, at which time the system automatically sets the state to nonsignaled. Ifno threads are waiting, the event object's state remains signaled.
An event object is useful in sending a signal to a thread, indicating that a particular event hasoccurred.
Using RtCreateEvent
A thread uses the RtCreateEvent function to create an event object. The creating threadspecifies the initial state of the object and whether it is a manual-reset or auto-reset eventobject. The creating thread can also specify a name for the event object. Threads in otherprocesses can open a handle of an existing event object by specifying its name in a call toRtOpenEvent. For additional information about names for objects, see Object Names onpage 43.
Using RtPulseEvent
A thread can use RtPulseEvent to set the state of an event object to signaled and then reset itto nonsignaled after releasing the appropriate number of waiting threads. For a manual-resetevent object, all waiting threads are released. For an auto-reset event object, the functionreleases only a single waiting thread, even if multiple threads are waiting. If no threads arewaiting, RtPulseEvent simply sets the state of the event object to nonsignaled and returns.
Mutex Objects
The RTSS mutex object is a synchronization object whose state is signaled when it is notowned by any thread and not signaled when the mutex is owned by a thread. The mutexobject arbitrates exclusive access to a shared resource.
Ownership
A thread owns a mutex between the exit from a wait function and the call toRtReleaseMutex. No other thread can own the mutex between these calls. If another threadcalls a wait function while the mutex is owned (not signaled), the wait function will not exituntil the mutex owner releases the mutex. When an owning thread terminates, the mutex issignaled and abandoned. The waiter learns of an abandoned mutex by examining the waitfunction's return value. A thread that acquires an abandoned mutex should expect aninconsistent shared resource.
If more than one thread is waiting for ownership, the thread with the highest priority getsownership and is the first thread to return from the wait function. In cases where threads with
Chapter 3: Using Using the RTX Functionality
47
the same priority are waiting to be owners, the earliest request goes first.
Inter-Process Communication via Mutex Objects
To synchronize threads running in multiple processes, including RTSS processes and Win32processes, a thread in each process must have its own process-relative handle to a singleRTSS mutex object. These handles can be obtained by calling either RtCreateMutex orRtOpenMutex.
Using RtCreateMutex
The first and most common way is for one thread in each process to call RtCreateMutex,passing the identical string for the parameter of RTSS mutex name. The first thread to callRtCreateMutex will cause the system to create the RTSS mutex object. As additionalthreads call RtCreateMutex, the system determines that an RTSS mutex with the specifiedname already exists; as a result, it does not create a new RTSS mutex object but returns aprocess-relative handle identifying the existing RTSS mutex object.
A thread can determine whether RtCreateMutex actually created a new RTSS mutex objectby calling GetLastError right after the call to RtCreateMutex. If GetLastError reportsERROR_ALREADY_EXISTS, a new RTSS mutex object was not created. If you areexpecting to share this RTSS mutex with other processes, you can ignore this last step.
Using RtOpenMutex
Another method for obtaining the handle of an RTSS mutex involves a call to theRtOpenMutex. The dwDesiredAccess parameter is ignored. The lpName parameter is thezero-terminated string name of the RTSS mutex object. When the call to RtOpenMutex ismade, the system scans all existing RTSS mutex objects to see if any of them have the samename indicated by lpName. If the system finds an RTSS mutex object with the specifiedname, it creates a process-relative handle identifying the RTSS mutex and returns the handleto the calling thread. Any thread in the calling process can now use this handle in anyfunction that accepts an RTSS mutex handle. If an RTSS mutex with the specified namecannot be found, null is returned.
Environments
The RTSS mutex is always maintained in the RTSS environment. However, Win32 processesmay create, open, and own RTSS mutex objects. The RTSS mutex name space is separatefrom the Win32 mutex name space.
RTX User’s Guide
48
Device Management
Interrupts
Real-time systems frequently are required to respond to external devices. In doing so, it isoften desirable to have a real-time process respond directly to the interrupts generated bythese devices. RTX allows a process to directly interface with a device without having towrite a Windows driver.
Interrupt Management
The RTX interrupt management routines provide interfaces that enable an application tosatisfy interrupt requests from devices attached to the computer. These interfaces let youattach a handling routine to an interrupt, much the same way that the RTX timer routinesallow you to associate a handling routine with a given timer expiration.
Win32 and RTSS processes can attach to an interrupt handler usingRtAttachInterruptVector. The priority assigned to the interrupt handler thread determinesthe priority execution order of the interrupt handler in both the RTSS and Win32environments.
When an interrupt handler is attached to a particular interrupt, a thread is created whichresponds to the interrupt. This handling thread is analogous to an Interrupt Service Thread(IST). When the interrupt occurs, the interrupt source is masked; the interrupt’s thread isresumed; and, if its priority is greater than the priority of the currently executing thread, itbecomes the currently executing thread. After the interrupt handler returns, the interruptsource is unmasked and the thread is suspended.
There are twelve interrupt levels availale to RTSS. The RtAttachInterruptVector call mapsRTSS priorities into these twelve interrupt levels. These are, in increasing hardware priority:
0-117, 118, 119, ...127
For example, interrupts that require the highest hardware priority, the user should assign anRTSS priority of 127 when the interrupt is attached. For hardware interrupts of lesser priority,the user may choose from a range of 118-126. For the lowest level priorities, use 117 or less.
APIs
The following APIs are available to manage RTX interrupt services:
RtAttachInterruptVector attaches an IST to a specified interrupt.
RtAttachInterruptVectorEx can attach an IST and/or an Interrupt Service Routine (ISR)to a specified interrupt. You can also share interrupts exclusively attached within either theRTSS or Win32 environments (but not both) with this call.
RtReleaseInterruptVector releases an interrupt previously attached withRtAttachInterruptVector or RtAttachInterruptVectorEx.
RtDisableInterrupts under the Win32 environment disables interrupt handling for allinterrupts attached to a process. In the RTSS environment, all interrupts are disabled at the
Chapter 3: Using Using the RTX Functionality
49
processor level.
RtEnableInterrupts enables all interrupts disabled by RtDisableInterrupts.
General Programming Considerations
As with any thread, an interrupt thread can be preempted at any time by a thread that runs at ahigher thread priority level.
Time slicing effects the execution of ISTs if there is a time quantum set for the IST.
� Interrupt processing can be disabled for the set of interrupts attached to the RTX processby raising the thread priority level of the currently executing thread. The level must behigher than all of the thread priority levels specified for the RTSS Interrupt ServiceThreads. An interrupt handler that signals an object may satisfy the wait conditions of ahigher priority thread. Resuming the higher priority thread will delay the completion ofthe interrupt handler and delay the time at which the interrupt source will be unmasked.High priority threads never mask timer interrupts; thus, the timer interrupt is effectivelythe highest priority interrupt. To mask timer interrupts, use RtDisableInterrupts.
Win32 Environment Programming Considerations
All processing in the RTSS environment takes priority over all processing in the Win32environment. Therefore, any time-critical interrupt processing that must be accomplishedshould be done with a handler running an RTSS process, rather than a Win32 process. In theWin32 environment, the Windows NT and Windows 2000 schedulers service RTX interruptthreads. This can lead to non-deterministic scheduling latencies for the handling thread toreceive and process the interrupt.
Using RtAttachInterruptVector
To attach an interrupt vector, use RtAttachInterruptVector. To use this call, you must supplybus-specific parameters. For buses with automatic configurations, such as PCI you can obtainthe parameter information by calling RtGetBusDataByOffset. For more information, look inthe Bus I/O section of this manual.
Using RtAttachInterruptVectorEx
Use RtAttachInterruptVectorEx to share interrupt vectors. This function lets you associate ahandling routine with a hardware interrupt on one of the supported buses on the computer.
RTSS threads can share a given interrupt vector, and Win32 threads can do the same.However, an RTSS thread and a Win32 thread cannot share the same interrupt. To determinewhat interrupts Windows NT is using, use Windows NT Diagnostics. To determine whatinterrupts Windows 2000 is using, look in Device Manager. You should be aware that sharingof interrupts increases the interrupt latency for the lower priority interrupt service threads;this occurs because the higher priority interrupt service thread must run and determine that ashared interrupt is to be passed along to another thread. For situation where very low interruptlatency is necessary, the extra overhead of interrupt sharing could cause problems. Devicesthat require very short interrupt latency should be assigned to unique interrupt lines. If yourdevice has hard real-time interrupt latency requirements, you probably do not want it to sharean interrupt line with another device.
RTX User’s Guide
50
Level-triggered interrupts cannot be used by Win32 processes because the interrupt will bereasserted when RTSS tries to return to Windows NT to allow the Win32 service routine torun. For level-triggered interrupts to operate correctly, the interrupt service routine must clearthe interrupt condition before it unmasks the interrupt line. This limitation is found onuniprocessor systems only.
Using RtReleaseInterruptVector
Unlike driver unloading, an RTX application can exit and leave a device enabled, with thedevice attempting to deliver interrupts to the handling thread. Although the RTX libraryusually cleans up after an application exits, there are times when the exiting application canbypass the library’s attempt to detect the exit. To avoid such a condition, useRtReleaseInterruptVector; it will release a previously attached interrupt.
Note: Just as in an interrupt service routine in a device driver, a real-time application must beable to acknowledge an interrupt and control the device that generated it. For further detailson communicating with devices, see the Port I/O and Physical Memory Mapping sectionsthat follow.
Programming Example (Interrupt Management and Port I/O Calls)
See the Interrupt Management and Port I/O Calls Programming Example in Code and FileExamples. It demonstrates the use of RTX interrupt management and port I/O calls.
Port IO
Real-time systems require the ability to control, read, and write data to hardware devices. TheRTX port I/O programming interfaces allow data movement in the I/O space of a processorby a user process without the need to switch to a kernel-mode code. This functionalityeliminates the need for creating a device driver for every device that must be accessed.Additionally, it eliminates the latencies associated with requesting device driver services forevery device access.
Port I/O provides an alternate method of communicating directly with hardware. The I/Oaddress space is a feature found on Intel processors where each address represents an 8-bit"port." Each port typically corresponds to an 8-bit control register on a hardware device.While sequential addresses can represent the bytes in a multi-byte port, hardware designersusually employ designs that have a single-byte port, and multi-byte values are entered assequential single-byte writes to the port address. For details about a particular device, youshould consult its programming reference documentation.
Access to port I/O devices must be enabled prior to attempting any data transfers. This isaccomplished with the RtEnablePortIo function by passing in the port I/O address range thatwill be accessed. Subsequent to enabling access, the RtWrite* and RtRead* functions,discussed below, may be used to transfer data to and from the enabled port I/O space.
Port I/O Control APIs
The following APIs are available to access Port I/O control services:
RtEnablePortIo enables the direct Port I/O access for the specified range of I/O
Chapter 3: Using Using the RTX Functionality
51
addresses.
RtDisablePortIo disables the direct Port I/O access for the specified range of I/Oaddresses.
Port I/O Data Transfer APIs (described in the section that follows)
Port I/O Data Transfer APIs
The following APIs are available to access Port I/O data transfer services:
RtReadPortUchar,RtReadPortUshort,RtReadPortUlong directly reads a one-, two-, orfour-byte datum from the specified I/O port.
RtWritePortUchar,RtWritePortUshort,RtWritePortUlong directly writes a one-, two-,or four-byte datum to the specified I/O port.
RtReadPortBufferUchar,RtReadPortBufferUshort,RtReadPortBufferUlong copies aseries of one-, two-, or four-byte datum from the specified I/O port to a buffer.
RtWritePortBufferUchar,RtWritePortBufferUshort,RtWritePortBufferUlong copiesa one-, two-, or four-byte datum from the specified I/O port to a buffer.
General Programming Considerations
The RTX interfaces are coded in assembly and use the __stdcall convention, indicating thatthe subroutines handle the stack cleanup. You should not use other calling conventions.
Programming Example
See Interrupt Managemet and Port I/O Calls Programming Example in Code and FileExamples in Appendix A. It demonstrates the use of RTX interrupt management and port I/Ocalls.
Physical Memory Mapping
The existence of an I/O space is dependent on the processor architecture. Several WindowsNT and Windows 2000-supported architectures are based on processors that do not have aseparate I/O space. Rather, their ports are mapped into memory addresses. Thesearchitectures can use the memory mapping function to enable access to physical memory oncontrollers and other hardware devices.
Physical memory mapping can also be used to give processes access to physical memoryranges in the CPU’s address space.
The RTX physical memory map interface maps a section of physical memory into anapplication’s virtual address space. This enables the application to access a region of physicalmemory directly, as if it were a buffer in the application. This interface is useful forapplications that need to access device memory or registers that are mapped into the physicaladdress space of the CPU.
APIs
The following APIs are available to access RTX memory mapping services:
RTX User’s Guide
52
RtMapMemory maps a physical memory address range into the process’ virtual addressspace.
RtUnmapMemory removes a previously mapped physical memory object from theprocess’ virtual address space.
General Programming Considerations
There are no restrictions or protections on the mapped memory region. The mapping willprovide precisely the base address and length specified, if successful. You should take carenot to map in and modify Windows NT or Windows 2000 address space as this may lead tocorruption of either operating system.
Win32 Environment Programming Considerations
Accesses beyond the address range allocated in the mapping will result in an exception.
Programming Example (RTX Memory Mapping Calls)
See the RTX Memory Mapping Calls Programming Example in Code and File Examples inAppendix A.
Contiguous Memory Mapping
Certain devices, particularly devices that perform DMA, require that their buffers reside inphysically contiguous memory in the CPU’s address space. In addition, these devices mustaccess the memory buffers using the actual physical address, rather than by the virtualaddress that is used by a Win32 or an RTSS process.
The RtAllocateContiguousMemory and RtGetPhysicalAddress functions are used toallocate physically contiguous memory and to translate the virtual address of the memory to aphysical address, respectively.
APIs
The following APIs are available to access RTX contiguous memory allocation services:
RtAllocateContiguousMemory allocates a physically contiguous memory address rangeand maps that memory into the process’ virtual address space.
RtFreeContiguousMemory frees a previously allocated physically contiguous memoryregion.
RtGetPhysicalAddress returns the physical address for the virtual address of a previouslyallocated physically contiguous memory region.
Programming Considerations
Contiguous memory is always allocated from the non-paged pool of memory maintained byWindows NT and Windows 2000. This pool of memory is relatively small and is rapidlyfragmented by the allocations of other drivers and subsystems in Windows NT and Windows2000 shortly after system boot. To avoid failure of large allocations, you should minimizetheir use and/or ensure that they are accomplished shortly after system boot.
Chapter 3: Using Using the RTX Functionality
53
In the Win32 environment, RtGetPhysicalAddress operates only with addresses returned byRtAllocateContiguousMemory.
Programming Example (RTX Contiguous Memory Allocation Calls)
See the RTX Contiguous Memory Allocation Calls Programming Example in Code and FileExamples in Appendix A. It demonstrates the use of RTX contiguous memory allocationcalls.
Bus IO
RtGetBusDataByOffset, RtTranslateBusAddress, and RtSetBusDataByOffset facilitatethe development of RTSS hardware drivers. Each function eases the gathering of specifichardware information and/or setting hardware.
RtGetBusDataByOffset is used primarily in support of attaching a driver to a hardwaredevice by obtaining device information required for input to RtAttachInterruptVector, suchas the bus number, interrupt level, and interrupt vector. For example, by issuing a call toRtGetBusDataByOffset, a PCI bus can be scanned, detect a particular device, and thenreturn the bus number where the device resides, the bus interrupt level, and interrupt vector.
For further information, see RtAttachInterruptVector and RtAttachInterruptVectorEx inthe RTX 5.0 Reference Guide.
Setting hardware is accomplished with a call to RtSetBusDataByOffset. This function isuseful when device initialization requires clearing or setting of status registers, slot, and soon.
RtTranslateBusAddress is used to translate a device-specific memory address range into thelogical address space of a driver.
Programming Example (Bus I/O)
See the Bus I/O Programming Example in Code and File Examples in Appendix A. The codefragment illustrates each of the Bus I/O calls in a PCI driver.
File IO
File IO
RTX allows two options for file input and output (I/O). You can write to the supported fileI/O functions in the Win32 API or to the supported file I/O functions in the C run-timelibrary. The API delivers low-overhead, fast access to Windows NT and Windows 2000 fileI/O capabilities using standard APIs. A subset of CreateFile flags are supported with file I/O.Please refer to the RTX 5.0 Reference Guide for more details. File I/O does not includesupport for asynchronous file operations.
Because RTSS applications have no current-directory notion, RTSS file I/O requests must usefully qualified path names, such as:
c:\temp\MyFile.txt (for a file system object)
RTX User’s Guide
54
\\.\MyDevice0 (for a device object)
RTSS file I/O calls are made from the Windows NT or the Windows 2000 kernelenvironment: RTX actually translates Win32 names such as c:\MyFile.txt and \\.\MyDevice0to NT internal names \??\c:\MyFile.txt and \Device\MyDevice0, respectively. You can,therefore, use Windows NT and Windows 2000 internal names from your RTSS applications,although such calls fail in Win32. Using an internal Windows NT or Windows 2000 namelets you access a device object for which Win32 has no symbolic link, such as \Device\beepor \Device\Harddisk0\Partition1\testfile.txt.
With boot-time file I/O, you may only use paths such as\\Device\\Harddisk0\\Partition1\foo.txt because paths such as \\??\\C:\\foo.txt and C:\\foo.txtare not supported.
55
Chapter 4
Developing an ApplicationThis chapter discusses the two types of real-time dynamic link libraries (RTSS DLL andRTDLL), and provides references to code examples for each type. It also explains how to usethe C run-time library functions and floating point; provides guidance on writing devicedrivers; explains exception handling in the RTSS and Win32 environments; and providestechniques for managing starvation conditions.
This chapter contains information on:
Using the RTX Makefile
Using RTX Dynamic Link Libraries
Using the C Run-time Library Functions
Using Floating Point
Writing RTSS Device Drivers
C++ and Structured Exception Handling
System Exception Handling
About System Exception HandlingRTX HandlerTables of ExceptionsRTX Exception HandlingAbout RTX and Windows NT / WIndows 2000 Stop MessagesInterpreting Windows NT Blue Screen Stop MessagesInterpreting RTX Green Screen Stop Messages
Starvation Management
Power Management
RTX User’s Guide
56
Using the RTX Makefile
You can use the RTX master makefile (rtx.mak) to build both RTSS and Win32 versions of aparticular program. Rtx.mak contains rules to compile C files and link the resulting objects.You can specify Win32 executable (.exe) files in a makefile using rtx.mak because rtx.makincludes win32.mak.
Variables
The master makefile uses the following variables:
NODEBUG — Calls the link using the /RELEASE option.
RTSS_CRT — Includes the RTSS C run-time library for single-threaded applications inthe final link of the RTSS executable.
RTSS_MTCRT — Includes the RTSS C run-time library for multi-threaded applicationsin the final link of the RTSS executable.
USER_LIBS — Additional user-specified libraries that will be included in the link stage.
RTSS_OBJS, RTDLL_OBJS — List of object files linked by rtss link or rtdll linkmakefile rules, respectively.
Sample Makefile
See the Makefile Sample in Code and File Examples in Appendix A.
Chapter 4: Developing an Application
57
Using RTX Dynamic Link Libraries
This topic provides:
n Descriptions of the two types of real-time DLLs (RTSS DLL and RTDLL)
n C Run-Time Libraries: Programming Considerations for DLLs
n References to RTSS DLL and RTDLL code examples
For instructions on creating DLLs, see Creating RTX Dynamic Link Libraries on page 25.
About RTSS DLLs and RTDLLs
There are two types of real-time DLLs (RTSS DLL and RTDLL) that you can use to sharecode between processes or make run-time determinations of what libraries need to be loadedfor a given hardware configuration.
RTSS DLLs — An RTSS DLL is actually not a DLL but an RTSS process that exportsfunctions for use by other RTSS processes. It shares a common address space with RTSSprocesses. They can be loaded either at boot time or through a call to Windows NT fromwithin a C/C++ program (e.g., System("RTSSrun LibName.rtss"). Although similar toRTSS applications, their entry point is Main, and they are compiled and linked to generatea library of exported functions that can be linked with RTSS applications. Typically, Mainfor an RTSS DLL will simply issue a SuspendThread call. RTSS DLLs allow you toreference exported functions by name in a calling program, but are cumbersome to loadbecause they are neither loaded nor unloaded automatically when RTSS applications usingthem start running.
RTDLLs — RTDLLs are RTSS objects that can be dynamically loaded and unloadedusing the LoadLibrary and FreeLibrary calls. They are automatically unloaded frommemory when the last RTSS process referencing them terminates. Because RTDLLs donot require linking to an explicit export library, they provide a convenient, flexible run-time accommodation of changes to RTDLLs or applications. However, with RTDLLs theaddress of each exported function used by a calling process must be explicitly obtainedthrough a call to GetProcAddress. Additionally, because RTDLLs are not RTXprocesses, it is not reliable to use C run-time functions within an RTDLL loaded by morethan one RTX process simultaneously. For further details about the relationship between Crun-time libraries and RTDLLs see C Run-Time Libraries:Programming Considerationsfor DLLs below.
The choice of RTSS DLLs or RTDLLs for a particular application depends on the specificfunctional requirements of the application. The variation of hardware run-timeconfigurations that an application must accommodate may also affect your choice.Programming examples for RTSS DLLs and RTDLLs are provided in the sections thatfollow.
C Run-Time Libraries: Programming Considerations for DLLs
This section discusses considerations that you should keep in mind when designing an RTSSDLL or RTDLL that will be linked with the RTX-supplied C run-time libraries, RTXlibc.libor RTXlibcmt.lib (see Using the C Run-time Library Functions on page 59).
The Microsoft C run-time initialization code assumes that global variables have process
RTX User’s Guide
58
scope, i.e., a separate copy of all C run-time global variables and structures exists for eachprocess using the libraries. This is not true for RTSS DLLs or RTDLLs.
RTSS DLLs
Because RTSS DLLs are RTSS processes which have been linked to generate an exportlibrary, and because they never get unloaded from memory except at shutdown, globalstructures created at initialization will persist during the entire life of any process dependingon the RTSS DLL.
Note: A few C run-time routines are unsafe within an RTSS DLL used by multiple processes.
The routines that you should not use are: fprintf(), getenv(), perror(), printf(), vsprintf(), andwprintf(). Because these routines rely on per-process global variables, they can yieldundefined behavior that may require system reboot. Note that in this context "used bymultiple processes" means used by more than one process at any time between system startupand shutdown, including the same RTSS image, running twice in succession with the sameRTSS PID.
RTDLLs
RTDLLs are not RTSS processes; they are RTSS objects which can be dynamically loadedand unloaded. Because other objects created by an RTDLL are always owned by the callingprocess, they are destroyed when that process terminates. Among other things, the C run-timeinitialization creates heaps used for memory allocation. These heaps persist only until theprocess that initially loaded the RTDLL terminates. Since the behavior of C run-timefunctions is reliable only in an RTDLL loaded by multiple processes given strict limitationson the LoadLibrary, FreeLibrary sequence, it is recommended that you never registerRTDLLs linked with the C run-time libraries with the /s switch of RTSSrun.
RTSS DLL and RTDLL Code Examples
See RTSS DLL Code Example and RTDLL Code Example in Code and File Examples inAppendix A.
Chapter 4: Developing an Application
59
Using the C Run-time Library Functions
RTX provides support for C run-time library functions. The RTX-supplied C run-timelibraries are based on the Microsoft Visual C++, C run-time libraries. The RTX libraries,named RTXlibc.lib and RTXlibcmt.lib (indicating single and multi-threaded libraries),provide improvements to the efficiency of memory allocation (malloc). Other than thisimprovement, they do not differ substantially from the Microsoft libraries.
For a list of available functions, see the C Run-Time API List in the RTX 5.0 Reference Guide.
Using Floating Point
Threads that run in the RTSS environment always run in kernel mode. Whereas the WindowsNT and Windows 2000 kernel does not support floating-point operations in kernel-mode code(such code causes the system to crash), RTX allows RTSS threads to use the Floating-PointUnit (FPU) to perform floating-point operations.
Enabling Floating-Point Support in RTSS Programs
If you build RTSS programs using NMAKE, you must add the following line to yourmakefile before the line that includes rtx.mak:
RTSS_CRT = 1
The preceding line enables Floating-Point Unit (FPU) support, including the floating-pointmath routines and printf with floating-point support.
If you are using Microsoft Visual Studio, follow the procedure to enable C run-time supportas described in Using Microsoft Visual Studio 6.0.
Running RTSS Programs Using Floating-Point
You do not need to follow any special procedures to run an RTSS program that uses floating-point. The program can simply issue Floating-Point Unit (FPU) instructions and call floating-point math routines as done by a standard Win32 program.
Writing RTSS Device Drivers
RTX provides a number of features that enable you to quickly and easily develop devicedrivers. The RTX device driver model is simpler than that of Windows NT and gives yougreater flexibility in design. Because Windows NT and Windows 2000 device drivers areoften user-mode drivers and rely on user-mode Windows NT and Windows 2000 services,they cannot be used "as-is" with RTSS applications. Furthermore, since even kernel-modedrivers are often accessed through user-mode libraries supplied by hardware vendors, it isgenerally not possible to access standard Windows NT and Windows 2000 device driversfrom within an RTSS application.
Devices can be accessed and controlled through three types of functions: Port I/O, Bus I/O,and mapped memory. Additionally, drivers can respond to devices by providing interrupthandlers through RtAttachInterruptVector. Unlike Windows NT, where access to drivers
RTX User’s Guide
60
occurs via calls to DeviceIoControl, RTSS drivers can be structured as static libraries, RTSSDLLs, or RTDLLs. In each case, the driver writer can supply library functions directly to theRTSS application writer without the need to employ the DeviceIoControl interface.
For many applications, it is not necessary to write a hard real-time (RTSS) device driver forstandard desktop devices. When hard real-time performance is not required for device access,as is often the case with video, sound, and network devices, the recommended approach is todevelop a Win32 application that communicates with RTSS applications through IPCmechanisms, and communicates with necessary devices through standard Windows NTdevice drivers.
C++ and Structured Exception Handling
RTX supports Microsoft C++ exceptions (catch/throw), Win32 Structured ExceptionHandling (SEH) API, and C frame-based exception handling (try/except/finally), all asdefined by the Win32 Platform SDK.
This topic discusses:
C++_Support
� Structured_Exception_Handling
C++ Support
RTX supports the Visual C++ language, with some restrictions discussed in the note below.RTSS should support any C++ features usable in a Win32 C++ RTX API console application,including new/delete operators and exception handling.
Note: RTX does not claim support for all C++ libraries. Support is limited to libraries thatdepend upon the set of Win32 functions supported in the RTSS environment. You can testspecific libraries to determine whether they are supported by RTX.
Structured Exception Handling
RTSS supports Structured Exception Handling and C++ exceptions, as described by theWin32 Platform SDK, including:
Win32 Structured Exception Handling calls, which include RaiseException,SetUnhandledExceptionHandler, UnhandledExceptionFilter, AbnormalTermination,GetExceptionCode, GetExceptionInformation
Frame-based exception handlers: try-except and try-finally.
C++ exception handling: try-catch.
� Handling for the following software exceptions in RTSS:
EXCEPTION_DATATYPE_MISALIGNMENTEXCEPTION_BREAKPOINTEXCEPTION_ACCESS_VIOLATIONEXCEPTION_ILLEGAL_INSTRUCTIONEXCEPTION_FLT_DENORMAL_OPERAND
Chapter 4: Developing an Application
61
EXCEPTION_FLT_DIVIDE_BY_ZEROEXCEPTION_FLT_INEXACT_RESULTEXCEPTION_FLT_INVALID_OPERATIONEXCEPTION_FLT_OVERFLOWEXCEPTION_FLT_UNDERFLOWEXCEPTION_INT_DIVIDE_BY_ZERO
Using SEH
To use SEH in an RTSS application, an application must be linked with a Win32 static-linkage run-time support library (such as RTXlibc.lib or RTXlibcmt.lib which contain run-time support for the SEH frame-based exception handlers), or with static-linkage run-timesupport C++ libraries.
Differences Between Win32 and RTSS Exception Handling
The RTSS implementation follows Win32 SEH semantics where possible. This sectiondescribes the differences.
UnhandledExceptionFilter
Win32 UnhandledExceptionFilter semantics provide the option to disable the exception-related dialog box pop-up via SetErrorMode with the SEM_NOGPFAULTERRORBOX flag.On an exception, RTSS always displays a pop-up saying that the application has been frozenor unloaded.
Exception caused by a thread
When a thread of a multithreaded application causes an exception in Win32, the systemdisplays a dialog box. Until the user responds to the box, other threads of the applicationcontinue running. Once the user has responded, all threads of the application terminate.
RTSS acts differently; it freezes (or unloads, if so configured) all threads of a processwhenever any of them gets an exception, and produces an informational pop-up. Thisbehavior is safer and more intuitive in the RTSS context. You can, however, emulate theWin32 behavior by using per-thread unhandled exception filter functions.
Nested exceptions and collided unwinds
RTSS follows Win32 rules for nested exceptions and "collided" unwinds, with a few minordifferences:
Non-continuable exceptions — Non-continuable exceptions caused by the programdirectly or by exception handling run-time itself. Win32 repeatedly re-asserts those; butrepeated re-assertion of exceptions consumes stack space. A stack fault in RTSS causes asystem shutdown (the "green screen"), so for robustness, RTSS terminates a process thathas generated a non-continuable exception.
Hardware exceptions — RTSS exception codes for hardware exceptions are tied toPentium interrupt codes, thus differing from Win32 exception codes caused by similarerrors.
For example, an errant Win32 application gets an EXCEPTION_ACCESS_VIOLATION
RTX User’s Guide
62
as defined by Win32, an RTSS application gets EXCEPTION_PAGE_FAULT asdescribed in the RTX Reference Guide. A Win32EXCEPTION_ILLEGAL_INSTRUCTION is equivalent to the RTSSEXCEPTION_INVALID_OPCODE.
Reads/writes of address 0 — Win32 explicitly guarantees that the first 64K of a userprocess's address space is unmapped, so any access of that area causes an exception.However, Windows NT and Windows 2000 occasionally make this area valid for kernelprocesses and device drivers (and, therefore, for RTSS). This means that a write to/readfrom address 0 from an RTSS process may occasionally succeed, rather than cause anexception.
Debugging
For debugging, see the Debug tab in the RTX Properties control panel.
General User Notes for Exception Handling
Exception handling is a powerful mechanism with often subtle semantics. It is quite easy towrite code that causes infinite re-assertion of an exception. For example, if a filter expressionalways faults, or always dismisses a hardware exception which gets re-executed, the processcontinues generating exceptions until it overflows the stack. Miscasting the handler argumentto SetUnhandledException filter may be equally fatal.
Because stack faults in RTSS cause system shutdown, you must be careful when writingexception handlers. Testing your application in Win32 becomes more important than ever toavoid stack overflows in RTSS.
System Exception Handling
About System Exception Handling
An exception is a forced transition from normal program execution to a specializedprocedure, called a handler, which processes the exception. An exception is raised (occurs)when the CPU encounters an error condition during program execution. Each exception isassigned an error code or vector number. For example, if the CPU encounters a divide by 0,exception 0 is raised. For a complete discussion of exception handling, see Volume 3:Architecture and Programming of the Pentium® Processor Family Developer's Manual.
Important: All discussions in this chapter ("System Exception Handling") assume that RTSSapplications do not use Structured Exception Handling (SEH). For information on SEH, seeC++ and Structured Exception Handling.
RTX Handler
RTX provides a handler to process exceptions that occur in an RTSS process. (If an exceptionoccurs in a native Windows NT or Windows 2000 application, the Windows operatingsystem handles it.) When the RTX handler encounters an error, it initiates one of thefollowing actions:
Freezes and/or terminates the process
Chapter 4: Developing an Application
63
Modifies the application environment and continues
� Executes an orderly shutdown, known as a "Green Screen"
Note: If an exception occurs within an ISR (such as an RTX harware interrupt or RTX timerinterrupt), RTX immediately initiates an RTX Green Screen stop message. If a fault occursduring exception processing, the RTX handler immediately initiates a double fault and GreenScreen stop message.
Tables of Exceptions
This topic contains tables of the following types of exceptions:
RTX exceptions
� Intel exceptions
RTX Exception Codes
The table that follows lists the exception name, the vector number or error code, and theexception handler response.
([FHSWLRQ (UURU�&RGH 57;�ZLOO���
(;&(37,21B13;B127B$9$,/$%/( �;�� $OORZ�IRU�IORDWLQJ�SRLQWFDSDELOLW\��DQG�FRQWLQXHH[HFXWLQJ�WKH�DSSOLFDWLRQ�
(;&(37,21B,17� �[�� (QWHU�WKH�GHEXJJHU��,I�QRGHEXJJHU�LV�SUHVHQW��57;�IUHH]HVWKH�SURFHVV�
(;&(37,21B10,�(;&(37,21B'28%/(B)$8/7�(;&(37,21B5(6(59('B75$3�(;&(37,21B,19$/,'B766
��[����[����[�)��[�$
,VVXH�D�*UHHQ�6FUHHQ�VWRSPHVVDJH�
Intel Exception Codes
Following Win32 behavior, RTSS maps the Intel (x86) exception code to the Win32 one, andthen invokes Structured Exception Handling. RTX will alert the user via a popup message,make an entry to the event log, and freeze or terminate the thread and associated process.
[���([FHSWLRQ :LQ���0DSSLQJ
(;&(37,21B',9,'('B%<B=(52 (;&(37,21B,17B',9,'(B%<B=(52�(;&(37,21B)/7B',9,'(B%<B=(52
(;&(37,21B13;B29(5581 (;&(37,21B)/7B,19$/,'B23(5$7,21
(;&(37,21B13;B(5525 (;&(37,21B)/7B'(1250$/B23(5$1'�(;&(37,21B)/7B',9,'(B%<B=(52�(;&(37,21B)/7B29(5)/2:�(;&(37,21B)/7B81'(5)/2:�(;&(37,21B)/7B,1(;$&7B5(68/7�(;&(37,21B)/7B,19$/,'B23(5$7,21
(;&(37,21B,19$/,'B23&2'( (;&(37,21B,//(*$/B,16758&7,21
(;&(37,21B*3B)$8/7�(;&(37,21B3$*(B)$8/7
(;&(37,21B$&&(66B9,2/$7,21
RTX User’s Guide
64
[���([FHSWLRQ :LQ���0DSSLQJ�(;&(37,21B%281'B&+(&.�(;&(37,21B6(*0(17B127B35(6(17
(;&(37,21B'(%8* (;&(37,21B%5($.32,17
(;&(37,21B$/,*10(17B&+(&. (;&(37,21B'$7$7<3(B0,6$/,*10(17
RTX Exception Handling
For most exceptions, the RTX handler performs the following tasks:
Freezes or terminates the errant RTSS process, depending on the state of theExceptionDisposition flag
Alerts the user with a popup window
� Writes one or more associated entries in the event log
The sections that follow describe each of these tasks.
Freeze or Terminate Processing
The ExceptionDisposition registry flag, settable from the RTX Properties Control Panel,controls the disposition of faulting RTSS processes. Possible values are:
0 = Terminates processing (default)
1 = Freezes the thread and processing
Alert User
The RTX handler alerts the user of an exception with a popup message window. For example,if the handler terminates processing, RTX might display the following window:
RTX Exception - Memory Access Fault at loc FEBEB229 (Proc=80452448, Thread=804526F8) Process image has been * unloaded *
In this example, a memory protection fault has been detected. The message identifies theapplication instruction address and the process and thread identification values. Thedisposition of the thread is unloaded.
If the RTX handler freezes processing, RTX might display the following window:
��RTX Exception - Memory Access Fault at loc FEBDF229 (Proc=80452448, Thread=804526F8) Process image has been * frozen * Debug and/or use "RTSSkill" command to unload all processes
In this example, a memory protection fault has been detected. The message identifies theapplication instruction address and the process and thread identification values. Thedisposition of the thread is frozen. The user is directed to manually terminate the processusing RTSSkill.
Chapter 4: Developing an Application
65
Generate Event Log Entries
The event log message includes an information entry, which is the text portion of the popupwindow, and an error entry that provides details about the error. The error entry contains twoparts: a description and binary detail. The binary detail consists of 10 dwords of message dataand 3 dwords of RTSS fault data, as illustrated in the sample that follows.
The description for Event ID (12) in Source (Rtx_rtss) could not be found. It contains the following insertion string(s): \Device\Rtx_rtss, RTX Exception - Memory Access Fault 0000: 00100000 00620002 00000000 c004000c 0010: 00000000 c0000183 00000000 00000000 0020: 00000000 00000000 feac12e8 febdf229 0030: 80452448 804526f8
The first 10 entres in the message dump are` specific to the error logging call and areignored. The 3 dwords of RTSS fault data are:
Instruction pointer value (febdf229 in the sample)
RTSS process identification (80452448 in the sample)
� RTSS thread identification (804526f8 in the sample)
Caution: To preserve event log information, do not filter event entries.
About RTX and Windows NT / Windows 2000 Stop Messages
Stop messages, presented via an RTX Green Screen or a Windows NT Blue Screen, quicklyprovide you with key information about a system crash. A stop message often gives yousufficient data to determine why a system has crashed and what actions to take to resolve theproblem.
To enable (view) stop messages, you must disable the Windows NT Automatically Rebootoption as shown in the procedure that follows.
To enable stop messages1. In the Windows NT Control Panel, double click the System icon and then open the
Startup/Shutdown tab.
2. In the Recovery section, deselect the Automatically Reboot option.
Note: You should select the Automatically Reboot option only if you want to disablestop messages and have the system reboot automatically when there is a systemfailure.
Click OK to save the settings.
RTX User’s Guide
66
Interpreting Windows NT Blue Screen Stop Messages
When a non-recoverable exception occurs within a native Windows NT application,Windows NT initiates a Blue Screen. The Windows NT Blue Screen contains four sections ofdata, with the most important information contained in the first two lines. These two linescontain the stop error code, its four parameters, and the text of the stop error message. Youshould always record the first few lines, along with the driver list (in the second Blue Screensection), before rebooting the computer. With this data, you can often diagnose the source ofa stop condition.
Note: Under some conditions, the kernel displays only the top line of the stop messagebecause the services required to display the rest of the information may not be available.
Section 1 - Stop Message
The Stop Message section provides the bugcheck data in the form:
***STOP: #E(#1, #2, #3, #4) Text interpretation of the error
where
#E = Actual error code.
#1 - #4 = Additional parameters relating to the error.
Text = Best effort interpretation of the error.
Section 2 - Driver List
The Driver List is a two-column display that lists all drivers loaded on the computer at thetime the stop message occurred, along with their base addresses in memory and date stampsof the driver file dates. This section is important because many stop messages contain theaddress of the instruction that caused the error. If the address falls within the base address ofone of the drivers on this list, then that driver may be the cause of the crash.
Section 3 - System Stack Dump
The System Stack Dump lists some of the calls on the stack that preceded the stop message.Sometimes, the first few lines indicate what component or driver caused the error. Youshould note, however, that the last calls on the stack are not always the cause of the problem.The stack dump also provides the names of modules along with their starting addresses. Toget a more detailed stack trace, use a kernel debugger such as WinDbg.
Chapter 4: Developing an Application
67
Section 4 - Communication
The Communication section of the Blue Screen provides confirmation of the communicationparameters used by a kernel debugger (if present on the target computer). The followingmessage then appears:
Restart and set the recovery options in the system control panel or the /CRASHDEBUG system start option. If the error persists enable the Kernel Debugger in either DEBUG or CRASHDEBUG mode on your computer. Consult the Windows NT Debugger documentation for instructions on configuring the computer for debugging
This message implies that if the computer is restarted, the stop condition may not happenagain. If this message reappears after you restart, contact your system administrator ortechnical support group.
To obtain additional information about a system stop1. In the Windows NT Control Panel, double-click the System icon and then open the
Startup/Shutdown tab.
2. In the Recovery section, select the Write Debugging Information option and thenclick OK to apply the change.
Note: When this option is selected, the system memory dump will be written to%SystemRoot%\memory.dmp after a crash.
3. Copy the system symbol files (*.dbg) from the Windows NT installation CD and theRTX-supplied *.dbg files to %SystemRoot%\symbols.
4. Install the dumpexam.exe utility (also on the installation CD).
5. Reboot your system and then run the dumpexam utility.
For more detailed system information concerning the crash, consult the dumpexam textoutput.
RTX User’s Guide
68
Interpreting Windows 2000 Stop Screens
For Windows 2000 the traditional "Blue Screen" has been eliminated. The user can stillobtain the same type of information by using the "minidump" or small memory dump option.All that is needed is a small 2mb paging file on the system drive and configuring the Startupand Recovery Options for minidump on the System properties screen.
This dump file type includes the following information:
The stop message and parameters, as well as other data
A list of loaded drivers
� The processor context (PRCB) for the processor that stopped
� The process information and kernel context (EPROCESS) for the process thatstopped
� The process information and kernel context (ETHREAD) for the thread that stopped
� The Kernel-mode call stack for the thread that stopped
This kind of dump file can be useful when space is limited. However, because of the limitedamount of information included, errors that were not directly caused by the thread running atthe time of the problem may not be discovered by an analysis of this file. The Windows 2000support tool dumpchk.exe will be required to generated text from the binary dump. Refer tothe following Microsoft documentation:
Reading Small Memory Dump Files Created by Windows 2000
Windows 2000 Memory Dump Options Overview
Chapter 4: Developing an Application
69
Interpreting RTX Green Screen Stop Messages
When a non-recoverable exception occurs within an RTSS process, the RTX exceptionhandler initiates a Green Screen. The RTX Green Screen contains four sections of data.Sections 1 and 2 are RTX specific. Sections 3 and 4 are similar to those sections of theWindows NT Blue Screen.
Section 1 - RTSS-Specific Stop Message
This Stop Message section provides the bugcheck data in the form:
*** RTX/RTSS Stop : #E(#1, #2, #3, #4) Text interpretation of the error
where
#E = Actual error code. Error code numbers and their associated text are:
1. UNHANDLED_EXCEPTION 2. THREAD_STACK_OVERFLOW 3. LOCK_HIERARCHY_VIOLATION 4. LOCK_OWNER_VIOLATION 5. PROXY_DISPATCHER_SANITY 6. PROXY_THREAD_SANITY 7. SERVER1_SANITY 8. EXCEPTION_IN_ISR 9. KERNEL_MODE_EXCEPTION 10. SYSTEM_PROCESS_EXCEPTION 11. NMI_EXCEPTION 12. STACK_OVERFLOW
#1 = Exception code taken from Exception Table.
#2 = Contents of Instruction Pointer Register at the time exception was raised. If the #2value is outside the address range of the process, the most likely cause of theexception is a corrupt stack with an illegal value restored to the IP.
#3 = RTSS Thread identification.
#4 = RTSS Process identification.
RTX User’s Guide
70
Section 2 - HAL-Supplied Stop Message
This Stop Message section provides the bugcheck data in the form:
���*** STOP: #E(#1, #2, #3, #4) *** Address XXXXXXXX has base at YYYYYYYY-Kernel Image
where
#E = 0 (zero). Indicates that an RTSS process caused the exception. Other codes arereserved for internal RTX errors.
#1 = Hardware exception vector number.
#2 = Contents of Instruction Pointer Register at time exception was raised.
#3 = Stack pointer at time of fault.
#4 = Base address of the exception frame. For the majority of exceptions, an exceptionstack frame containing the system state information is stored on the current stack.In the case of a double fault, this address will be the base address of the Task StateSegment. For more information, see Volume 3: Architecture and Programming ofthe Pentium® Processor Family Developer's Manual.
Text = The text interpretation attempts to match one of the entries in the stop message toa loaded image base address to determine approximately where the fault wasraised.
Starvation Management
This topic discusses the RTX watchdog timer and programming techniques that you can useto manage starvation conditions.
Watchdog TimerWhen a single RTSS thread becomes CPU bound, it is often the result of a program logicerror (which occurs most frequently during the development phase). When a thread becomesCPU bound on a single-processor system, Windows NT and Windows 2000 both freeze. On amulti-processor system, the both Windows operating systems continue to run but cannotterminate the CPU-bound thread because the lower priority Service Request Interrupt (SRI)manager threads will not run.
Watchdog Management
For this type of condition, you can use the RTX starvation management watchdog timer. Thistimer checks on every timer interrupt (which is normally always enabled) for continuousrunning of the same thread and/or RTSS threads to the exclusion of Windows NT (the idlethread). When the watchdog timer expires, an exception is raised; a popup message notifiesyou of the error; and then Windows NT and Windows 2000 resume normal operation. Theoffending process is either stopped or terminated, based on the Process Exception Dispositionsetting in the RTX Settings control panel. You can use the RTSSkill utility to unload thestopped process.
Chapter 4: Developing an Application
71
Setting the Starvation Time Out Period
You can set the Starvation Time Out period using from the Settings tab of the RTX Propertiescontrol panel.
Values are:
0 = Disable the watchdog timer.
N milliseconds = Enable the watchdog timer and set time period (a typical period is tensof seconds).
Programming Techniques/ConsiderationsAn application may behave correctly, yet it may have one or more threads that become CPUbound for periods of time. In this case, you could periodically give small amounts of time toWindows NT during these periods. This might be needed, for example, to allow Windows NTand Windows 2000 to empty the RS232 UART silo, acknowledge network requests, performdisk I/O, move the mouse pointer, or display something on the GUI. Since the desiredbehavior can be quite complex, an RTX-defined policy of giving Windows NT time slicesmay be unnecessary or may interfere with RTSS deterministic behavior.
You can easily manage this type of situation by creating a timer handler that periodicallysuspends the CPU bound thread(s) for short periods of time. Take, for example, anapplication that runs a thread for 100 milliseconds every second. You could suspend thethread for .5 milliseconds every 10 milliseconds during the 100 milliseconds that it runs. Youcan create an algorithm, as simple or complex as desired, to support starvation management.Typically, a five percent duty cycle is a reasonable initial setting. You can then use thealgorithm to measure and adjust your starvation management.
The RTX sample program, starve.c, demonstrates the use of the timer approach. It is locatedin:
c:\program files\vci\rtx\bin\samples\starvation
Another approach to starvation management is to simply include calls to Sleep, which shouldgive small amounts of time to Windows NT and Windows 2000 within your application.
RTX Power Management for Windows 2000
If there are RTSS processes running on UP system, system power state transitions fromworking state (S0) to any sleeping state (S1-S5) will be blocked by RTX Power Management.You will see a popup message box telling this fact. However, if there are no RTSS processesrunning on UP system, such transitions are not blocked. On MP system, system power statetransitions from working state (S0) to any sleeping state (S1-S5) will be blocked if RTSS isloaded on one processor.
RTX User’s Guide
72
73
Chapter 5
Performance OverviewReal-time systems have exacting performance requirements, including deterministic responsetimes for key operations. This chapter covers the sources of interrupt latency, platform-specific timing factors, and measurement techniques an RTX developer can use to ensuregood response times.
This chapter contains:
Causes and Management of Interrupt Latencies
Reducing Your System’s Latencies: Tools Overview
KSRTM versus SRTM
Using KSRTM (Kernel System Response Time Measurement)
Using SRTM (System Response Time Measurement)
Using RTX Demo (Graphical version of SRTM)
Using the Timer Latency Display Tool
Using LTP (Latency Test Program)
RTX User’s Guide
74
Causes and Management of Interrupt Latencies
Interrupt latency is of particular concern to real-time systems developers. This topic examinesits causes and RTX techniques for managing them. It includes:
Software causes
Hardware causes
� Management of interrupt latencies
Software Causes
Software causes of interrupt latencies include:
PIC (programmable interrupt controller)-level masking of interrupts. Windows NT andWindows 2000 kernels and drivers change interrupt masking via HAL IRQL manipulationcalls. Drivers routinely mask interrupts for several µs.
Processor-level masking of all interrupts. The Windows NT and Windows 2000 kernel, HAL,and special system drivers may mask interrupts for up to 100ms.
� Interrupt-processing overhead.
Hardware Causes
Hardware causes of interrupt latencies include:
Bus "hijacking" by peripheral devices. For example, a video card may stall the CPU's attemptto read the card's I/O space register.
Burst DMA by SCSI controllers.
Cache dirtying by Windows NT and applications.
� Power Management features. Some systems, particularly portables, go to a low-powerstate after a time-out, and "wake up" with a delay that you can barely notice, but which isintolerable to a real-time application.
RTX Management of Interrupt Latencies
RTX eliminates PIC-level interrupt disabling by isolating interrupts (through the RTX HALextension). Windows NT and Windows 2000 and their drivers cannot disable RTSSinterrupts. In addition, all Windows NT and Windows 2000 interrupts are masked whenRTSS is running.
Chapter 5: Performance Overview
75
Reducing Your System’s Latencies: Tools Overview
An RTX developer should be mindful of platform factors. The performance-measurementtools introduced in this topic will help you analyze your system and determine whether it isperforming as expected.
SRTM (System Response Time Measurement) and RTX Demo
SRTM is an RTAPI timer latency measurement tool that measures timer latency observed byan application. Each of the two versions of SRTM, Win32 and RTSS, measures its ownenvironment. An SRTM histogram often shows a characteristic double peak profile: the firstpeak is a near-) and Using RTX Demo (Graphical version of SRTM). See also KSRTM versusSRTM. best case, the second is the dirty-cache case. The diagram occasionally showsadditional "humps" from processor-level interrupt masking. Among the samples is agraphical version of SRTM, RTX Demo, which measures results for both RTSS and Win32.For further details, see Using SRTM (System Response Time Measurement) on page 77.
KSRTM (Kernel System Response Time Measurement)
KSRTM is a driver and a Win32 utility that measures HAL-level timer latency. Short codepaths make it less sensitive to cache jitter than SRTM. It can determine which Windows NTcomponent or device driver is causing the greatest latency event for a real-time application.For further details, see Using KSRTM (Kernel System Response Time Measurement) on page76. See also KSRTM versus SRTM below.
LTP (Latency Test Program)
LTP finds misbehaving peripheral devices. This application loops, reading the RTXCLOCK_FASTEST, detecting latency events caused by peripheral activities (such as burstDMA), and reporting instances of latencies exceeding a certain threshold. For further details,see Using LTP (Latency Test Program) on page 82.
Timer Latency Display
The Timer Latency Display tool performs timing measurements and outputs two displays:Histogram and Latency. For further details and sample outputs, see Using the Timer LatencyDisplay Tool on page 80.
KSRTM versus SRTM
Both KSRTM (Kernel System Response Time Measurement) and SRTM (System ResponseTime Measurement) measure timer latencies. While KSRTM provides detailed informationabout the source of the worst-case latency, it measures only the time to the beginning of theInterrupt Service Routine (ISR). SRTM measures the total time to an RTSS program’s timerhandler (i.e., a full thread context); it is the more realistic measurement of latenciesencountered by RTSS applications.
The worst-case SRTM reported latencies range from 35 to 100 microseconds on mostPentium-based systems.
RTX User’s Guide
76
Using KSRTM (Kernel System Response Time Measurement)
Use KSRTM to measure timer response latencies and obtain reports and histograms of theresults.
This tool exercises the real-time HAL extension, and measures and reports timer responselatencies against a synchronized clock. It can present a histogram of such latencies and reportwhich kernel component was running when the longest latency event occurred. It can alsoprovide a list of drivers.
KSRTM optionally measures the latencies associated with kernel (DPC-level) andmultimedia (user-level) timers. It also allows the timer to drive the sound speaker (a 500-microsecond timer will generate a 1000 Hz square wave). Any timing jitter will produce anaudible frequency wobble.
Note: KSRTM only works in uniprocessor systems.
Usageksrtm -s 2
Formatksrtm [-r] [-k] [-m] [any of the following flags] seconds_to_sample
where
-r = Real-time HAL extension timer (default).
-k = Kernel (DPC-level) timer.
-m = Multimedia (user-level) timer.
-h = Histogram of latencies (in addition to summary).
-n = No use of real-time priorities.
-s = Sound output (square wave driven by timer).
-i = IRQL HIGH stalls (test interrupt isolation).
-c = Cache flush/dirty and TLB shoot down stalls.
-d = Display loaded driver information.
-l = Longest latency event information.
-u minutes = Minutes between display updates.
seconds_to_sample = Duration in seconds to sample timer response latencies.
See AlsoKSRTM versus SRTM
Chapter 5: Performance Overview
77
Using SRTM (System Response Time Measurement)
Use SRTM to measure timer response latencies.
By default, this tool generates a 15-second tone and prints a histogram of timer responselatencies. You can run SRTM in the RTSS environment to measure RTSS latencies or in theWin32 environment to measure Windows NT latencies.
UsageRTSSrun "c:\program files\vci\rtx\bin\samples\srtm" -h -f -s 15
You can also run SRTM using Windows NT Explorer by double-clicking the srtm.rtss icon(for RTSS environment) or the srtm.exe icon (for Win32 environment).
Formatsrtm [-h] [-s] [-1] [-f] seconds_to_sample
where
-h = Display histogram (in addition to summary).
-s = Turn on sound (square wave driven by timer).
-1 = Use a 10 ms timer period (default is 1 ms).
-f = Use fastest available timer (1 ms or better).
seconds_to_sample = Duration in seconds to sample timer latencies.
To build SRTM on your systemOptionally, you can build SRTM on your system (provided that you have a compiler on it) byentering the following commands at a command prompt:
cd \program files\vci\rtx\bin\samples\srtm nmake -f srtm.mak RTSSrun srtm.rtss -f -h -s 5
There should be no compile, link, or make errors. When you run srtm.rtss, you should hear asteady 1 KHz tone for five seconds.
See AlsoKSRTM versus SRTM
RTX User’s Guide
78
Using RTX Demo (Graphical version of SRTM)
RTX Demo graphically illustrates response time latencies in the Win32 and RTSSenvironments. It measures the total time to an RTSS, Windows NT, or Windows 2000program’s time handle (i.e., full thread context). It is a realistic measurement of latenciesencountered by an application.
RTX Demo runs an RTSS timer process, a Win32 timer process, or both processes at thesame time. It runs the process using either the fastest timer or a 1 ms timer. The timer canalso be used to drive a sound speaker. The results are plotted to the graphical area whereminimum, average, and maximum latency values are displayed. There are two types of plots:a plot showing the maximum latency values over time and a plot showing the raw data countsof maximum latency values for one sample period.
SettingsRun Timer As — Run an RTSS process, a Win32 process, or both processes at once. Thedefault is an RTSS process.
Sound Options — Choose to hear sound or not. The default setting is sound enabled. Ifrunning both types of processes, you can choose from which process to hear sound. You canalso change the sound options while the timer process is running.
Timer to Use — Choose either the fastest timer available or the 1 ms timer. This optioncannot be changed while the process is running.
Display Options — The Plot option displays graphs in the graphical output area. The defaultsetting is plot enabled at the start of a run. The Data option writes latency values to the dataarea. The default setting is data enabled at the start of a run. You can change these optionswhile the process is running.
Max Latency Y-axis Scale — This option is used with the Run Max Latency action only.The selectable values for the plot's y-axis scale are 100 ms, 1000 ms, and 10,000 ms. Thedefault is 100 ms. You cannot change this selection during data retrieval. This option isdisabled when running the histogram option.
ActionsRun Max Latency — Plots the maximum and average latency values at one-secondintervals. RTSS process results are plotted in cyan, Win32 results in red. The minimum,average, and maximum latency values are recorded in the data area.
Run Histogram — Plots the number of latency values occurring within 1 ms intervals. RTSSprocess results are plotted in cyan, Win32 results in red. The minimum, average, andmaximum values are recorded in the data area, along with the raw data for the histogram.
Stop — Stops the process.
Add Load — Simulates a disk load on the system in order to show more accurately themaximum latency times on a busy system. The load consists of a creating a file and writing toit repeatedly with no buffering.
Chapter 5: Performance Overview
79
Remove Load — Stops the "load" process.
Exit — Terminates the program.
To run RTX Demo
1. Start RTX Demo using one of these methods:
Choose RTX Demo from the RTX menu, or
Open the tool from the following directory: c:\programfiles\vci\rtx\bin\samples\rtxdemo
2. Select the type of process to run and which type of timer to use.
3. Click on either Run Max Latency or Run Histogram.
4. Once the process is running, you can change sound, plot, and data options. You canalso click:
Stop to terminate the SRTM process.
Add Load (if enabled) to simulate a disk load, and then Remove Load to stop it.
Exit to terminate RTX Demo.
Interpreting the Max Latency Plot
57;�'HPR��0D[�/DWHQF\�YLHZ
The x-axis shows time in seconds. The y-axis is the response time latency in microseconds.The solid line plots the maximum latency value in microseconds during a one-secondinterval. The dashed line plots the average latency value.
The x-axis shows time in seconds. The y-axis is the response time latency in microseconds.The solid line plots the maximum latency value in microseconds during a one-secondinterval. The dashed line plots the average latency value.
The data area records the minimum, average, and maximum latencies for the interval. It alsoshows the greatest maximum value over the course of the data retrieval (from clicking on theRun Max Latency button until clicking on the Stop button). RTSS latency values are shown
RTX User’s Guide
80
in cyan, Win32 values in red. When Win32 values are too high, they are plotted at the upperboundary of the window.
Interpreting the Histogram Plot
The x-axis shows response time latency in microsecond intervals. The y-axis shows a countfrom 0 to 2000 when using the fastest timer, 0 to 100 when using the 1 ms timer. Thehistogram shows the number of latencies that fell within a particular microsecond interval.
The raw data for the histogram is written to the data area, along with the minimum, average,and maximum values. The data is refreshed every second. RTSS latency values are shown incyan, Win32 values in red.
Using the Timer Latency Display Tool
The Timer Latency Display tool consists of:
A control and presentation application, which runs as an ordinary Windows NT task
� An RTSS application, which performs the timing measurements
These two tasks communicate through shared memory.
The RTSS task is similar to SRTM. The main execution thread creates an RTX timer, andsets it to expire periodically at the fastest available timer rate. The thread then enters a loop,testing a terminate request flag in shared memory, and sleeping between tests.
The timer function, which is called by RTSS each time the timer expires, reads the RTSSsystem clock, and computes the difference between the time observed, and the requestedscheduled time. A histogram of this difference is compiled in shared memory. The RTSS taskalso accumulates shortest and longest observed latencies.
SettingsEnable Sound — The timer function toggles the output state of the system speaker port eachtime it is called. Since the timer function is called periodically, this results in a tone with a
Chapter 5: Performance Overview
81
period equal to one half of the timer setting value. The system timer is set to 1 ms in thedemo, resulting in a 500 Hz tone.
Histogram — View the data as an accumulated histogram.
Latency — View a time sequence of minimum, maximum, and average values observed in aseries of 1-second intervals.
ActionsReset — Reset accumulated statistics.
To run the Timer Latency Display tool1. Open the following directory:
c:\program files\vci\rtx\bin\samples\latencydisplay
2. Double-click NtRTSS.rtss to start the timer program. The program starts with thesound enabled.
3. Double-click the display program, RTSSDisplay.exe. You can change settings forsound and view while the timer program is running.
4. Follow these steps, as appropriate:
To end the program — Terminate the client process and then exit from the displayprocess.To end the display process — Click the X button at the far right of the title bar.To terminate the timer process — Obtain the RTSS Process ID and then kill theprocess by typing the following command at a command prompt: RTSSkillTo obtain a list of the current RTX processes — Find the PID associated withNtRTSS.rtss and then type: RTSSkill ### (where ### is the PID).
Interpreting the Histogram
Timer Latency Display: Histogram view (Recorded on Gateway G5-233 233 MHzPentium)
The horizontal axis represents the time difference between scheduled and observed time, inmicrosecond units. The vertical axis represents a count of the number of times this difference
RTX User’s Guide
82
is observed to fall within a particular range, or ’bin.’ Counts are displayed on a logarithmicaxis. The histogram bin size is adjusted automatically to ensure that the highest observedlatency value is visible on the graph.
Interpreting the Latency display
Timer Latency Display: Latency view (Recorded on Gateway G5-233 233 MHzPentium)
The Latency view selects presentation of a time sequence of minimum, maximum, andaverage values observed in a series of one-second intervals. Latency is plotted on the verticalaxis. The horizontal axis is set to display the results accumulated over the past one-minuteinterval. A bright green vertical bar sweeps from left to right, illuminating the current second.
Using LTP (Latency Test Program)
Use LTP to find misbehaving peripheral devices.
This tool counts the number of instances in a given period of time that the time between clockreads exceeds a threshold value, using approximately 20% of the CPU time for the durationof the test. The latency is expected to be two to five microseconds. Higher latencies probablyindicate non-CPU related blocking.
UsageRTSSrun ltp -h
Formatltp [-t <num>] [-s <num>]
where
-t <num> = Watch for latencies greater than this number of microseconds; the default is10 microseconds.
-s <num> = Run the test for this number of seconds; the default is 20 seconds.
-h = Display message
83
APPENDIX A
Code and File ExamplesBus IO Programming Example
The following code fragment illustrates the Bus I/O calls in a PCI driver.
/*++ * * Copyright (c) 1996-1999 VenturCom, Inc. All rights reserved. * * Module Name: * * RtxLevelIntTest.c * * Abstract: * * Test code for processing level triggered interrupts * using the PCI-DIO-96 card. Developed from the pci test * and gmpt driver. * * Author: * * Environment: * * RTX RTSS application * * Revision History: * * Version 1 Jun 1 1998 --*/
#include <windows.h>#include <stdio.h>#include <rtapi.h>
//// Get and Set Long value macros.//#define PTL(x) (*(PLONG)(x))
/* DO NOT CHANGE PARAMETERS BELOW THIS POINT */#define BASE_ADDR _base_addr
/* PPI A */#define PORTA_ADDR ((PUCHAR) BASE_ADDR + 0x00) // Port A (Port 0)#define PORTB_ADDR ((PUCHAR) BASE_ADDR + 0x01) // Port B (Port 1)#define PORTC_ADDR ((PUCHAR) BASE_ADDR + 0x02) // Port C (Port 2)#define CNFG_ADDR ((PUCHAR) BASE_ADDR + 0x03) // Config Register
/* PPI B */#define B_PORTA_ADDR ((PUCHAR) BASE_ADDR + 0x04) // PPI B Port A (Port 3)#define B_PORTB_ADDR ((PUCHAR) BASE_ADDR + 0x05) // PPI B Port B (Port 4)#define B_PORTC_ADDR ((PUCHAR) BASE_ADDR + 0x06) // PPI B Port C (Port 5)#define B_CNFG_ADDR ((PUCHAR) BASE_ADDR + 0x07) // PPI B Config Port
/* PPI C */#define C_PORTA_ADDR ((PUCHAR) BASE_ADDR + 0x08) // PPI C Port A (Port 6)#define C_PORTB_ADDR ((PUCHAR) BASE_ADDR + 0x09) // PPI C Port B (Port 7)#define C_PORTC_ADDR ((PUCHAR) BASE_ADDR + 0x0A) // PPI C Port C (Port 8)#define C_CNFG_ADDR ((PUCHAR) BASE_ADDR + 0x0B) // PPI C Config Port
RTX User’s Guide
84
/* PPI D */#define D_PORTA_ADDR ((PUCHAR) BASE_ADDR + 0x0C) // PPI D Port A (Port 9)#define D_PORTB_ADDR ((PUCHAR) BASE_ADDR + 0x0D) // PPI D Port B (Port 10)#define D_PORTC_ADDR ((PUCHAR) BASE_ADDR + 0x0E) // PPI D Port C (Port 11)#define D_CNFG_ADDR ((PUCHAR) BASE_ADDR + 0x0F) // PPI D Config Port
/* Counter/Timer */#define CLOCKA ((PUCHAR) BASE_ADDR + 0x10) // Clock or Counter 0#define CLOCKB ((PUCHAR) BASE_ADDR + 0x11) // Clock or Counter 1#define CLOCKC ((PUCHAR) BASE_ADDR + 0x12) // Clock or Counter 2#define CLOCK_CTRL ((PUCHAR) BASE_ADDR + 0x13) // Clock or Counter Control
/* Interrupt control */#define INTR_CTRL1 ((PUCHAR) BASE_ADDR + 0x14) // First interrupt control reg#define INTR_CTRL2 ((PUCHAR) BASE_ADDR + 0x15) // Second interrupt control reg#define INTR_CLEAR (PUCHAR) BASE_ADDR + 0x16) // Interrupt Clear Register
//#define CNFG_VAL 0x80 // 1000 0000 - Port A Output Port B Output Port C Output//#define CNFG_VAL 0x90 // p 6-10 - Port A Input Port B Output Port C Output#define CNFG_VAL 0x15 // p 6-10 - Port A Input Port B Input Port C Input
// Note: Standard RTX time units are 100 ns long, or 10 units per microsecond.#define STOP_TIME 5 // Minutes for shutdown handler to wait
// after stopping before terminating. // 0 for indefinite.
#define BASE_ADDR _base_addr
/* respond: the interrupt handler */void _stdcall respond(PVOID addr);
/* fail: utility routine for fatal errors. */void fail(char *mesg);
/* shutdownh: the shutdown handler */void _stdcall shutdownh(PVOID dummy, long cause);
PCHAR _base_addr;
PCI_SLOT_NUMBER SlotNumber;PPCI_COMMON_CONFIG PciData;UCHAR buffer[PCI_COMMON_HDR_LENGTH];ULONG IntCountDown; // number of ints calls wait for clearingULONG IntCountTotal; // total int countULONG IntCountCLear; // total int clearedBOOLEAN IntDone; // when we are done
voidmain( int argc, PCHAR *argv ){ ULONG i; // logical slot number for the PCI adapter ULONG f; // function number on the specified adapter ULONG bytesWritten; // return value from RtGetBusDataByOffset ULONG bus; // bus number BOOLEAN flag;
LARGE_INTEGER BAR0; // base port address of the MITE LARGE_INTEGER BAR1; // base port address of the board registers LARGE_INTEGER tBAR0, tBAR1; // translated base addresses (system
// mapped addresses) returned by// RtMapMemory
ULONG AddressSpace = 0; // indicates memory space ULONG window_data_value = 0; // not really needed... PCHAR vBAR0=NULL, vBAR1 = NULL; // pointer virtual memory addresses
// returned by RtMapMemory ULONG IrqLevel; // interrupt level ULONG IrqVectr; // interrupt vector PVOID ihr; // interrupt handler
Appendix A: Code and File Examples
85
ULONG intbusnumb; // Interrupt bus number
BAR0.QuadPart = 0; BAR1.QuadPart = 0; tBAR0.QuadPart = 0; tBAR1.QuadPart = 0;
PciData = (PPCI_COMMON_CONFIG) buffer; SlotNumber.u.bits.Reserved = 0; flag = TRUE;
// // Search for the PCI-DIO-96 card // for (bus = 0; flag; bus++) { for (i = 0; i < PCI_MAX_DEVICES && flag; i++) { SlotNumber.u.bits.DeviceNumber = i;
for (f = 0; f < PCI_MAX_FUNCTION; f++) { SlotNumber.u.bits.FunctionNumber = f;
bytesWritten = RtGetBusDataByOffset ( PCIConfiguration, bus, SlotNumber.u.AsULONG, PciData, 0, PCI_COMMON_HDR_LENGTH ); if (bytesWritten == 0) { // out of PCI buses flag = FALSE; break; }
if (PciData->VendorID == PCI_INVALID_VENDORID) { // no device at this slot number, skip to next slot break; }
// // A device is found, if this is our card, then // print out all the PCI configuration information // and set the variables. // if ((PciData->VendorID == 0x1093) && (PciData->DeviceID == 0x0160)) { // Set IRQ values for attaching interrupt below IrqLevel = PciData->u.type0.InterruptLine; // interrupt level IrqVectr = IrqLevel; // interrupt IRQ
// Put the BusAddresses into other variables BAR0.QuadPart = PciData->u.type0.BaseAddresses[0];
// MITE address BAR1.QuadPart = PciData->u.type0.BaseAddresses[1]; // new board address intbusnumb = bus;
printf("\nPCI-DIO-96:\n"); printf("------------------------------------------\n"); printf("BusNumber:\t\t%d\n", bus); printf("DeviceNumber:\t\t%d\n", i); printf("FunctionNumber:\t\t%d\n", f); printf("VendorID:\t\t0x%x\n", PciData->VendorID); printf("DeviceID:\t\t0x%x\n", PciData->DeviceID);
RTX User’s Guide
86
printf("Command:\t\t0x%x\n", PciData->Command); printf("Status:\t\t\t0x%x\n", PciData->Status); printf("RevisionID:\t\t0x%x\n", PciData->RevisionID); printf("ProgIf:\t\t\t0x%x\n", PciData->ProgIf); printf("SubClass:\t\t0x%x\n", PciData->SubClass); printf("BaseClass:\t\t0x%x\n", PciData->BaseClass); printf("CacheLineSize:\t\t0x%x\n", PciData->CacheLineSize); printf("LatencyTimer:\t\t0x%x\n", PciData->LatencyTimer); printf("HeaderType:\t\t0x%x\n",PciData->HeaderType); printf("BIST:\t\t\t0x%x\n", PciData->BIST); printf("BaseAddresses[0]:\t0x%08x\n",PciData->u.type0.BaseAddresses[0]); printf("BaseAddresses[1]:\t0x%08x\n",PciData->u.type0.BaseAddresses[1]); printf("BaseAddresses[2]:\t0x%08x\n",PciData->u.type0.BaseAddresses[2]); printf("BaseAddresses[3]:\t0x%08x\n",PciData->u.type0.BaseAddresses[3]); printf("BaseAddresses[4]:\t0x%08x\n",PciData->u.type0.BaseAddresses[4]); printf("BaseAddresses[5]:\t0x%08x\n",PciData->u.type0.BaseAddresses[5]); printf("ROMBaseAddress:\t\t0x%08x\n",PciData->u.type0.ROMBaseAddress); printf("InterruptLine:\t\t%d\n",PciData->u.type0.InterruptLine); printf("InterruptPin:\t\t%d\n",PciData->u.type0.InterruptPin); printf("MinimumGrant:\t\t%d\n",PciData->u.type0.MinimumGrant); printf("MaximumLatency:\t\t%d\n",PciData->u.type0.MaximumLatency); printf("\n"); printf(" BAR0: BusRelativeAddress: 0x%08x\n", BAR0.LowPart); printf(" BAR1: BusRelativeAddress: 0x%08x\n", BAR1.LowPart);
// // Translate the base port addresses to system mapped addresses. // if (! RtTranslateBusAddress( PCIBus, 0, BAR0, &AddressSpace, &tBAR0 )) { fail ("tBAR0: RtTranslateBusAddress failed"); } else { printf("tBAR0: SystemMappedAddress: 0x%08x\n", tBAR0.LowPart); }
if (! RtTranslateBusAddress(PCIBus, 0, BAR1, &AddressSpace, &tBAR1 )) { fail ("tBAR1: RtTranslateBusAddress failed."); } else { printf("tBAR1: SystemMappedAddress: 0x%08x\n", tBAR1.LowPart); }
// // Map the addresses to virtual addresses the software can use //
vBAR0=RtMapMemory( tBAR0, 4*1024, 0); // 4K, cache disabled
if (vBAR0 == 0) { printf(" BAR0: Failure on RtMapMemory\nError=%d\n", GetLastError()); } else { printf(" BAR0: VirtualMemoryAddress: 0x%08x\n",vBAR0); }
Appendix A: Code and File Examples
87
vBAR1=RtMapMemory( tBAR1, 4*1024, 0); // 4K, cache disabled if (!vBAR1) { printf(" BAR1: Failure on RtMapMemory\nError=%d\n", GetLastError()); } else { printf(" BAR1: VirtualMemoryAddress: 0x%08x\n", vBAR1); }
// // Set the command parameter so we can access the PCI device’s // control registers. // PciData->Command = (PCI_ENABLE_IO_SPACE | PCI_ENABLE_MEMORY_SPACE | PCI_ENABLE_BUS_MASTER | PCI_ENABLE_WRITE_AND_INVALIDATE);
RtSetBusDataByOffset(PCIConfiguration, bus, SlotNumber.u.AsULONG, PciData, 0, PCI_COMMON_HDR_LENGTH); // // Initialize the card // No 1 MB limit - no need to remap the memory. // Note: You need to use the BusRelativeAddress to set the // window_data_value. // window_data_value = ( (0xffffff00 & (ULONG)BAR1.LowPart) | (0x00000080) );
PTL(vBAR0+0x000000c0) = window_data_value; }// dio 96 } // max_function } // max_devices } // flag
// // At this point the card has been found, memory mapped, so we go ahead // and attempt to utilize the card for testing // _base_addr=vBAR1; // Memory already mapped // Disable interrupts from I/O ports *(INTR_CTRL1) = 0x00; // Disable interrupts from counters *(INTR_CTRL2) = 0x00;
// // Attempt to attach to this interrupt, using data acquired above // ihr = RtAttachInterruptVector(NULL, // security attributes (default) 0, // stacksize (default) respond, // interrupt handler NULL, // context argument RT_PRIORITY_MAX, PCIBus, // interface type (PCI) intbusnumb, // bus number IrqLevel, // interrupt level IrqVectr); // interrupt vector}
See Also
Bus IO
RTX User’s Guide
88
Interrupt Management and Port IO Calls Programming Example
The following programming example demonstrates the use of RTX interrupt managementand port I/O calls.
// Generate an interrupt// with the digital outs
// Jumper any digital out [3-10] to IR INPUT [1]// Jumper GND [11] to IR ENABLE [2]
#include <windows.h>#include <rtapi.h>
#define CT_PORT ((unsigned char *) 0x340)#define CT_PORT_9513DATA	(CT_PORT + 0)#define CT_PORT_9513CMD	(CT_PORT + 1)#define CT_PORT_9513STATUS	(CT_PORT + 1)#define CT_PORT_DI	(CT_PORT + 2)#define CT_PORT_DO	(CT_PORT + 3)#define CT_PORT_SPACE (CT_PORT_DO - CT_PORT_9513DATA + 1)
#define CT_BASE_PORT_9513DATA(BASE) ((unsigned char *)((BASE) + 0))#define CT_BASE_PORT_9513CMD(BASE) ((unsigned char *)((BASE) + 1))#define CT_BASE_PORT_9513STATUS(BASE) ((unsigned char *)((BASE) + 1))#define CT_BASE_PORT_DI(BASE) ((unsigned char *)((BASE) + 2))#define CT_BASE_PORT_DO(BASE) ((unsigned char *)((BASE) + 3))
int ihc = 0 ;int ihc2 = 0 ;int limit = 30 ;
void RTFCNDCLInterruptHandler(void * unused){ RtWritePortUchar(CT_BASE_PORT_DO(CT_PORT), 0x00) ; inc + + ;}
int TestIncrease = 1 ;
main(){ HANDLE hInterrupt ;
int i ;
printf("Simple Interrupt Attach Handler Functional Test") ; // Enable CT range of ports if ( !RtEnablePortIo(CT_PORT, CT_PORT_SPACE)) { (void)printf("RtEnablePortIo(0x%x, 0x%x) failed\n", CT_PORT, CT_PORT_SPACE); return 1 ; }
// Attach the interupt vector to the interrupt handler hInterrupt = RtAttachInterruptVector(NULL, 0,
InterruptHandler, (void *)&TestIncrease, 1, 1, 0, 7, 7) ; if ( NULL == hInterrupt ) {
Appendix A: Code and File Examples
89
printf("Could not register interrupt handler (%d)\n", GetLastError()) ; return 2 ; }
for(i=0; i<limit; i++) { Sleep; // Pulse the interrupt RtWritePortUchar(CT_BASE_PORT_DO(CT_PORT), 0xff) ; } // Determine what happened. if ( limit != ihc ) { printf("FAIL\n") ; else { printf("Got %d interrupts\n", limit) ; } RtReleaseInterruptVector(hInterrupt) ; RtWritePortUchar(CT_BASE_PORT_DO(CT_PORT), 0) ;}
See Also
InterruptsPort IO
RTX User’s Guide
90
Makefile Sample
The following makefile is an annotated version of the one used to build srtm (a sampleprogram that measures timer response latencies).
## Copyright (c) 1996 - 1999 VenturCom, Inc. All rights reserved.## Module Name:## srtm.mak## Abstract:## nmakefile to build the SRTM demo as a RTSS process.#
# NODEBUG
# Define to remove debugging information in executable
NODEBUG = 1
# RTSS_CRT
# Define to link with RTSS single-threaded C run-time library
# RTSS_CRT = 1
# RTSS_MTCRT
# Define to link with RTSS multi-threaded C run-time library
# RTSS_MTCRT = 1
# Include rtx.mak for rules and linking flags necessary making
# RTSS executable files
!include <rtx.mak>
all: srtm.rtss
See Also
Using the RTX MakefileDebugging an RTX Program
Appendix A: Code and File Examples
91
Nmake Input File Example
The following is an example of an nmake input file which will build an RTDLL and Win32DLL from a single source file, thandler.c.
!include <rtx.mak>all: thandler.dll thankler.rtdllclean: -del thandler.obj thandler.dll thandler.rtdll
See Also
Creating Dynamic Link Libraries
RTX User’s Guide
92
RTDLL Code Example
This example implements the same functionality as the RTSS DLL example above using anRTDLL to provide the toggle() function. It is shown in four parts:
1. Simple RTDLL program source code
2. Simple RTSS application which loads the RTDLL and calls an exported subroutine
3. Makefile used to create the RTSS application and RTDLL
4. RTSSrun command used to register the RTDLL
RTDLL Part 1: sampleRtdll.c
#include "windows.h"#include "rtapi.h"
#define SPEAKER_PORT ((PUCHAR)0x61) //Port IO address for speaker#define GATE_BIT 0x02
//exported Rtdll Function__declspec ( dllexport )int _stdcall Toggle(int argc, char* argv[]){ UCHAR i; // Read PIT PORTB register i = RtReadPortUchar( SPEAKER_PORT);
// Check GATE bit i^= GATE_BIT;
// Write it to PIT PORTB RtWritePortUchar( SPEAKER_PORT, i); return 0;}
//DllMain must Explicitly return TrueBOOL WINAPI _stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){ return TRUE;}
RTDLL Part 2: usingRtdll.c
#include <windows.h>#include <stdio.h>#include <rtapi.h>
#define NO_ERRORS 0#define ERROR_OCCURRED -1#define SPEAKER_PORT ((PUCHAR)0x61) //Port IO address for speaker
FARPROC FunctionPtr = NULL;
int RTFCNDCL TimerHandler(PVOID unused){ //call Function Toggle FunctionPtr(0, NULL); return NO_ERRORS;}
Appendix A: Code and File Examples
93
/*** MAIN ****/int main(int argc, char* argv[]){ HANDLE hLibModule = NULL; HANDLE hTimer = NULL; LARGE_INTEGER time; LPCSTR lpLibFileName = "sampleRtdll.dll"; LPCSTR lpProcName = "_Toggle@8"; ULONG sleepTime = 10000;
//*********** Sample Code: usingRtdll ***********\\
//load Library sampleRtdll hLibModule = LoadLibrary(lpLibFileName);
//check if loadLibrary returned correctly if(hLibModule==NULL) { //error caused by loading a corrupt or unregistered Rtdll RtPrintf("UsingRtdll: ERROR: LoadLibrary() failed. Get last Error =%d\n",GetLastError()); RtPrintf("%s maybe corrupt or not registered with RTSS\n", lpLibFileName); return (ERROR_OCCURED); }
//Get function from Rtdll FunctionPtr = GetProcAddress(hLibModule, lpProcName);
//check if function was found if(FunctionPtr == NULL) { //error caused by nonexistent function name RtPrintf("UsingRtdll: Error: GetProcAddress() failed. Get Last Error =%d\n",GetLastError()); RtPrintf("The Function %s does not exist\n", lpProcName); //free library before exit FreeLibrary(hLibModule); return (ERROR_OCCURED); }
//Enable so Win32 can use PortIO if (! RtEnablePortIo(SPEAKER_PORT, 1)) { printf("UsingRtdll: Error: Could not enable Port IO\n"); FreeLibrary(hLibModule); return (ERROR_OCCURED); }
// Setup and start the periodic timer. hTimer = RtCreateTimer(NULL, 0, TimerHandler, NULL,RT_PRIORITY_MAX,CLOCK_FASTEST); //check if timer was created if(hTimer == NULL) { RtPrintf("UsingRtdll: ERROR: RtCreateTimer failed. Get Last Error =%d\n",GetLastError()); //free library before exit FreeLibrary(hLibModule); return (ERROR_OCCURED); }
time.QuadPart = 10000; // 1 milliscond interval
if (!RtSetTimerRelative( hTimer, &time, &time)) { RtPrintf("UsingRtdll: ERROR: Could not set and start the RTAPI timer.\n"); //free library before exit FreeLibrary(hLibModule); return (ERROR_OCCURED); }
RTX User’s Guide
94
// Wait for 10 seconds. Sleep(sleepTime);
// Stop and delete the timer. if(!RtDeleteTimer(hTimer)) { RtPrintf("UsingRtdll: ERROR: RtDeleteTimer failed. Get Last Error =%d.\nGetLastError()); //free library before exit FreeLibrary(hLibModule); return (ERROR_OCCURED); }
//free the Library before exiting Process if(!FreeLibrary(hLibModule)) { //error caused by an invalid Library handle RtPrintf("UsingRtdll: Error: FreeLibrary() failed. Get Last Error =%d\n",GetLastError()); return (ERROR_OCCURED); }
//the end return (NO_ERRORS);}
RTDLL Part 3: rtdll.mak
NODEBUG = 1RTSS_CRT = 1
!include <rtx.mak>
all: sampleRtdll.rtdll usingRtdll.rtss \ sampleRtdll.dll usingRtdll.exe
clean: -del *.rtdll -del *.lib -del *.obj
-del *.exp -del *.dll -del *.exe
RTDLL Part 4: Register the rtdll
C:\> RTSSRun /dll sampleRtdll
Appendix A: Code and File Examples
95
RTSS DLL Code Example
This programming example demonstrates a simple RTSS DLL that exports one function,toggle(), which toggles the state of the PC speaker. A timer is used to control the frequencywith which toggle() is called in order to generate a tone with a constant pitch. This example isshown in five parts:
1. Simple dll.c program
2. Definition file (dll.def)
3. Simple program which imports toggle() from dll.rtss
4. Makefile used to link dll.c
5. Win32 program to start the DLL and the application that uses it
RTSS DLL Part 1: dll.c
#include "windows.h"#include "rtapi.h"
#define SPEAKER_PORT ((PUCHAR)0x61) // Port IO address for speaker#define GATE_BIT 0x02
//// MAIN - just suspend the main thread for this process until its// use as a DLL is finished and the process is terminated.//int main(int argc, char **argv){ SuspendThread( GetCurrentThread()); return 0;}
//// The exported DLL function.//VOID_stdcallToggle(VOID){ UCHAR i;
i = RtReadPortUchar( SPEAKER_PORT); // Read PIT PORTB register
i ^=GATE_BIT; // Change GATE bit
RtWritePortUchar( SPEAKER_PORT, i); // Write it to PIT PORTB}
RTSS DLL Part 2: dll.def
LIBRARY DLL.RTSS
DESCRIPTION ’DLL RTSS’
EXPORTSToggle
RTX User’s Guide
96
RTSS DLL Part 3: dll-test.c
#include "windows.h"#include "stdio.h"#include "rtapi.h"
#define NO_ERRORS 0#define ERROR_OCCURRED -1
//// External function prototype.//VOID _stdcall Toggle(VOID);
//// Timer handler -- call the "Toggle" function.intRTFCNDCLTimerHandler(PVOID unused){ Toggle(); // Call the DLL exported function return NO_ERROR;}
//// MAIN -- start the timer and wait 10 seconds.//intmain( int argc, char *argv[]){ LARGE_INTEGER time; HANDLE hTimer; ULONG stackSize = 0; int waitTime = 10000; //10 seconds
// // Setup and start the periodic timer. // if (!(hTimer = RtCreateTimer( NULL, // Security - NULL is none stackSize, // Stack size - 0 is use default TimerHandler, // Timer handler NULL, // NULL context (argument to handler) RT_PRIORITY_MAX, // Priority CLOCK_FASTEST))) // Always use fastest available clock { printf("ERROR: Could not create the RTX timer.\n"); return (ERROR_OCCURED); }
time.QuadPart = 10000; // 1 milliscond interval
if (!RtSetTimerRelative( hTimer, &time, &time)) { printf("ERROR: Could not set and start the RTAPI timer.\n"); return (ERROR_OCCURED); }
// // Wait for 10 seconds. // Sleep(waitTime);
//
Appendix A: Code and File Examples
97
// Stop and delete the timer. // if (!RtDeleteTimer( hTimer)) { printf("ERROR: Could not Delete timer.\n"); return (ERROR_OCCURED); }
return (NO_ERRORS);}
RTSS DLL Part 4: dll.mak
NODEBUG = 1
!include <rtx.mak>
all: dll.rtss dll-test.rtss RunTest.exe
dll.rtss: dll.obj lib -nodefaultlib -machine:$(CPU) -out:dll.lib -def:dll.def dll.obj link $(rtsslflags) -out:dll.rtss dll.exp dll.obj $(rtsslibs) del dll.exp
dll-test.rtss: dll.lib dll-test.obj link $(rtsslflags) -out:$*.rtss $*.obj dll.lib $(rtsslibs)
clean: -del *.rtss -del *.obj -del *.exe -del dll.lib
RTSS DLL Part 5: runtest.c
#include "windows.h"#include "stdio.h"
#define NO_ERRORS 0#define ERROR_OCCURRED -1
//// Standard function to run a utility.//LONGRunUtility( PCHAR lpCmd ){ STARTUPINFO sinfo; PROCESS_INFORMATION pinfo; LONG exitCode = 0;
// // Initialize startup info to all zeros. // ZeroMemory(&sinfo, sizeof(sinfo)); sinfo.cb=sizeof(sinfo);
// // Create the process to run the utility. // if (CreateProcess(NULL, lpCmd, NULL, NULL, FALSE, 0, NULL,
RTX User’s Guide
98
NULL, &sinfo, &pinfo)==FALSE) { return (exitCode-1); }
// // Wait for the utility to complete. // WaitForSingleObject( pinfo.hProcess, INFINITE);
// // Get the exit code (RTSSrun returns the process slot) and close handles. // GetExitCodeProcess( pinfo.hProcess, &exitCode);
CloseHandle( pinfo.hThread); CloseHandle( pinfo.hProcess);
return exitCode;}
//// MAIN.//intmain( int argc, char *argv[]){ LONG dllPid, testPid; char buf[50]; int sleepTime = 5000; LONG exitCode = 0;
// // Load the RTSS DLL first. // dllPid = RunUtility("RTSSrun dll.rtss");
if (dllPid<=exitCode) { printf("DLL failed to load.\n"); return (ERROR_OCCURED); } // // Now run the test program. // testPid = RunUtility("RTSSrun dll-test.rtss");
if (testPid<=exitCode) { printf("DLL-TEST failed to run,\n"); return (ERROR_OCCURED); }
// // Sleep for 5 seconds and then terminate program and dll. // Sleep(sleepTime);
sprintf( buf, "RTSSkill %d", testPid); RunUtility( buf);
sprintf( buf, "RTSSkill %d", dllPid); RunUtility( buf);
return NO_ERROR;}
Appendix A: Code and File Examples
99
RTSS DLL Makefile Example
The following example shows a typical RTSS DLL makefile for dll.c.
NODEBUG = 1!include <rtx.mak>
all: dll.rtss
dll.rtss: dll.obj lib -nodefaultlib -machine:$(CPU) -out:dll.lib -def:dll.def dll.obj link $(rtsslflags) -out:dll.rtss dll.exp dll.obj $(rtsslibs) del dll.exp
clean: -del *.rtss -del *.obj -del *.exe -del dll.lib
See Also
Creating Dynamic Link Libraries
RTX User’s Guide
100
RTSSkill Examples
RTSSkill Example 1
The following example illustrates information provided by RTSSkill when run with noarguments for a system running an application called TimerTest which uses a single RTDLL.
RTSSkill
RTSS process list:
PID START STATE COMMAND 001 R TimerTest.rtss Timer_test2 002 003 004 005 006 007 008 009 010 /boot R w32_dll.rtss - Supplemental Win32 for C runtime library
RTSS Registered Dlls:
STATE NAMELoaded timer.rtdllNot Loaded foo.rtdll
RTSSkill Example 2
The following example illustrates information provided by RTSSkill 001 for the system in thepreceding example.
RTSSkill
RTSS process list:
PID START STATE COMMAND 001 R TimerTest.rtss Timer_test2 (terminated) 002 003 004 005 006 007 008 009 010 /boot R w32_dll.rtss - Supplemental Win32 for C runtime library
RTSS Registered Dlls:
STATE NAMENot Loaded timer.rtdllNot Loaded foo.rtdll
See Also
RTSSkill Utility
Appendix A: Code and File Examples
101
RTSSview Example
The following example illustrates information provided by RTSSview for a system runningan application called TimerTest, linked with the C run-time library. The unnamed mutexesare created by the C run-time initialization code.
============== RTSSview v4.3 ==============Object(ID) Address Information 15---------- ------- -----------Command w32_dll.rtss - Supplemental Win32 for C runtime library
Process(010) 806a3c28Thread(00004) 806a3cc8 Pri=0 Flags=1 State=Suspended
Command timertest.rtss Timer_test2Process(001) 805d6008Thread(0000c) 805d60a8 Pri=0 Flags=1 State=SleepingThread(0000d) 805ef490 Pri=15 Flags=0 State=WaitInternalTimer 805f9f10 Clock=1 Remain=7000us Interval=12000us
Command rtssview.rtssProcess(002) 805fad28Thread(0000e) 805fadc8 Pri=0 Flags=1 State=Ready
Mutexes: 805f18f0 Count=0 Owner=0 Name="** UNNAMED **" 805efb70 Count=0 Owner=0 Name="** UNNAMED **" 805ef6d0 Count=0 Owner=0 Name="** UNNAMED **" 805f0b70 Count=0 Owner=0 Name="** UNNAMED **" 805f06d0 Count=0 Owner=0 Name="** UNNAMED **" 805f3690 Count=0 Owner=0 Name="** UNNAMED **" 805f2b70 Count=0 Owner=0 Name="** UNNAMED **" 805f26d0 Count=0 Owner=0 Name="** UNNAMED **" 805f5b70 Count=0 Owner=0 Name="** UNNAMED **" 805f56d0 Count=0 Owner=0 Name="** UNNAMED **" 805d5010 Count=0 Owner=0 Name="** UNNAMED **" 805d5690 Count=0 Owner=0 Name="** UNNAMED **" 805beb70 Count=0 Owner=0 Name="** UNNAMED **" 805bb010 Count=0 Owner=0 Name="** UNNAMED **"
Dynamically Loaded Libraries: 805fa6b0 Count=-2141245552 Owner=805f2f98 Name="Timer.dll"
============== End RTSSview ==============
See Also
RTSSview Utility
RTX User’s Guide
102
RTX Contiguous Memory Allocation Calls Programming Example
The following programming example demonstrates the use of RTX contiguous memoryallocation calls.
#include <windows.h>#include <stdio.h>#include <rtapi.h>
static PVOID vAddress; // virtual memory address returned by // RtAllocateContiguousMemorystatic LARGE_INTEGER pAddress; // physical memory address returned by // RtGetPhysicalAddress
void main(void){
LARGE_INTEGER maxPhyAddr; //highest physical memory address ULONG size=0; //bytes to allocate
maxPhyAddr.QuadPart = 0xFFFFFF; size= 0x1000; // Size in KB.
// Allocate memory vAddress = RtAllocateContiguousMemory( size, maxPhyAddr); if (!vAddress) { printf("\nFailure on RtAllocateContiguousMemory\t"); printf("Error=%d\n", GetLastError()); break; } else { printf("\nSuccess on RtAllocateContiguousMemory\n"); printf("Virtual memory address = 0x%08X\n", vAddress);
// Get the physical address pAddress = RtGetPhysicalAddress(vAddress); if (!pAddress.QuadPart) { printf("\nFailure on RtGetPhysicalAddress(0x%08X).\t, vAddress"); printf("Error=%d\n", GetLastError()); } else { printf("Success on RtGetPhysicalAddress(0x%08X).\n", vAddress); }
// Free memory if (!RtFreeContiguousMemory(vAddress)) { printf("\nFailure on RtFreeContiguousMemory(0x%08X).\t", vAddress); printf("Error Code = %d\n", GetLastError()); } else { printf("Success on RtFreeContiguousMemory(0x%X).\n", vAddress); } } ExitProcess(0);}
See Also
Contiguous Memory Mapping
Appendix A: Code and File Examples
103
RTX Kernel Memory Locking Calls Programming Example
The following programming example demonstrates the use of RTX kernel memory lockingcalls.
#include <windows.h>#include <stdio.h>#include <rtapi.h>
void main(void) {
DWORD dwSections = RT_KLOCK_ALL; if (!RtLockKernel( dwSections)) { printf("\nFailure on RtLockKernel.\t"); printf("Error=%d\n", RtGetLastError()); } else { printf("\nSuccess on RtLockKernel\n"); if (!RtUnlockKernel( dwSections)){ printf("\nFailure on RtUnlockKernel.\t"); printf("Error=%d\n", RtGetLastError()); } else { printf("\nSuccess on RtUnlockKernel\n"); } } ExitProcess(0);}
See Also
System Memory Management
RTX User’s Guide
104
RTX Locked Memory Allocation Calls Programming Example
The following programming example demonstrates the use of RTX locked memory allocationcalls.
#include <windows.h>#include <stdio.h>#include <rtapi.h>
static PVOID vAddress; // virtual memory address returned byRtAllocateLockedMemoryvoid main(void) {
ULONG size=4096; // bytes to allocate
// Allocate memory vAddress = RtAllocateLockedMemory(size); if (!vAddress) { printf("\nFailure on RtAllocateLockedMemory\t"); printf("Error=%d\n", GetLastError()); break; // if this fails - no use to continue } else { printf("\nSuccess on RtAllocateLockedMemory\n"); printf("Virtual memory address = 0x%08X\n", vAddress);
// Write to the memory *vAddress= 0; }
// Free memory if (!RtFreeLockedMemory(vAddress)) { printf("\nFailure on RtFreeLockedMemory(0x%08X).\t", vAddress); printf("Error Code = %d\n", GetLastError()); } else { printf("Success on RtFreeLockedMemory(0x%X).\n", vAddress); } ExitProcess(0);}
See Also
System Memory Management
Appendix A: Code and File Examples
105
RTX Memory Mapping Calls Programming Example
The following programming example demonstrates the use of RTX memory mapping calls.
#include <windows.h>#include <stdio.h>#include <rtapi.h>
void main(void) { BOOL success=0; static PVOID vAddress; // virtual memory address returned LARGE_INTEGER physAddr; // base physical address ULONG length; // length to map in BOOLEAN cacheEnable; // cache accesses to memory ? physAddr.QuadPart = 0x0000FFFFF; length = 1024; cacheEnable = 0;
vAddress=RtMapMemory( physAddr, length, cacheEnable);
if (vAddress==NULL) { printf("Failure on RtMapMemory( 0x%08X, %d, %d ).\n", physAddr.LowPart, length, cacheEnable ); } else { printf("Success on RtMapMemory( 0x%08X, %d, %d ).\n", physAddr.LowPart, length, cacheEnable ); printf("Virtual memory address = 0x%08X \n", vAddress);
success = RtUnmapMemory( vAddress); if (!success) { printf("Failure on RtUnmapMemory( 0x%08X)\t", vAddress); } else { printf("Success on RtUnmapMemory( 0x%08X)\n\n", vAddress); } } ExitProcess(0);}
See Also
Physical Memory Mapping
RTX User’s Guide
106
RTX Process Memory Locking Calls Programming Example
The following programming example demonstrates the use of RTX process memory lockingcalls.
#include <windows.h>#include <stdio.h>#include <rtapi.h>
void main(void) {
DWORD dwSections = RT_PLOCK_ALL;
if (!RtLockProcess( dwSections)) { printf("\nFailure on RtLockProcess.\t"); printf("Error=%d\n", RtGetLastError()); } else { printf("\nSuccess on RtLockProcess\n");
if (!RtUnlockProcess( dwSections)) { printf("\nFailure on RtUnlockProcess.\t"); printf("Error=%d\n", RtGetLastError()); } else { printf("\nSuccess on RtUnlockProcess\n", i); } } ExitProcess(0);}
See Also
System Memory Management
Appendix A: Code and File Examples
107
RTX Timer and Sleep Calls Programming Example
The following example demonstrates the use of RTX timer and sleep calls.
#include "windows.h"#include "stdio.h"#include "rtapi.h"
//// Local data.//LARGE_INTEGER Period; // Timer periodLARGE_INTEGER StartTime; // Start time of sampling runULONG TimerCounter = 0; // Counts entries to timer handler
////VOIDmain(int argc, char **argv){ LARGE_INTEGER x; HANDLE hTimer;
// // Set default timer period to 500 micro seconds // Period.QuadPart = 5000;
// // Set to the next to highest real-time priority. // if (!RtSetThreadPriority( GetCurrentThread(), RT_PRIORITY_MAX-1)) printf("WARNING: Can’t set to highest RTAPI priority.\n"); // // Setup and start the periodic timer. // if (!(hTimer = RtCreateTimer(
NULL, // Security - NULL is none0, // Stack size - 0 is use defaultTimerHandler, // Timer handlerNULL, // NULL context (argument to handler)RT_PRIORITY_MAX, // PriorityCLOCK_2))) // RTX HAL Timer
{ printf("ERROR: Could not create the RTAPI timer.\n"); ExitProcess(2); }
if (!RtSetTimerRelative( hTimer, &Period, &Period)) { printf("ERROR: Could not set and start the RTAPI timer.\n"); ExitProcess(2); }
// // Wait for the sampling time. // Sleep(1000);
// // Stop and delete the timer. // RtCancelTimer( hTimer, &x); RtDeleteTimer( hTimer);
printf(" Value of number of timers counter is %d\n",TimerCounter); ExitProcess(0);
RTX User’s Guide
108
}
//// timer handler function// - increment the tick counter//intRTFCNDCLTimerHandler( PVOID unused ){ TimerCounter++; return 0 ;}
See Also
Clocks and Timers
109
IndexB
Book Overview, 33
C
C Run-time Library Functions, 59Using, 59
CENTer, xControl Panel, 30CreateFile, 53
D
Debugging, 4, 21, 30RTSS, 4
Developer Studio 5.0, 21Developing RTX Applications, 4Device Management, 33DMA, 52, 75Documentation Updates, x
E
Event Objects, 46Exception Handling, 60
General User Notes, 60
F
Floating-Point Support, 59FreeLibrary, 92
G
GetCurrentProcess, 34GetExceptionCode, 60GetExceptionInformation, 60Graphical version
SRTM, 78
H
HAL, 30, 40HAL Timer Period, 30HalTimerPeriod, 40Histogram, 78Histogram Plot, 78
Interpreting, 78
I
Interprocess Communication, 33Inter-Process Communication, 43, 46Interrupt Latencies, 74
Management, 74RTX Management, 74
Interrupt Management, 48Interrupt Service Routine, 48Interrupt Service Thread, 48Interrupts, 48IPC, 1ISR, 48Issue
Green Screen, 63IST, 48
attach, 48set, 48
K
Kernel System Response Time Measurement,75
KSRTM, 75KSRTM versus SRTM, 75
L
Latency, 75Latency Test Program, 75, 82
M
Max Latency Plot, 78Interpreting, 78
Microsoft Developer Studio 5.0, 21Microsoft Visual Studio, 21Microsoft Visual Studio 6.0, 21Mutex, 43
O
Object Names, 43
P
Port I/O Calls, 48Power Management, 74Process Exception Disposition, 70Programming, 70
Techniques/Considerations, 70
R
Real-Time Inter-Process Communication, 1RtAllocateContiguousMemory, 102RTAPI, 95RtAttachInterruptVector, 48RtCancelTimer, 107
RTX User’s Guide
110
RtCreateTimer, 95, 107RtDeleteTimer, 95, 107RTDLLs, 8, 15, 57, 100
Register, 8Unregister, 8
RtFreeContiguousMemory(vAddress, 102RtGetBusDataByOffset, 83RtGetLastError, 103, 106RtGetPhysicalAddress, 102RtLockKernel, 103RtLockProcess, 106RtMapMemory, 83RtSetThreadPriority, 107RtSetTimerRelative, 107RTSS, 4, 7, 34, 78
building, 7debugging, 4launch, 4Running, 34starting, 4, 34use, 34Win32 Thread Priority Mapping, 34
RTSS application, 59RTSS Device Drivers, 59
Writing, 59RTSS DLLs, 25, 57, 59
Building, 25create, 25designing, 57use, 25
RTSS Exception Handling, 60RTSS Object Viewer, 13RTSS Process, 4, 15
Starting, 4Stopping, 4
RTSS Programs, 59RTSS Task Manager, 4, 15, 34RTSS Task Manager window, 15RTSS Thread Priority Mapping, 34RTSSkill, 4, 30, 34RTSSkill Examples, 100RTSSkill Utility, 11RTSSrun, 11, 34, 77, 95RTSSrun Console, 9RTSSrun GUI, 9RTSSrun Utility, 9RtTranslateBusAddress, 83RtUnlockKernel, 103RTX API, 60RTX AppWizard, 7RTX Demo, 75RTX Device Drivers, 4RTX Exception Codes, 63RTX Exception Handling, 64RTX Functionality, 33
Using, 33
RTX Green Screen, 62, 65RTX HAL Timer, 107RTX Inter-Process Communication, 34RTX Kernel Memory Locking Calls, 37RTX Locked Memory Allocation Calls, 37RTX Makefile, 29, 56RTX Memory Mapping Calls, 51RTX Power Management, 71
Windows 2000, 71RTX Process Memory Locking Calls, 37RTX Settings, 70RTX Settings icon, 30RTX Startup, 30RTX Timer, 107RTX Utilities, 7RTX-defined, 70RtxServer, 16Run
Timer Latency Display tool, 80
S
Select, 65Automatically Reboot, 65
Semaphores, 8, 44Service Request Interrupt, 70SetErrorMode, 60Setting
Starvation Time Out, 70Starvation Time Out Period, 70
SetUnhandledExceptionHandler, 60Shutdown Handlers, 29Shutdown Program, 29Sleep Calls, 40Sleep Calls Programming Example, 107Sleep Services, 40SRTM, 75, 77Starvation Management, 70Structured Exception Handling, 60, 62, 63Support ID, ixSystem Exception Handling, 62System Memory Allocation, 37System Memory Locking, 37System Memory Management, 37System Response Time Measurement, 75
T
Technical Support, ixTechnical Support Area, ixTesting, 4
Real-Time Applications, 4Thread Management, 33Timer Latency Display, 75Timer Latency Display Tool, 75, 80TimerHandler, 95Tools Overview, 75
Index
111
U
UseRTSSkill, 70RTX, 70
Using LTP, 82Using RTX Demo, 78Using Software Development Tools, 7
V
VenturCom Customer Support Web, ixVenturCom Web site, ix
W
Watchdog Management, 70Watchdog Timer, 70Win32 application, 59
develop, 59Win32 Platform SDK, 60Win32 SDK Tools, 26Win32 Structured Exception Handling, 60Win32Debug, 21WinDbg, 26, 66WinDbg 4.0, 26WinDbg 5.0, 26Windows 2000 Stop Messages, 65Windows 2000 Stop Screens, 68Windows NT Automatically Reboot, 65Windows NT Blue Screen, 65, 66Windows NT Blue Screen Stop Messages, 66
Interpreting, 66Windows NT Control Panel, 65, 66Write Debugging Information, 66