|
By sharing a system with Windows, RTX enables developers to take advantage of components and services provided by Windows without depending on those components and services for critical real-time tasks. Even after a blue screen (or a STOP message in Windows), the RTX subsystem continues to run, and any application or driver built on RTX and/or RT-TCP/IP can also continue to run.
Windows can call KeBugCheck for many reasons, such as a disk failing or bad pointers being called. Provided the failure is not a complete hardware failure such as the CPU failing, which is rare, RTX will continue to run even after a KeBugCheck is called. All RTSS processes continue to perform real-time tasks, but can only perform real-time tasks. Since services and components provided by Windows are no longer available, the RTSS processes that need to keep running cannot call on Windows.
In the event KeBugCheck is called:
Device drivers can register to be informed when a bug-check occurs. They are supposed to checkpoint state in memory so that determining the cause is easier.
The goal is to cycle the equipment to a safe state or allow the real-time application to run for some reasonable time after Windows has bug-checked.
NOTE: In the RTX Properties control panel (System tab, Behavior setting), you can configure the behavior of Shutdown print handling to one of these values: Always, On Demand, or Not at All.
See Shutdown Handling for additional information.
In a real-time system, all critical tasks are handled by RTX, and monitoring and other tasks are handled by Windows. Making a call to Windows after a blue screen has occurred will hang the thread or process that calls it because the OS is no longer available to handle requests. Care must be taken to avoid calling APIs that RTX cannot directly process. In general, any API that is deterministic will work after a blue screen. However, there are also some non-deterministic functions that are designed to work after blue screen, such as printf. When attaching shutdown handlers to your applications and drivers, adhere to the following:
NOTE: RTX supports a local memory pool that you can enable by opening the RTX Properties control panel and accessing the Memory tab. After this memory pool has been enabled, you can make allocations from the pool after the Windows STOP message appears until the memory pool has been used up.
A FAT or FAT32 file system requires a file system check after a blue screen. NTFS partitions do not require this check.
Attach a shutdown handler to process each process that needs to be running after the blue screen. That process and all threads created by that process will continue to run after the blue screen.
Attaching a shutdown handler will keep the process, and any threads created by the process, running after a normal shutdown or a blue screen.RTX systems typically perform all initialization, memory allocation, and non-deterministic processing at the beginning of the process, before time-critical processing begins. This is especially important when using shutdown handlers, because non-deterministic functions will not be accessible after a blue screen (and would hang the thread/process). You can design routines to be aware of the state of the system, alerting them that a blue screen has occurred by pulsing an event, changing a variable, or using some similar technique.The main process should not close before the shutdown handler returns. This would prevent the shutdown handler from returning and hang the process.
main() { BOOL bBlueScreen = FALSE; RtCreateEvent()… CreateThread()… RtAttachShutdownHandler()… Sleep(INFINITE); // until shutdown handler returns }
After normal shutdown or blue screen, the shutdown handler function begins. Typically, the body of this thread alerts the process and its threads that a shutdown occurs, and their behavior changes accordingly. When necessary processing is completed, the shutdown handler returns. Here, RtPulseEvent is called to notify any sleeping thread or other routine that a shutdown has occurred. The sample program rtxtcpserver changes the value of a global variable to prevent routines from creating threads.When the shutdown handler returns, the attached process and all its threads will terminate. You must include some mechanism that keeps the shutdown handler open until processing is complete.
ShutdownHandler()
{
// when shutdown occurs,
// pulse event
RtPulseEvent()
// or set a global variable
bBlueScreen = TRUE;
// continue other processing, but
// keep ShutdownHandler open
RtWaitForSingleObject()
}
This thread waits for an event to be triggered in the shutdown handler. Although threads cannot be created after a blue screen, you can create threads that don't begin processing until a blue screen occurs.
Thread1()
{
// wait until event is
// triggered
RtWaitForSingleObject()
// shutdown occurred,
// begin cleanup
}
It is not necessary (or possible) to close handles or destroy objects while in RTX Shutdown mode. Since memory can no longer be allocated, the memory used by these objects will not be needed and this kind of cleanup is not necessary. But care must be taken not to make requests to Windows, since the OS is no longer available and calls to it will hang the calling process or thread.
For cleanup, you may want to place any destructors, close handles, and exit functions after code similar to the following:
if (bBlueScreen==TRUE)
Sleep(INFINITE); // no destructors or process exits allowed
During system initialization, if a critical component cannot be initialized you can release the shutdown handler by calling RtReleaseShutdownHandler.
if (!(hTimer = RtCreateTimer( NULL, stackSize, default TimerHandler, NULL, RT_PRIORITY_MAX, CLOCK_FASTEST)))
{
printf("Shutdown: Error: Could not create the timer. GetLastError = %d\n", GetLastError());
RtReleaseShutdownHandler(hShutdown);
return ERROR_OCCURRED;
}