⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 emos_core.c

📁 emos是一个新的类似于ucos的内核
💻 C
📖 第 1 页 / 共 4 页
字号:
    #else
    emosTaskCreate(emosTaskIdle, (void *)0, &emosTaskIdleStk[EMOS_TASK_IDLE_STK_SIZE - 1], EMOS_IDLE_PRIO);
    #endif
    
#else
    #if EMOS_TASK_CREATE_EXT_EN
    emosTaskCreateExt(emosTaskIdle, 
                    (void *)0,           /* No arguments passed to gEmosTaskIdle()  */
                    &emosTaskIdleStk[0],     /* Set Top-Of-Stack */
                    EMOS_IDLE_PRIO,           /* Lowest priority level*/
                    EMOS_TASK_IDLE_ID,
                    &emosTaskIdleStk[EMOS_TASK_IDLE_STK_SIZE - 1],  /* Set Bottom-Of-Stack  */
                    EMOS_TASK_IDLE_STK_SIZE, 
                    (void *)0,                          /* No TCB extension*/
                    EMOS_TASK_OPT_STK_CHK | EMOS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack  */
    #else
    emosTaskCreate(emosTaskIdle, (void *)0, &emosTaskIdleStk[0], EMOS_IDLE_PRIO);
    #endif
#endif

#if EMOS_TASK_STAT_EN 
        #if EMOS_TASK_CREATE_EXT_EN
        #if EMOS_STK_GROWTH == 1
        emosTaskCreateExt(emosTaskStat, 
                        (void *)0,        /* No args passed to gEmosTaskStat()    */
                        &emosTaskStatStk[EMOS_TASK_STAT_STK_SIZE - 1],/* Set Top-Of-Stack */
                        EMOS_STAT_PRIO,                  /* One higher than the idle task*/
                        EMOS_TASK_STAT_ID,
                        &emosTaskStatStk[0],              /* Set Bottom-Of-Stack*/
                        EMOS_TASK_STAT_STK_SIZE, 
                        (void *)0,                        /* No TCB extension */
                        EMOS_TASK_OPT_STK_CHK | EMOS_TASK_OPT_STK_CLR);  /* Enable stack checking + clear  */
        #else
        emosTaskCreateExt(emosTaskStat, 
                        (void *)0,                       /* No args passed to gEmosTaskStat() */
                        &emosTaskStatStk[0],             /* Set Top-Of-Stack */
                        EMOS_STAT_PRIO,                  /* One higher than the idle task */
                        EMOS_TASK_STAT_ID,
                        &emosTaskStatStk[EMOS_TASK_STAT_STK_SIZE - 1], /* Set Bottom-Of-Stack */
                        EMOS_TASK_STAT_STK_SIZE, 
                        (void *)0,                        /* No TCB extension */
                        EMOS_TASK_OPT_STK_CHK | EMOS_TASK_OPT_STK_CLR);  /* Enable stack checking + clear  */
        #endif
        
    #else
        #if EMOS_STK_GROWTH == 1
        emosTaskCreate(emosTaskStat, 
                       (void *)0, /* No args passed to gEmosTaskStat() */
                       &emosTaskStatStk[EMOS_TASK_STAT_STK_SIZE - 1],   /* Set Top-Of-Stack  */
                       EMOS_STAT_PRIO);       /* One higher than the idle task */
        #else
        emosTaskCreate(emosTaskStat, 
                       (void *)0, /* No args passed to gEmosTaskStat() */
                       &emosTaskStatStk[0],   /* Set Top-Of-Stack  */
                       EMOS_STAT_PRIO);        /* One higher than the idle task */
        #endif
    #endif    
#endif /*end of STAT_EN*/
#endif 

  emosInitStart();
  return ;
}

/*adjust the Idle and Stat task to the seperated callback,
  to fix init errors*/
static void emosInitIdleStatTask()
{
   #if EMOS_STK_GROWTH == 1
       #if EMOS_TASK_CREATE_EXT_EN
       emosTaskCreateExt(emosTaskIdle, 
                       (void *)0, /* No arguments passed to gEmosTaskIdle()  */
                       &emosTaskIdleStk[EMOS_TASK_IDLE_STK_SIZE - 1], /* Set Top-Of-Stack*/
                       EMOS_IDLE_PRIO,       /* Lowest priority level */
                       EMOS_TASK_IDLE_ID,
                       &emosTaskIdleStk[0],   /* Set Bottom-Of-Stack */
                       EMOS_TASK_IDLE_STK_SIZE, 
                       (void *)0,  /* No TCB extension*/
                       EMOS_TASK_OPT_STK_CHK | EMOS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack  */
       #else
       emosTaskCreate(emosTaskIdle, (void *)0, &emosTaskIdleStk[EMOS_TASK_IDLE_STK_SIZE - 1], EMOS_IDLE_PRIO);
       #endif
       
   #else
       #if EMOS_TASK_CREATE_EXT_EN
       emosTaskCreateExt(emosTaskIdle, 
                       (void *)0,           /* No arguments passed to gEmosTaskIdle()  */
                       &emosTaskIdleStk[0],     /* Set Top-Of-Stack */
                       EMOS_IDLE_PRIO,           /* Lowest priority level*/
                       EMOS_TASK_IDLE_ID,
                       &emosTaskIdleStk[EMOS_TASK_IDLE_STK_SIZE - 1],  /* Set Bottom-Of-Stack  */
                       EMOS_TASK_IDLE_STK_SIZE, 
                       (void *)0,                          /* No TCB extension*/
                       EMOS_TASK_OPT_STK_CHK | EMOS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack  */
       #else
       emosTaskCreate(emosTaskIdle, (void *)0, &emosTaskIdleStk[0], EMOS_IDLE_PRIO);
       #endif
   #endif
   
   #if EMOS_TASK_STAT_EN 
           #if EMOS_TASK_CREATE_EXT_EN
           #if EMOS_STK_GROWTH == 1
           emosTaskCreateExt(emosTaskStat, 
                           (void *)0,        /* No args passed to gEmosTaskStat()    */
                           &emosTaskStatStk[EMOS_TASK_STAT_STK_SIZE - 1],/* Set Top-Of-Stack */
                           EMOS_STAT_PRIO,                  /* One higher than the idle task*/
                           EMOS_TASK_STAT_ID,
                           &emosTaskStatStk[0],              /* Set Bottom-Of-Stack*/
                           EMOS_TASK_STAT_STK_SIZE, 
                           (void *)0,                        /* No TCB extension */
                           EMOS_TASK_OPT_STK_CHK | EMOS_TASK_OPT_STK_CLR);  /* Enable stack checking + clear  */
           #else
           emosTaskCreateExt(emosTaskStat, 
                           (void *)0,                       /* No args passed to gEmosTaskStat() */
                           &emosTaskStatStk[0],             /* Set Top-Of-Stack */
                           EMOS_STAT_PRIO,                  /* One higher than the idle task */
                           EMOS_TASK_STAT_ID,
                           &emosTaskStatStk[EMOS_TASK_STAT_STK_SIZE - 1], /* Set Bottom-Of-Stack */
                           EMOS_TASK_STAT_STK_SIZE, 
                           (void *)0,                        /* No TCB extension */
                           EMOS_TASK_OPT_STK_CHK | EMOS_TASK_OPT_STK_CLR);  /* Enable stack checking + clear  */
           #endif
           
       #else
           #if EMOS_STK_GROWTH == 1
           emosTaskCreate(emosTaskStat, 
                          (void *)0, /* No args passed to gEmosTaskStat() */
                          &emosTaskStatStk[EMOS_TASK_STAT_STK_SIZE - 1],   /* Set Top-Of-Stack  */
                          EMOS_STAT_PRIO);       /* One higher than the idle task */
           #else
           emosTaskCreate(emosTaskStat, 
                          (void *)0, /* No args passed to gEmosTaskStat() */
                          &emosTaskStatStk[0],   /* Set Top-Of-Stack  */
                          EMOS_STAT_PRIO);        /* One higher than the idle task */
           #endif
       #endif    
   #endif /*end of STAT_EN*/
}


void emosInitStart(void)
{
  /*Adjus the idle and Stat task to emosStart,
  other wise there are problems for task using timeDly()/Sem()/MsgQ() etc*/
  emosInitIdleStatTask();

  #if EMOS_TASK_STAT_EN
  emosStatInit();
  #endif
  
  return;
}

/**********************************************************************************************************
*                                              ENTER ISR
*
* Description: This function is used to notify EMOS that you are about to service an interrupt
*              service routine (ISR).  This allows EMOS to keep track of interrupt nesting and thus
*              only perform rescheduling at the last nested ISR.
*
* Arguments  : none
*
* Returns    : none
*
* Notes      : 1) Your ISR can directly increment OSIntNesting without calling this function because 
*                 OSIntNesting has been declared 'global'.  You MUST, however, be sure that the increment
*                 is performed 'indivisibly' by your processor to ensure proper access to this critical
*                 resource.
*              2) You MUST still call OSIntExit() even though you increment OSIntNesting directly.
*              3) You MUST invoke OSIntEnter() and OSIntExit() in pair.  In other words, for every call
*                 to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the
*                 end of the ISR.
**********************************************************************************************************/
void emosIntEnter (void)
{
    EMOS_ENTER_CRITICAL();
    gEmosIntNesting++;                              /* Increment ISR nesting level                        */
    EMOS_EXIT_CRITICAL();
}

/**********************************************************************************************************
*                                               EXIT ISR
*
* Description: This function is used to notify EMOS that you have completed serviving an ISR.  When 
*              the last nested ISR has completed, EMOS will call the scheduler to determine whether
*              a new, high-priority task, is ready to run.
*
* Arguments  : none
*
* Returns    : none
*
* Notes      : 1) You MUST invoke OSIntEnter() and OSIntExit() in pair.  In other words, for every call
*                 to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the
*                 end of the ISR.
*              2) Rescheduling is prevented when the scheduler is locked (see OSSchedLock())
**********************************************************************************************************/

void emosIntExit (void)
{
    EMOS_ENTER_CRITICAL();

    if ((--gEmosIntNesting | gEmosLockNesting) == 0) 
    {
          /* Reschedule only if all ISRs completed & not locked */
        emosIntExitY    = gEmosUnMapTbl[gEmosRdyGrp];
        gEmosPrioHighRdy = (uint8)((emosIntExitY << 3) + gEmosUnMapTbl[gEmosRdyTbl[emosIntExitY]]);
        if (gEmosPrioHighRdy != gEmosPrioCur)
        {        /* No context switch if current task is highest ready */
            gEmosTCBHighRdy  = gEmosTCBPrioTbl[gEmosPrioHighRdy];
            gEmosCtxSwCtr++;                        /* Keep track of the number of context switches       */
            emosIntCtxSw();                           /* Perform interrupt level context switch             */
        }
    }

    EMOS_EXIT_CRITICAL();
}

/**********************************************************************************************************
* SCHEDULER
* Description: This function is called by other EMOS services to determine whether a new, high
*              priority task has been made ready to run.  This function is invoked by TASK level code
*              and is not used to reschedule tasks from ISRs (see OSIntExit() for ISR rescheduling).
* Arguments  : none
* Returns    : none
* Notes      : 1) This function is INTERNAL to EMOS and your application should not call it.
*              2) Rescheduling is prevented when the scheduler is locked (see OSSchedLock())
*********************************************************************************************************
*/
void emosSched (void)
{
    uint8 y;

    EMOS_ENTER_CRITICAL();

    if ((gEmosLockNesting | gEmosIntNesting) == 0) 
    {
       /* Task scheduling must be enabled and not ISR level  */
        y = gEmosUnMapTbl[gEmosRdyGrp]; /* Get pointer to highest priority task ready to run  */       
        gEmosPrioHighRdy = (uint8)((y << 3) + gEmosUnMapTbl[gEmosRdyTbl[y]]);

        if (gEmosPrioHighRdy != gEmosPrioCur) 
        {          
           /* No context switch if current task is highest ready */
            gEmosTCBHighRdy = gEmosTCBPrioTbl[gEmosPrioHighRdy];
            gEmosCtxSwCtr++; /* Increment context switch counter */
            EMOS_TASK_SW();  /* Perform a context switch */
        }
     }
    
    /*EMOS_Printf("==>emosShed Returning pTCBCur=%08x pri=%d\r\n",
                  (int)gEmosTCBCur,(int)gEmosTCBCur->osTCBPrio);*/
    EMOS_EXIT_CRITICAL();
}

/**********************************************************************************************************
* PREVENT SCHEDULING
* Description: This function is used to prevent rescheduling to take place.  This allows your application
*              to prevent context switches until you are ready to permit context switching.
* Arguments  : none
* Returns    : none
* Notes      : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair.  In other words, for every 
*                 call to OSSchedLock() you MUST have a call to OSSchedUnlock().
**********************************************************************************************************/
void emosSchedLock (void)
{
    if (gEmosRunning == EMOS_TRUE) 
   {
        /* Make sure multitasking is running                  */
        EMOS_ENTER_CRITICAL();
        gEmosLockNesting++;                         /* Increment lock nesting level*/
        EMOS_EXIT_CRITICAL();
    }
}

/**********************************************************************************************************
* ENABLE SCHEDULING
* Description: This function is used to re-allow rescheduling.  
* Arguments  : none
* Returns    : none
* Notes      : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair.  In other words, for every 
*                 call to OSSchedLock() you MUST have a call to OSSchedUnlock().
**********************************************************************************************************/
void emosSchedUnlock (void)
{
    if (gEmosRunning == EMOS_TRUE) 
   {            
        /* Make sure multitasking is running  */
        EMOS_ENTER_CRITICAL();
        if (gEmosLockNesting > 0) 
       {
           /* Do not decrement if already 0  */
            gEmosLockNesting--;  /* Decrement lock nesting level                 */
            if ((gEmosLockNesting | gEmosIntNesting) == 0) 
           {
                /* See if scheduling re-enabled and not an ISR  */
                EMOS_EXIT_CRITICAL();
                emosSched();   /* See if a higher priority task is ready       */
            } 
            else 
            {
                EMOS_EXIT_CRITICAL();
            }
        } 
        else
        {
            EMOS_EXIT_CRITICAL();
        }
    }
}

/**********************************************************************************************************
*  START MULTITASKING
* Description: This function is used to start the multitasking process which lets EMOS manages the
*              task that you have created.  Before you can call OSStart(), you MUST have called OSInit()
*              and you MUST have created at least one task.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -