os_cpu_c.c
上传用户:tkwrx3909
上传日期:2015-10-06
资源大小:3310k
文件大小:28k
源码类别:

uCOS

开发平台:

Visual C++

  1. /*
  2. *********************************************************************************************************
  3. *                                               uC/OS-II
  4. *                                        The Real-Time Kernel
  5. *
  6. *                                         Win32 Specific code
  7. *
  8. * This is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. *
  11. * File : OS_CPU_C.C
  12. * By   : Vladimir Antonenko
  13. *********************************************************************************************************
  14. */
  15. #define  OS_CPU_GLOBALS
  16. #include "includes.h"
  17. #include "os_trace.h"
  18. #include <windows.h>
  19. #include <mmsystem.h>
  20. #if 0
  21. #define    USE_CRITICAL_SECTION                                                /* use Win32 critical sections                                                              */
  22. #endif
  23. #define    ALLOW_CS_RECURSION                                                  /* allow recursion of critical sections                                                     */
  24. #define    SET_AFFINITY_MASK                                                   /* must be used for miltiprocessor systems                                                  */
  25. #define    OS_CPU_TRACE                                                        /* allow print trace messages                                                               */
  26. #define     WIN_MM_TICK                                                        /* Enabling WIN_MM_TICK will cause the uC/OS-II port to use the high resolution Multimedia  */
  27.                                                                                /* timer instead of Sleep.  The higher resolution timer has a resolution of 1 ms, which     */
  28.                                                                                /* results in a much more "real-time" feel - jdf                                            */
  29. #define     WIN_MM_MIN_RES (1)                                                 /* Minimum timer resolution                                                                 */
  30. /*
  31. *********************************************************************************************************
  32. *                                                    Prototypes
  33. *********************************************************************************************************
  34. */
  35. DWORD WINAPI OSCtxSwW32( LPVOID lpParameter );
  36. DWORD WINAPI OSTickW32 ( LPVOID lpParameter );
  37. DWORD WINAPI OSTaskW32 ( LPVOID lpParameter );
  38. /*
  39. *********************************************************************************************************
  40. *                                                    Globals
  41. *********************************************************************************************************
  42. */
  43. INT32U              OSTerminateTickW32     = 0;
  44. INT32U              OSTerminateCtxSwW32    = 0;
  45. INT32U              OSTerminateTickCtrlW32 = 0;
  46. HANDLE              OSTick32Handle;
  47. HANDLE              OSCtxSwW32Event;
  48. HANDLE              OSCtxSwW32Handle;
  49. #ifdef WIN_MM_TICK
  50. HANDLE              OSTickEventHandle;
  51. DWORD               OSTickTimer;
  52. TIMECAPS            OSTimeCap;
  53. #endif
  54. CRITICAL_SECTION    OSCriticalSection;
  55. HANDLE              OSSemaphore;
  56. OS_EMU_STK          *SS_SP;
  57. #ifdef ALLOW_CS_RECURSION
  58.     DWORD           ThreadID = 0;
  59.     int             Recursion = 0;
  60. #endif
  61. /*
  62. *********************************************************************************************************
  63. *                                       OS INITIALIZATION HOOK
  64. *                                            (BEGINNING)
  65. *
  66. * Description: This function is called by OSInit() at the beginning of OSInit().
  67. *
  68. * Arguments  : none
  69. *
  70. * Note(s)    : 1) Interrupts should be disabled during this call.
  71. *********************************************************************************************************
  72. */
  73. void OSInitHookBegin(void)
  74. {
  75. #ifdef USE_CRITICAL_SECTION
  76.     InitializeCriticalSection(&OSCriticalSection);
  77. #else
  78.     OSSemaphore = CreateSemaphore( NULL, 1, 1, NULL );
  79. #endif
  80. }
  81. /*
  82. *********************************************************************************************************
  83. *                                       OS INITIALIZATION HOOK
  84. *                                               (END)
  85. *
  86. * Description: This function is called by OSInit() at the end of OSInit().
  87. *
  88. * Arguments  : none
  89. *
  90. * Note(s)    : 1) Interrupts should be disabled during this call.
  91. *********************************************************************************************************
  92. */
  93. void OSInitHookEnd(void) {}
  94. /*
  95. *********************************************************************************************************
  96. *                                                    OS_INIT_CRITICAL()
  97. * Initialize code necessary for WIN32 implementation 
  98. * of ENTER and EXIT CRITICAL routines.
  99. *********************************************************************************************************
  100. */
  101. void OS_INIT_CRITICAL()
  102. {
  103. #ifdef USE_CRITICAL_SECTION
  104.     InitializeCriticalSection(&OSCriticalSection);
  105. #endif
  106. }
  107. /*
  108. *********************************************************************************************************
  109. *                                                    OS_ENTER_CRITICAL()
  110. * Defines the beginning of a critical section of code.
  111. *********************************************************************************************************
  112. */
  113. void OS_ENTER_CRITICAL()
  114. {
  115. #ifdef USE_CRITICAL_SECTION
  116.     EnterCriticalSection(&OSCriticalSection);
  117. #else
  118. #ifdef ALLOW_CS_RECURSION
  119.     if( WaitForSingleObject( OSSemaphore, 0 ) == WAIT_TIMEOUT )
  120.     {
  121.         if( GetCurrentThreadId() != ThreadID )
  122.             WaitForSingleObject( OSSemaphore, INFINITE );
  123.     }
  124.     ThreadID = GetCurrentThreadId();
  125.     ++Recursion;
  126. #else
  127.     WaitForSingleObject( OSSemaphore, INFINITE );
  128. #endif
  129. #endif
  130. }
  131. /*
  132. *********************************************************************************************************
  133. *                                                    OS_EXIT_CRITICAL()
  134. * Defines the end of a critical section of code.
  135. *********************************************************************************************************
  136. */
  137. void OS_EXIT_CRITICAL()
  138. {
  139. #ifdef USE_CRITICAL_SECTION
  140.     LeaveCriticalSection(&OSCriticalSection);
  141. #else
  142. #ifdef ALLOW_CS_RECURSION
  143.     if( Recursion > 0 ) {
  144.         if(--Recursion == 0 ) {
  145.             ThreadID = 0;
  146.             ReleaseSemaphore( OSSemaphore, 1, NULL );
  147.         }
  148.     }
  149.     else {
  150. #ifdef OS_CPU_TRACE
  151.     OS_Printf("Error: OS_EXIT_CRITICALn");
  152. #endif
  153.     }
  154. #else
  155.     ReleaseSemaphore( OSSemaphore, 1, NULL );
  156. #endif
  157. #endif
  158. }
  159. /*
  160. *********************************************************************************************************
  161. *                                        INITIALIZE A TASK'S STACK
  162. *
  163. * Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the
  164. *              stack frame of the task being created.  This function is highly processor specific.
  165. *
  166. * Arguments  : task          is a pointer to the task code
  167. *
  168. *              pdata         is a pointer to a user supplied data area that will be passed to the task
  169. *                            when the task first executes.
  170. *
  171. *              ptos          is a pointer to the top of stack.  It is assumed that 'ptos' points to
  172. *                            a 'free' entry on the task stack.  If OS_STK_GROWTH is set to 1 then 
  173. *                            'ptos' will contain the HIGHEST valid address of the stack.  Similarly, if
  174. *                            OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address
  175. *                            of the stack.
  176. *
  177. *              opt           specifies options that can be used to alter the behavior of OSTaskStkInit().
  178. *                            (see uCOS_II.H for OS_TASK_OPT_???).
  179. *
  180. * Returns    : Always returns the location of the new top-of-stack' once the processor registers have
  181. *              been placed on the stack in the proper order.
  182. *
  183. * Note(s)    : Interrupts are enabled when your task starts executing. You can change this by setting the
  184. *              PSW to 0x0002 instead.  In this case, interrupts would be disabled upon task startup.  The
  185. *              application code would be responsible for enabling interrupts at the beginning of the task
  186. *              code.  You will need to modify OSTaskIdle() and OSTaskStat() so that they enable 
  187. *              interrupts.  Failure to do this will make your system crash!
  188. *********************************************************************************************************
  189. */
  190. OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
  191. {
  192.     OS_EMU_STK *stk;
  193.     stk             = (OS_EMU_STK *)((char*)ptos-sizeof(OS_EMU_STK));   /* Load stack pointer          */
  194.     stk->pData      = pdata;
  195.     stk->Opt        = opt;
  196.     stk->Task       = task;
  197.     stk->Handle     = NULL;
  198.     stk->Id         = 0;
  199.     stk->Exit       = 0;
  200.     return ((void *)stk);
  201. }
  202. /*$PAGE*/
  203. #if OS_CPU_HOOKS_EN
  204. /*
  205. *********************************************************************************************************
  206. *                                          TASK CREATION HOOK
  207. *
  208. * Description: This function is called when a task is created.
  209. *
  210. * Arguments  : ptcb   is a pointer to the task control block of the task being created.
  211. *
  212. * Note(s)    : 1) Interrupts are disabled during this call.
  213. *********************************************************************************************************
  214. */
  215. void OSTCBInitHook(OS_TCB *ptcb)
  216. {
  217.     OS_EMU_STK  *stack;
  218.     
  219.     stack = (OS_EMU_STK*) ptcb->OSTCBStkPtr;
  220.     stack->Handle = CreateThread( NULL, 0, OSTaskW32, ptcb, CREATE_SUSPENDED, &stack->Id );
  221.     
  222. #ifdef SET_AFFINITY_MASK
  223.     if( SetThreadAffinityMask( stack->Handle, 1 ) == 0 ) 
  224. {
  225. #ifdef OS_CPU_TRACE
  226.         OS_Printf("Error: SetThreadAffinityMaskn");
  227. #endif
  228.     }
  229. #endif
  230. }
  231. void OSTaskCreateHook (OS_TCB *ptcb)
  232. {
  233. }
  234. /*
  235. *********************************************************************************************************
  236. *                                           TASK DELETION HOOK
  237. *
  238. * Description: This function is called when a task is deleted.
  239. *
  240. * Arguments  : ptcb   is a pointer to the task control block of the task being deleted.
  241. *
  242. * Note(s)    : 1) Interrupts are disabled during this call.
  243. *********************************************************************************************************
  244. */
  245. void OSTaskDelHook (OS_TCB *ptcb)
  246. {
  247.     OS_EMU_STK  *stack;
  248.     
  249.     stack = (OS_EMU_STK*) ptcb->OSTCBStkPtr;
  250.     if(!(stack->Exit))
  251.     {
  252.         SuspendThread(stack->Handle);
  253.         CloseHandle(stack->Handle);
  254.     }
  255. }
  256. /*
  257. *********************************************************************************************************
  258. *                                           TASK SWITCH HOOK
  259. *
  260. * Description: This function is called when a task switch is performed.  This allows you to perform other
  261. *              operations during a context switch.
  262. *
  263. * Arguments  : none
  264. *
  265. * Note(s)    : 1) Interrupts are disabled during this call.
  266. *              2) It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that
  267. *                 will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the 
  268. *                 task being switched out (i.e. the preempted task).
  269. *********************************************************************************************************
  270. */
  271. void OSTaskSwHook (void)
  272. {
  273. }
  274. /*
  275. *********************************************************************************************************
  276. *                                           STATISTIC TASK HOOK
  277. *
  278. * Description: This function is called every second by uC/OS-II's statistics task.  This allows your 
  279. *              application to add functionality to the statistics task.
  280. *
  281. * Arguments  : none
  282. *********************************************************************************************************
  283. */
  284. void OSTaskStatHook (void)
  285. {
  286. }
  287. /*
  288. *********************************************************************************************************
  289. *                                               TICK HOOK
  290. *
  291. * Description: This function is called every tick.
  292. *
  293. * Arguments  : none
  294. *
  295. * Note(s)    : 1) Interrupts may or may not be ENABLED during this call.
  296. *********************************************************************************************************
  297. */
  298. void OSTimeTickHook (void)
  299. {
  300. }
  301. /*
  302. *********************************************************************************************************
  303. *                                               TASK IDLE HOOK
  304. *
  305. * Description: This function is called by the idle task.
  306. *
  307. * Arguments  : none
  308. *
  309. * Note(s)    : 1) Interrupts may or may not be ENABLED during this call.
  310. *********************************************************************************************************
  311. */
  312. void OSTaskIdleHook (void)
  313. {
  314. }
  315. #endif
  316. /*
  317. ;*********************************************************************************************************
  318. ;                                          START MULTITASKING
  319. ;                                       void OSStartHighRdy(void)
  320. ;
  321. ; The stack frame is assumed to look as follows:
  322. ;
  323. ; OSTCBHighRdy->OSTCBStkPtr --> DS                               (Low memory)
  324. ;                               ES
  325. ;                               DI
  326. ;                               SI
  327. ;                               BP
  328. ;                               SP
  329. ;                               BX
  330. ;                               DX
  331. ;                               CX
  332. ;                               AX
  333. ;                               OFFSET  of task code address
  334. ;                               SEGMENT of task code address
  335. ;                               Flags to load in PSW             
  336. ;                               OFFSET  of task code address
  337. ;                               SEGMENT of task code address
  338. ;                               OFFSET  of 'pdata'
  339. ;                               SEGMENT of 'pdata'               (High memory)
  340. ;
  341. ; Note : OSStartHighRdy() MUST:
  342. ;           a) Call OSTaskSwHook() then,
  343. ;           b) Set OSRunning to TRUE,
  344. ;           c) Switch to the highest priority task.
  345. ;*********************************************************************************************************
  346. */
  347. void OSStartHighRdy()
  348. {
  349.     DWORD  dwID;
  350.     OSInitTrace(100000);
  351.     OS_ENTER_CRITICAL();
  352.     OSTaskSwHook();
  353.     ++OSRunning;
  354.     OSCtxSwW32Event  = CreateEvent(NULL,FALSE,FALSE,NULL);
  355.     OSCtxSwW32Handle = CreateThread( NULL, 0, OSCtxSwW32, 0, 0, &dwID );
  356.     SetPriorityClass(OSCtxSwW32Handle,THREAD_PRIORITY_HIGHEST);
  357. #ifdef SET_AFFINITY_MASK
  358.     if( SetThreadAffinityMask( OSCtxSwW32Handle, 1 ) == 0 ) {
  359. #ifdef OS_CPU_TRACE
  360.         OS_Printf("Error: SetThreadAffinityMaskn");
  361. #endif
  362.        }
  363. #endif
  364.     
  365. SetThreadPriority(OSCtxSwW32Handle,THREAD_PRIORITY_TIME_CRITICAL);
  366.     OSTick32Handle = CreateThread( NULL, 0, OSTickW32, 0, 0, &dwID );
  367.     SetPriorityClass(OSTick32Handle,THREAD_PRIORITY_HIGHEST);
  368. #ifdef SET_AFFINITY_MASK
  369.     if( SetThreadAffinityMask( OSTick32Handle, 1 ) == 0 ) 
  370. {
  371. #ifdef OS_CPU_TRACE
  372.         OS_Printf("Error: SetThreadAffinityMaskn");
  373. #endif
  374.     }
  375. #endif
  376. SetThreadPriority(OSTick32Handle,THREAD_PRIORITY_HIGHEST);
  377. #ifdef WIN_MM_TICK
  378.     timeGetDevCaps(&OSTimeCap, sizeof(OSTimeCap));
  379.     if( OSTimeCap.wPeriodMin < WIN_MM_MIN_RES )
  380.         OSTimeCap.wPeriodMin = WIN_MM_MIN_RES;
  381.     timeBeginPeriod(OSTimeCap.wPeriodMin);
  382.     OSTickEventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
  383.     OSTickTimer       = timeSetEvent((1000/OS_TICKS_PER_SEC),OSTimeCap.wPeriodMin,(LPTIMECALLBACK)OSTickEventHandle, dwID,TIME_PERIODIC|TIME_CALLBACK_EVENT_SET);
  384. #endif
  385.     
  386.     
  387.     SS_SP = (OS_EMU_STK*) OSTCBHighRdy->OSTCBStkPtr;                      /* OSTCBCur = OSTCBHighRdy;     */
  388.                                                                           /* OSPrioCur = OSPrioHighRdy;   */
  389.     ResumeThread(SS_SP->Handle);
  390.     OS_EXIT_CRITICAL();
  391.     
  392.     WaitForSingleObject(OSCtxSwW32Handle,INFINITE);
  393. #ifdef WIN_MM_TICK
  394.     timeKillEvent(OSTickTimer);
  395.     timeEndPeriod(OSTimeCap.wPeriodMin);
  396.     CloseHandle(OSTickEventHandle);
  397. #endif
  398. CloseHandle(OSTick32Handle);
  399.     CloseHandle(OSCtxSwW32Event);
  400. }
  401. /*
  402. ;*********************************************************************************************************
  403. ;                                PERFORM A CONTEXT SWITCH (From task level)
  404. ;                                           void OSCtxSw(void)
  405. ;
  406. ; Note(s): 1) Upon entry, 
  407. ;             OSTCBCur     points to the OS_TCB of the task to suspend
  408. ;             OSTCBHighRdy points to the OS_TCB of the task to resume
  409. ;
  410. ;          2) The stack frame of the task to suspend looks as follows:
  411. ;
  412. ;                 SP -> OFFSET  of task to suspend    (Low memory)
  413. ;                       SEGMENT of task to suspend      
  414. ;                       PSW     of task to suspend    (High memory)  
  415. ;
  416. ;          3) The stack frame of the task to resume looks as follows:
  417. ;                 OSTCBHighRdy->OSTCBStkPtr --> DS                               (Low memory)
  418. ;                                               ES
  419. ;                                               DI
  420. ;                                               SI
  421. ;                                               BP
  422. ;                                               SP
  423. ;                                               BX
  424. ;                                               DX
  425. ;                                               CX
  426. ;                                               AX
  427. ;                                               OFFSET  of task code address
  428. ;                                               SEGMENT of task code address
  429. ;                                               Flags to load in PSW             (High memory)
  430. ;*********************************************************************************************************
  431. */
  432. void OSCtxSw()
  433. {
  434.     DWORD n = 0;
  435.     if(!(SS_SP->Exit)) {
  436.         n = SuspendThread(SS_SP->Handle);
  437.     }
  438.     OSTaskSwHook();
  439.     OSTrace( OBJ_SW, PT_SW_CTX, OSTCBHighRdy, 0, OSPrioCur, OSPrioHighRdy,0 );
  440.     OSTCBCur = OSTCBHighRdy;
  441.     OSPrioCur = OSPrioHighRdy;
  442.     SS_SP = (OS_EMU_STK*) OSTCBHighRdy->OSTCBStkPtr;
  443.     ResumeThread(SS_SP->Handle);
  444. }
  445. /*
  446. ;*********************************************************************************************************
  447. ;                                PERFORM A CONTEXT SWITCH (From an ISR)
  448. ;                                        void OSIntCtxSw(void)
  449. ;
  450. ; Note(s): 1) Upon entry, 
  451. ;             OSTCBCur     points to the OS_TCB of the task to suspend
  452. ;             OSTCBHighRdy points to the OS_TCB of the task to resume
  453. ;
  454. ;          2) The stack frame of the task to suspend looks as follows:
  455. ;
  456. ;                                  SP+0 --> OFFSET  of return address of OSIntCtxSw()  (Low memory)
  457. ;                                    +2     SEGMENT of return address of OSIntCtxSw()
  458. ;                                    +4     PSW saved by OS_ENTER_CRITICAL() in OSIntExit()
  459. ;                                    +6     OFFSET  of return address of OSIntExit()
  460. ;                                    +8     SEGMENT of return address of OSIntExit()
  461. ;                                    +10    DS                               
  462. ;                                           ES
  463. ;                                           DI
  464. ;                                           SI
  465. ;                                           BP
  466. ;                                           SP
  467. ;                                           BX
  468. ;                                           DX
  469. ;                                           CX
  470. ;                                           AX
  471. ;                                           OFFSET  of task code address
  472. ;                                           SEGMENT of task code address
  473. ;                                           Flags to load in PSW                       (High memory)
  474. ;
  475. ;          3) The stack frame of the task to resume looks as follows:
  476. ;             OSTCBHighRdy->OSTCBStkPtr --> DS                               (Low memory)
  477. ;                                           ES
  478. ;                                           DI
  479. ;                                           SI
  480. ;                                           BP
  481. ;                                           SP
  482. ;                                           BX
  483. ;                                           DX
  484. ;                                           CX
  485. ;                                           AX
  486. ;                                           OFFSET  of task code address
  487. ;                                           SEGMENT of task code address
  488. ;                                           Flags to load in PSW             (High memory)
  489. ;*********************************************************************************************************
  490. */
  491. void OSIntCtxSw()
  492. {
  493.     DWORD n = 0;
  494.     if(!(SS_SP->Exit)) {
  495.         n = SuspendThread(SS_SP->Handle);
  496.     }
  497.     OSTaskSwHook();
  498.     OSTrace( OBJ_SW, PT_SW_INT, OSTCBHighRdy, 0, OSPrioCur,OSPrioHighRdy,0 );
  499.     OSTCBCur = OSTCBHighRdy;
  500.     OSPrioCur = OSPrioHighRdy;
  501.     SS_SP = (OS_EMU_STK*) OSTCBHighRdy->OSTCBStkPtr;
  502.     ResumeThread(SS_SP->Handle);
  503. }
  504. /*
  505. ;*********************************************************************************************************
  506. ;                                            HANDLE TICK ISR
  507. ;
  508. ; Description: This function is called 199.99 times per second or, 11 times faster than the normal DOS
  509. ;              tick rate of 18.20648 Hz.  Thus every 11th time, the normal DOS tick handler is called.
  510. ;              This is called chaining.  10 times out of 11, however, the interrupt controller on the PC
  511. ;              must be cleared to allow for the next interrupt.
  512. ;
  513. ; Arguments  : none
  514. ;
  515. ; Returns    : none
  516. ;
  517. ; Note(s)    : The following C-like pseudo-code describe the operation being performed in the code below.
  518. ;
  519. ;              Save all registers on the current task's stack;
  520. ;              OSIntNesting++;
  521. ;              OSTickDOSCtr--;
  522. ;              if (OSTickDOSCtr == 0) {
  523. ;                  INT 81H;               Chain into DOS every 54.925 mS 
  524. ;                                         (Interrupt will be cleared by DOS)
  525. ;              } else {
  526. ;                  Send EOI to PIC;       Clear tick interrupt by sending an End-Of-Interrupt to the 8259
  527. ;                                         PIC (Priority Interrupt Controller)
  528. ;              }
  529. ;              OSTimeTick();              Notify uC/OS-II that a tick has occured       
  530. ;              OSIntExit();               Notify uC/OS-II about end of ISR
  531. ;              Restore all registers that were save on the current task's stack;
  532. ;              Return from Interrupt;
  533. ;*********************************************************************************************************
  534. */
  535. void OSTickISR()
  536. {
  537.     OSIntEnter();
  538.     OSTimeTick();
  539.     OSIntExit();
  540. }
  541. /*
  542. *********************************************************************************************************
  543. *                                          WIN32 TASK - OSCtxSwW32()
  544. *
  545. * Description: These functions are body of OS multitasking in WIN32.
  546. *
  547. * Arguments  : lpParameter   is a pointer to special paraleter of the task.
  548. *
  549. * Note(s)    : 1) Priorities of these tasks are very important.
  550. *********************************************************************************************************
  551. */
  552. DWORD WINAPI OSCtxSwW32( LPVOID lpParameter )
  553. {
  554.     OS_INIT_CRITICAL();
  555.     while(!OSTerminateCtxSwW32)
  556.     {
  557.         if( WAIT_OBJECT_0 == WaitForSingleObject(OSCtxSwW32Event,INFINITE) )
  558.         {
  559.             OS_ENTER_CRITICAL();
  560.             OSCtxSw();
  561.             OS_EXIT_CRITICAL();
  562.         }
  563.     }
  564.     return 0;
  565. }
  566. /*
  567. *********************************************************************************************************
  568. *                                          WIN32 TASK - OSTickW32()
  569. *
  570. * Description: These functions are body of OS multitasking in WIN32.
  571. *
  572. * Arguments  : lpParameter   is a pointer to special paraleter of the task.
  573. *
  574. * Note(s)    : 1) Priorities of these tasks are very important.
  575. *********************************************************************************************************
  576. */
  577. DWORD WINAPI OSTickW32( LPVOID lpParameter )
  578. {
  579.     OS_INIT_CRITICAL();
  580.     while(!OSTerminateTickW32)
  581.     {
  582.         OSTickISR();
  583. #ifdef WIN_MM_TICK
  584.         if( WaitForSingleObject(OSTickEventHandle, 5000) == WAIT_TIMEOUT)
  585.         {
  586.             #ifdef OS_CPU_TRACE
  587.                 OS_Printf("Error: MM OSTick Timeout!n");
  588.             #endif
  589.         }
  590.         ResetEvent(OSTickEventHandle);
  591. #else
  592.         Sleep(1000/OS_TICKS_PER_SEC);
  593. #endif
  594.     }
  595.     return 0;
  596. }
  597. /*
  598. *********************************************************************************************************
  599. *                                          WIN32 TASK - OSTaskW32()
  600. *
  601. * Description: These functions are body of OS multitasking in WIN32.
  602. *
  603. * Arguments  : lpParameter   is a pointer to special paraleter of the task.
  604. *
  605. * Note(s)    : 1) Priorities of these tasks are very important.
  606. *********************************************************************************************************
  607. */
  608. DWORD WINAPI OSTaskW32( LPVOID lpParameter )
  609. {
  610.     OS_TCB *ptcb;
  611.     OS_EMU_STK  *stack;
  612.     ptcb = (OS_TCB*) lpParameter;
  613.     stack = (OS_EMU_STK*) ptcb->OSTCBStkPtr;
  614.     
  615. #ifdef DISABLE_PRIORITY_BOOST
  616.         if( SetThreadPriorityBoost( stack->Handle, TRUE ) == 0 ) {
  617. #ifdef OS_CPU_TRACE
  618.             OS_Printf("Error: SetThreadPriorityBoostn");
  619. #endif
  620.         }
  621. #endif
  622.     OS_INIT_CRITICAL();
  623.     stack->Task(stack->pData);
  624.     stack->Exit = 1;
  625.     OSTaskDel(ptcb->OSTCBPrio);
  626.     return 0;
  627. }
  628. /*
  629. *********************************************************************************************************
  630. *                                          WIN32 TASK - OS_SLEEP()
  631. *
  632. * Description: These functions are body of OS multitasking in WIN32.
  633. *
  634. * Arguments  : lpParameter   is a pointer to special paraleter of the task.
  635. *
  636. * Note(s)    : 1) Priorities of these tasks are very important.
  637. *********************************************************************************************************
  638. */
  639. void OS_SLEEP()
  640. {
  641.     Sleep(1);
  642. }
  643. /*
  644. *********************************************************************************************************
  645. *                                          WIN32 TASK - OS_STOP()
  646. *
  647. * Description: These functions are body of OS multitasking in WIN32.
  648. *
  649. * Arguments  : lpParameter   is a pointer to special paraleter of the task.
  650. *
  651. * Note(s)    : 1) Priorities of these tasks are very important.
  652. *********************************************************************************************************
  653. */
  654. void OS_STOP()
  655. {
  656.     OS_ENTER_CRITICAL();
  657.     ++OSTerminateTickW32;
  658.     ++OSTerminateCtxSwW32;
  659.     OS_TASK_SW();
  660.     OS_EXIT_CRITICAL();
  661.     Sleep(1000/OS_TICKS_PER_SEC);
  662. }
  663. /*
  664. *********************************************************************************************************
  665. *                                          OS_Printf()
  666. *
  667. * Description: These functions help make application more reliable.
  668. *
  669. * OS_Printf - analog of printf, but use critical sections
  670. *********************************************************************************************************
  671. */
  672. int OS_Printf(char *str, ...)
  673. {
  674.     int  ret;
  675.     va_list marker;
  676.     va_start( marker, str );
  677.     OS_ENTER_CRITICAL();
  678.     ret = vprintf( str, marker );
  679.     OS_EXIT_CRITICAL();
  680.     va_end( marker );
  681.     return ret;
  682. }