vs2008_ucos\uCOSII_port\os_cpu_c.c[part2] 移植ucosii在VS2008--part3

vs2008_ucos\uCOSII_port\os_cpu_c.c[part2] 移植ucosii在VS2008--part3
/***************************************************************************************************
*                                             IDLE TASK HOOK
* Description: This function is called by the idle task.  This hook has been added to allow you to do
*              such things as STOP the CPU to conserve power.
* Arguments  : none
* Note(s)    : 1) Interrupts are enabled during this call.
***************************************************************************************************/
#if (OS_CPU_HOOKS_EN > 0) && (OS_VERSION >= 251)
void  OSTaskIdleHook (void)
{
#if (OS_APP_HOOKS_EN > 0)
    App_TaskIdleHook();
#endif

    Sleep(1);         /* Reduce CPU utilization.   */
}
#endif
/***************************************************************************************************
*                                           STATISTIC TASK HOOK
*
* Description: This function is called every second by uC/OS-II's statistics task.  This allows your
*              application to add functionality to the statistics task.
* Arguments  : none
***************************************************************************************************/
#if (OS_CPU_HOOKS_EN > 0)
void  OSTaskStatHook (void)
{
#if (OS_APP_HOOKS_EN > 0)
    App_TaskStatHook();
#endif
}
#endif
/***************************************************************************************************
*                                       INITIALIZE A TASK'S STACK
*
* Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the
*              stack frame of the task being created. This function is highly processor specific.
* Arguments  : task          is a pointer to the task code
*              p_arg         is a pointer to a user supplied data area that will be passed to the task
*                            when the task first executes.
*              ptos          is a pointer to the top of stack. It is assumed that 'ptos' points to the
*                            highest valid address on the stack.
*              opt           specifies options that can be used to alter the behavior of OSTaskStkInit().
*                            (see uCOS_II.H for OS_TASK_OPT_???).
* Returns    : Always returns the location of the new top-of-stack' once the processor registers have
*              been placed on the stack in the proper order.
***************************************************************************************************/
OS_STK  *OSTaskStkInit (void  (*task)(void  *pd), void  *p_arg, OS_STK  *ptos, INT16U  opt)
{
    OS_TASK_STK  *pstack;
     /* Load stack pointer                                       */
    pstack               = (OS_TASK_STK *)((char*)ptos - sizeof(OS_TASK_STK));
    pstack->TaskArgPtr   =  p_arg;
    pstack->TaskOpt      =  opt;
    pstack->Task         =  task;
    pstack->ThreadHandle =  NULL;
    pstack->ThreadID     =  0;
    pstack->TaskState    =  STATE_NONE;
    pstack->SignalPtr    =  NULL;

    return ((void *)pstack);
}
/***************************************************************************************************
*                                           TASK SWITCH HOOK
* Description: This function is called when a task switch is performed.  This allows you to perform other
*              operations during a context switch.
* Arguments  : none
* Note(s)    : 1) Interrupts are disabled during this call.
*              2) It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that
*                 will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the
*                 task being switched out (i.e. the preempted task).
***************************************************************************************************/
#if (OS_CPU_HOOKS_EN > 0) && (OS_TASK_SW_HOOK_EN > 0)
void  OSTaskSwHook (void)
{
#if (OS_APP_HOOKS_EN > 0)
    App_TaskSwHook();
#endif
}
#endif
/***************************************************************************************************
*                                           OS_TCBInit() HOOK
* Description: This function is called by OS_TCBInit() after setting up most of the TCB.
* Arguments  : ptcb    is a pointer to the TCB of the task being created.
* Note(s)    : 1) Interrupts may or may not be ENABLED during this call.
*              2) Kernel objects must have unique names. Otherwise, a duplicate handle will be given for
*                 consecutive created objects. A GetLastError() ERROR_ALREADY_EXISTS can be checked when
*                 this case happens.
***************************************************************************************************/
#if (OS_CPU_HOOKS_EN > 0) && (OS_VERSION > 203)
void  OSTCBInitHook (OS_TCB  *ptcb)
{
    OS_TASK_STK  *pstack;
#if (OS_APP_HOOKS_EN > 0)
    App_TCBInitHook(ptcb);
#else
    (void)ptcb;                                                 /* Prevent compiler warning */
#endif
    pstack = (OS_TASK_STK *)ptcb->OSTCBStkPtr;
    pstack->SignalPtr = CreateEvent(NULL, FALSE, FALSE, NULL);  /* See Note #2.             */
    if (pstack->SignalPtr == NULL) {
#if (OS_MSG_TRACE > 0)
        OSPrintf("Task[%3.1d] cannot allocate signal event.\n", (CPU_INT16S)ptcb->OSTCBId);
#endif
        return;
    }
    pstack->ThreadHandle = CreateThread(NULL, 0, OSTaskW32, ptcb, CREATE_SUSPENDED, &pstack->ThreadID);
    if (pstack->ThreadHandle == NULL) {
#if (OS_MSG_TRACE > 0)
        OSPrintf("Task[%3.1d] failed to be created.\n", (CPU_INT16S)ptcb->OSTCBId);
#endif
        return;
    }
    pstack->TaskState = STATE_CREATED;
#if (OS_MSG_TRACE > 0)
    OSPrintf("Task[%3.1d] created, Thread ID %5.0d\n", (CPU_INT16S)ptcb->OSTCBId, pstack->ThreadID);
#endif

    if (SetThreadAffinityMask(pstack->ThreadHandle, 1) == 0) {
#if (OS_MSG_TRACE > 0)
        OSPrintf("Error: SetThreadAffinityMask [Thread ID %5.0d] failed.\n", pstack->ThreadID);
#endif
    }
}
#endif
/***************************************************************************************************
*                                               TICK HOOK
* Description: This function is called every tick.
* Arguments  : none
* Note(s)    : 1) Interrupts may or may not be ENABLED during this call.
***************************************************************************************************/
#if (OS_CPU_HOOKS_EN > 0) && (OS_TIME_TICK_HOOK_EN > 0)
void  OSTimeTickHook (void)
{
#if (OS_APP_HOOKS_EN > 0)
    App_TimeTickHook();
#endif
#if (OS_VERSION >= 281) && (OS_TMR_EN > 0)
    OSTmrCtr++;
    if (OSTmrCtr >= (OS_TICKS_PER_SEC / OS_TMR_CFG_TICKS_PER_SEC)) {
        OSTmrCtr = 0;
        OSTmrSignal();
    }
#endif
}
#endif

/***************************************************************************************************
*                              START HIGHEST PRIORITY TASK READY-TO-RUN
* Description: This function is called by OSStart() to start the highest priority task that was created
*              by your application before calling OSStart().
* Arguments  : none
* Note(s)    : 1) OSStartHighRdy() MUST:
*                      a) Call OSTaskSwHook() then,
*                      b) Set OSRunning to TRUE,
*                      c) Switch to the highest priority task.
***************************************************************************************************/
void  OSStartHighRdy (void)
{
    OS_TASK_STK  *pstack;
    OS_TCB       *ptcb;
    INT8U         prio;
    INT8U         ret;
    OSTaskSwHook();
    OSRunning = 1;
    ResumeThread(OSTick_Thread);                        /* Start OSTick Thread.                   */

    pstack = (OS_TASK_STK *)OSTCBHighRdy->OSTCBStkPtr;  /* OSTCBCur  = OSTCBHighRdy;              */
                                                        /* OSPrioCur = OSPrioHighRdy;             */
    ResumeThread(pstack->ThreadHandle);
    while (pstack->TaskState == STATE_CREATED) {        /* Wait until task is ready to run.       */
        SwitchToThread();
    }
    SetEvent(pstack->SignalPtr);
    WaitForSingleObject(OSTick_Thread, INFINITE);       /* Wait until Tick thread has terminated. */
#if (TIMER_METHOD == WIN32_MM_TMR)
    timeKillEvent(OSTick_TimerId);
    timeEndPeriod(OSTick_TimerCap.wPeriodMin);
    CloseHandle(OSTick_SignalPtr);
#endif

    CloseHandle(OSTick_Thread);
    CloseHandle(OSTerminate_SignalPtr);


#if (OS_MSG_TRACE > 0)
    OSPrintf("\nDeleting uC/OS-II tasks...\n");
#endif
                                                        /* Delete all created tasks/threads.      */
    ptcb = OSTCBList;
    while (ptcb != (OS_TCB *)0) {
        if (ptcb != OS_TCB_RESERVED) {
#if (OS_MSG_TRACE > 0)
            OSPrintf("Task[%3.1d] '%s' ", (CPU_INT16S)ptcb->OSTCBId, ptcb->OSTCBTaskName);
#endif
            prio = ptcb->OSTCBPrio;

            if (prio == OS_TASK_IDLE_PRIO) {
                OSTaskDelHook(ptcb);
                ret  = OS_ERR_NONE;
                ptcb = ptcb->OSTCBNext;
            } else {
                ptcb = ptcb->OSTCBNext;
                ret  = OSTaskDel(prio);
            }

#if (OS_MSG_TRACE > 0)
            if (ret == OS_ERR_NONE) {
                OSPrintf("Deleted.\n");
            } else {
                OSPrintf("Failed to delete (%d).\n", ret);
            }
#endif
        } else {
            ptcb = ptcb->OSTCBNext;
        }
    }

#if   (CRITICAL_METHOD == WIN32_MUTEX)
    CloseHandle(OSMutex);
#elif (CRITICAL_METHOD == WIN32_CRITICAL_SECTION)
    DeleteCriticalSection(&OSCriticalSection);
#endif

#if (OS_MSG_TRACE > 0)
//    OSDebuggerBreak();
#endif
}

/***************************************************************************************************
*                                      CRITICAL SECTION FUNCTIONS
*
* Description : These functions are used to enter and exit critical sections.
*
* Argument(s) : none
***************************************************************************************************/
void  OSCriticalEnter (void)
{
#if (CRITICAL_METHOD == WIN32_MUTEX)
    DWORD    ret;
#if (OS_MSG_TRACE > 0)
    DWORD    last_err;
    LPTSTR   pmsg;
    OS_TCB  *ptcb;
#endif
    ret = WaitForSingleObject(OSMutex, INFINITE);
    switch (ret) {
        case WAIT_OBJECT_0:
        default:
             break;

#if (OS_MSG_TRACE > 0)
        case WAIT_ABANDONED:
             ptcb = OSTCBCur;
             OSPrintf("Task[%3.1d] '%s' Enter Critical Section failed: Mutex abandoned by owning thread.\n", (CPU_INT16S)ptcb->OSTCBId, ptcb->OSTCBTaskName);
             break;

        case WAIT_TIMEOUT:
             ptcb = OSTCBCur;
             OSPrintf("Task[%3.1d] '%s' Enter Critical Section failed: Time-out interval elapsed.\n", (CPU_INT16S)ptcb->OSTCBId, ptcb->OSTCBTaskName);
             break;

        case WAIT_FAILED:
             last_err = GetLastError();

             FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                           NULL,
                           last_err,
                           MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                           (LPTSTR)&pmsg,
                           0,
                           NULL);

             ptcb = OSTCBCur;
             OSPrintf("Task[%3.1d] '%s' Enter Critical Section failed: %s.\n", (CPU_INT16S)ptcb->OSTCBId, ptcb->OSTCBTaskName, pmsg);

             LocalFree(pmsg);
             break;
#endif
    }
#elif (CRITICAL_METHOD == WIN32_CRITICAL_SECTION)
    EnterCriticalSection(&OSCriticalSection);
#endif
}

void  OSCriticalExit (void)
{
#if (CRITICAL_METHOD == WIN32_MUTEX)
#if (OS_MSG_TRACE > 0)
    DWORD    last_err;
    LPTSTR   pmsg;
    OS_TCB  *ptcb;
#endif

    if (ReleaseMutex(OSMutex) == 0) {
#if (OS_MSG_TRACE > 0)
        last_err = GetLastError();

        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                      NULL,
                      last_err,
                      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                      (LPTSTR)&pmsg,
                      0,
                      NULL);
        ptcb = OSTCBCur;
        OSPrintf("Task[%3.1d] '%s' Exit Critical Section failed: %s.\n", (CPU_INT16S)ptcb->OSTCBId, ptcb->OSTCBTaskName, pmsg);
        LocalFree(pmsg);
#endif
    }
#elif (CRITICAL_METHOD == WIN32_CRITICAL_SECTION)
    LeaveCriticalSection(&OSCriticalSection);
#endif
}
/***************************************************************************************************
*                                          TASK LEVEL CONTEXT SWITCH
* Description: This function is called when a task makes a higher priority task ready-to-run.
* Arguments  : none
* Note(s)    : 1) Upon entry,
*                 OSTCBCur     points to the OS_TCB of the task to suspend
*                 OSTCBHighRdy points to the OS_TCB of the task to resume
*              2) OSCtxSw() MUST:
*                      a) Save processor registers then,
*                      b) Save current task's stack pointer into the current task's OS_TCB,
*                      c) Call OSTaskSwHook(),
*                      d) Set OSTCBCur = OSTCBHighRdy,
*                      e) Set OSPrioCur = OSPrioHighRdy,
*                      f) Switch to the highest priority task.
*
*                      pseudo-code:
*                           void  OSCtxSw (void)
*                           {
*                               Save processor registers;
*
*                               OSTCBCur->OSTCBStkPtr =  SP;
*
*                               OSTaskSwHook();
*
*                               OSTCBCur              =  OSTCBHighRdy;
*                               OSPrioCur             =  OSPrioHighRdy;
*
*                               Restore processor registers from (OSTCBHighRdy->OSTCBStkPtr);
*                           }
***************************************************************************************************/

void  OSCtxSw (void)
{
    OS_TASK_STK  *pstack;
    OS_TASK_STK  *pstack_new;
#if (OS_MSG_TRACE > 0)
    OS_TCB       *ptcb_cur;
    OS_TCB       *ptcb_new;

    ptcb_cur = OSTCBCur;
    ptcb_new = OSTCBHighRdy;
#endif
    pstack = (OS_TASK_STK *)OSTCBCur->OSTCBStkPtr;
    OSTaskSwHook();
    OSTCBCur  = OSTCBHighRdy;
    OSPrioCur = OSPrioHighRdy;

    pstack->TaskState =  STATE_SUSPENDED;
    pstack_new        = (OS_TASK_STK *)OSTCBHighRdy->OSTCBStkPtr;
    switch (pstack_new->TaskState) {
        case STATE_CREATED:                                   /* TaskState updated to STATE_SUSPENDED once thread runs.   */
             ResumeThread(pstack_new->ThreadHandle);
             while (pstack_new->TaskState == STATE_CREATED) { /* Wait until new task is ready to run.                     */
                 SwitchToThread();
             }
                                                              /* Intentional fall through to STATE_SUSPENDED.             */
        case STATE_SUSPENDED:
             pstack_new->TaskState = STATE_RUNNING;
             SetEvent(pstack_new->SignalPtr);
             OSCriticalExit();
             WaitForSingleObject(pstack->SignalPtr, INFINITE);
             break;

        case STATE_INTERRUPTED:
             pstack_new->TaskState = STATE_RUNNING;
             ResumeThread(pstack_new->ThreadHandle);
             OSCriticalExit();
             WaitForSingleObject(pstack->SignalPtr, INFINITE);
             break;

#if (OS_MSG_TRACE > 0)
        case STATE_NONE:
             OSPrintf("[OSCtxSw] Error: Invalid state STATE_NONE\nCur    Task[%3.1d] Thread ID %5.0d: '%s'\nNew    Task[%3.1d] Thread ID %5.0d: '%s'\n\n",
                      (CPU_INT16S)ptcb_cur->OSTCBId,
                       pstack->ThreadID,
                       ptcb_cur->OSTCBTaskName,
                      (CPU_INT16S)ptcb_new->OSTCBId,
                       pstack_new->ThreadID,
                       ptcb_new->OSTCBTaskName);
             break;

        case STATE_RUNNING:
             OSPrintf("[OSCtxSw] Error: Invalid state STATE_RUNNING\nCur    Task[%3.1d] Thread ID %5.0d: '%s'\nNew    Task[%3.1d] Thread ID %5.0d: '%s'\n\n",
                      (CPU_INT16S)ptcb_cur->OSTCBId,
                       pstack->ThreadID,
                       ptcb_cur->OSTCBTaskName,
                      (CPU_INT16S)ptcb_new->OSTCBId,
                       pstack_new->ThreadID,
                       ptcb_new->OSTCBTaskName);
             break;

        case STATE_TERMINATING:
             OSPrintf("[OSCtxSw] Error: Invalid state STATE_TERMINATING\nCur    Task[%3.1d] Thread ID %5.0d: '%s'\nNew    Task[%3.1d] Thread ID %5.0d: '%s'\n\n",
                      (CPU_INT16S)ptcb_cur->OSTCBId,
                       pstack->ThreadID,
                       ptcb_cur->OSTCBTaskName,
                      (CPU_INT16S)ptcb_new->OSTCBId,
                       pstack_new->ThreadID,
                       ptcb_new->OSTCBTaskName);
             break;

        case STATE_TERMINATED:
             OSPrintf("[OSCtxSw] Error: Invalid state STATE_TERMINATED\nCur    Task[%3.1d] Thread ID %5.0d: '%s'\nNew    Task[%3.1d] Thread ID %5.0d: '%s'\n\n",
                      (CPU_INT16S)ptcb_cur->OSTCBId,
                       pstack->ThreadID,
                       ptcb_cur->OSTCBTaskName,
                      (CPU_INT16S)ptcb_new->OSTCBId,
                       pstack_new->ThreadID,
                       ptcb_new->OSTCBTaskName);
             break;
#endif
        default:
             break;
    }
    OSCriticalEnter();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值