The entire executive will compile and run under Windows without modification, and additionally requires the module ‘ExecWin.c’ which defines Windows-specific functionality.
The Windows-specific file has been designed for compilation under Microsoft Visual C/C++, although it may work with other Windows C compilers.
The executive and application must be compiled and linked using the multithreaded C libraries (a non-default option in Microsoft C/C++).
The execAppIdle() function must call the execSafeCpuIdle() function, because shutdown of the executive is performed from this function (and it also allows the proper yielding of execution in the Windows pre-emptive multitasking environment). Without this, the executive will not function properly under Windows.
The execAppCurrentTick(), execAppResyncTimer() functions and the equivalent of the timer interrupt routine is implemented within the Windows module and should not be defined in the application (use #ifndef _WIN32 in the embedded application code to prevent any embedded application-provided versions of these from being compiled under Windows). The size of the timer tick (in integral multiples of 100 nanoseconds) is assigned when starting up the executive under Windows, and thus an application designed for embedded use may run in a simulated environment under Windows in real time. (Note that the timer system under Windows 95, and subsequent DOS-based versions of Windows, may be using with 18ms DOS timer interrupt. Although cumulative errors may be minimal, precise short time delays may not be achievable).
Use the execWinStart() and execWinQuit() functions to start and stop the executive. The executive may be started and stopped on multiple occasions during the run time of a program, and each time the executive is started, it completely re-initialises itself.
Once started, the executive runs in a background thread. This means that the foreground part of the program, which started it, behaves towards it as if it were an interrupt routine. Therefore, from the foreground thread (typically consisting of Windows GUI event handling functions), only use functions which are safe to be called from within interrupt routines, such as execPostEvent(), unless the entire executive is explicitly locked.
The executive may be locked and unlocked using execWinLockExec() and execWinUnLockExec(). Locking the executive waits until the executive is idling before locking out the executive’s thread. The executive’s thread is then blocked until the executive is unlocked.
Only one instance of the executive may run at any one time, and calling execWinStart() multiple times without corresponding calls to execWinQuit() will have no effect.
If VCONST (variable constants) is defined in the compile options, then the executive may be re-configured at run time. Clearly, it is inadvisable to alter the structure of the application, which runs under the executive, while the executive is running.
When running under Windows, the executive additionally requires the application to provide the function execAppFinish(). This is called as the last item when the executive shuts down, after all outstanding events have been processed.
void execWinLockExec ();
This function is used to lock the executive thread so that another thread can safely access any variables belonging to an application running under the executive.
This function waits until the executive is idling before locking the thread and returning. If the executive is continually processing events, then this function will never return.
For each call of this function, there must be a corresponding call to execWinUnLockExec(), otherwise the executive will be permanently locked out and will also never exit safely.
boolean execWinStart (lword TickSize, lword StackSize, slword Priority);
Parameters: TickSize the size of the timer tick in 100ns intervals
StackSize the size of the stack used by the executive’s thread
Priority the priority of the executive’s thread
Returns: true if it succeeded or false if it failed. It will fail an instance of the executive is already running or if any of the Windows resources used by the executive fail to be created.
This function starts the executive in a background thread in the Windows environment.
Setting a tick size of zero will allocate a 1 millisecond timer tick.
Setting a stack size of zero will allocate a default stack size, which will be the same as the main foreground application’s stack size.
Setting a priority of zero will select ‘normal’ priority which is the default thread priority under the process priority of the current application. Use the appropriate Windows manifest constants for thread priority assignment.
boolean execWinQuit (lword Timeout);
Parameters: Timeout time in milliseconds to wait for termination
Returns: true if it succeeded or false if it failed. It will fail if the executive is not running.
This function causes the executive to shut down in an orderly fashion. Firstly, the timer thread shuts down so that no more timer events are posted, and then all events are processed, before the executive itself finally exits.
If the timeout time is reached before the executive has fully shutdown, its thread is immediately terminated, and various items in the system associated with the thread may be left in an indeterminate state. Therefore, timing out should be considered as a very last resort, and the timeout should be very long or INFINITE (manifest constant).
This function unlocks the executive thread and allows its event processing to continue.
It should be called after a corresponding call to execWinLockExec().