Implementation of the Variable Tick Scheduler (Windows Embedded CE 6.0)

1/5/2010

The variable tick scheduler enables OEMs to generate a timer interrupt only when required by the Windows Embedded CE scheduler. In previous versions of Windows Embedded CE, the OEM timerISR is set at every millisecond. If there is no thread that needs scheduling, the timerISR is set to sys-int-nop and goes back to sleep. This means that the system wakes up every millisecond and then goes back to sleep.

In Windows Embedded CE, the kernel calls pOEMUpdateRescheduleTime to set the time before calling OEMIdle. For example, if 100 milliseconds is passed to pOEMUpdateRescheduleTime, you are setting the timer tick to wait 100 milliseconds to prevent it from waking up every millisecond.

The variable tick scheduler is backward compatible. If you choose not to use this functionality, the OAL does not require any change.

If you choose to use the Windows Embedded CE variable tick scheduler, you must update a set of timer-related functions. You must also update pOEMUpdateRescheduleTime to point to a function that you implemented that reprograms the system timer to interrupt at the time required by the scheduler.

For more information on how to implement the variable tick scheduler, see the following procedure.

Note

The procedure uses MIPS-specific examples to demonstrate each step and provide more information.

To implement the variable tick scheduler

  1. Set up some constants.

    For example, you need to set up these SOC (system-on-chip) required constants: OEMTimerFreq and OEMMinTickDistance.

  2. Implement a function to update reschedule time and to update the function pointer pOEMUpdateRescheduleTime.

    In the sample MIPS and XScale implementations, NextINTMSec is assigned as the millisecond value next time a timer interrupt occurs.

    The pOEMUpdateRescheduleTime function passes in a millisecond value, which you can evaluate to make sure it is not smaller than 1 millisecond or larger than the maximum milliseconds that the timer counter can handle.

    You can then update the corrected millisecond value to NextINTMSec and then update NextINTMSec to the timer compare register for the next interrupt.

  3. Change the following timer-related functions to handle the variable tick correctly.

    1. SC_GetTickCount must reflect the real system tick, instead of only returning CurMSec.
    2. OEMIdle becomes simpler and only the following functionality needs to be implemented:
      - Call CPUEnterIdle routine to put the CPU in power saving mode.
      - Turn off interrupts when returning from the CPUEnterIdle function.
      - Calculate the idle time by updating the curridlelow and curridlehigh variables.
    3. InitClock function should be called in OEMInit.
      To initialize the clock correctly, do the following:
      - Assign the following derived constants from OEMTimerFreq. You can change the names of these constants depending on your design:
      *   MIPSCount1MS* = OEMTimerFreq/1000;      // 1 millisecond
      *   MIPSMaxSchedMSec* = nMaxSchedMSec = 0x7FFFFFF/MIPSCount1MS   // Maximum millisecond represented by 32 integer
      *   LastINTMSec
      = CurMSec
      *   NextINTMSec
      = LastINTMSec + nMaxSchedMSec;
      *   CurTicksLowPart* = <Current OS timer counter value>
         idleconv = MIPSCount1MS;
      - Map the following function pointers:
      *   *pQueryPerformanceCounter = OEMQueryPerformanceCounter;
      *   *pQueryPerformanceFrequency = OEMQueryPerformanceFrequency;
      *   *pOEMUpdateRescheduleTime = MIPSUpdateReschedTime;
    4. PerfCountFreq has changed to OEMTimerFreq.
    5. PerfCountSinceTick returns the difference between the current system timer counter value and the counter value at last timer interrupt.
    6. OEMQueryPerformanceCounter updates the function pointer pQueryPerformanceCounter.
      Like PerfCountSinceTick, the OEMQueryPerformanceCounter function also sets the current performance count value.
    7. OEMQueryPerformanceFrequency updates the function pointer pQueryPerformanceFrequency.
      The OEMQueryPerformanceFrequency function now assigns OEMTimerFreq as the performance counter frequency.

Remarks

Implementing the variable tick scheduler is not a simple task. To help with the implementation process, Windows Embedded CE provides a standard implementation in the system-on-chip (SOC) for all CPUs that meet the hardware requirement. These CPUs are SH4, XScale, and MIPS.

You can see a sample implementation for all MIPS, Intel XScale, and SH4 BSPs in Platform Builder. For other CPUs, you can reference the MIPS implementation if you have a count-and-compare system timer, or the SH4 implementation if you have a countdown system timer.

Common variable tick scheduler source code may be found at this location:

%_WINCEROOT%\Platform\Common\Src\Common\Timer\Vartick.

See Also

Reference

pOEMUpdateRescheduleTime

Concepts

OEM Adaptation Layer