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

📄 emos_core.c

📁 emos是一个新的类似于ucos的内核
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************
 *
 * (c) Copyright 2001,2008, EMB system, All Rights Reserved.
 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF EMB SYSTEM, INC.
 * The copyright notice above does not evidence any actual or intended
 * publication of such source code. 
 *  Subsystem:    EMOS 
 *  File:         emos_core.c
 *  Author:       zenf zhao
 *  Description:  embedded software operation system core implement file
 *
 ****************************************************************************/
#include "emos_cfg.h"

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

/* Declare GLOBAL variables by the EMOS_EXTERN definition*/
#define   EMOS_GLOBALS 
#include "emos_core.h"
#undef EMOS_GLOBALS

/***********************************
*   LOCAL GLOBAL VARIABLES
************************************/
/* Variable used by 'OSIntExit' to prevent using locals */   
static  uint8          emosIntExitY;               

/* Table of TCBs */
static  EMOS_TCB_T     emosTCBTbl[EMOS_MAX_TASKS + EMOS_N_SYS_TASKS];   

/* Idle       task stack  */
static  EMOS_STK       emosTaskIdleStk[EMOS_TASK_IDLE_STK_SIZE];      

#if EMOS_TASK_STAT_EN
/* Statistics task stack */
static  EMOS_STK       emosTaskStatStk[EMOS_TASK_STAT_STK_SIZE];      
#endif



/* 
   MAPPING TABLE TO MAP BIT POSITION TO BIT MASK
   Note: Index into table is desired bit position, 0..7
   Indexed value corresponds to bit mask
   For the EMOS/ucOS-II sheduler, the task is 8*8=64 task numbers
   the lower ID is with higher task priority, and divied into max 8 groups
   group number is indentified by   Y=(taskPri>>3)&0x07 
   and each in group indentified by X=(taskPri&0x07)
   the next two mapping table is just used to find the highest-priority task
*/
uint8 const gEmosMapTbl[]   = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};

/**********************************************************************************************************
* PRIORITY RESOLUTION TABLE
* Note: Index into table is bit pattern to resolve highest priority
*       Indexed value corresponds to highest priority bit position (i.e. 0..7)
  because total 64 task (0~63) will occupy bit 0~5;
  but for unMapTbl, for RdygGrp every bit mask is or-ed so max bits(0~7) are used to reach 255
**********************************************************************************************************/
uint8 const gEmosUnMapTbl[] = {
    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};


void emosDbgShow();

	
/**********************************************************************************************************
* MAKE TASK READY TO RUN BASED ON EVENT OCCURING
* Description: This function is called by other EMOS services and is used to ready a task that was
*              waiting for an event to occur.
* Arguments  : pevent    is a pointer to the event control block corresponding to the event.
*              msg       is a pointer to a message.  This pointer is used by message oriented services
*                        such as MAILBOXEs and QUEUEs.  The pointer is not used when called by other
*                        service functions.
*              msk       is a mask that is used to clear the status byte of the TCB.  For example,
*                        OSSemPost() will pass OS_STAT_SEM, OSMboxPost() will pass OS_STAT_MBOX etc.
* Returns    : none
* Note       : This function is INTERNAL to EMOS and your application should not call it.
*********************************************************************************************************/
#if  (EMOS_Q_EN && (EMOS_MAX_QS >= 2)) || EMOS_MBOX_EN || EMOS_SEM_EN
void  emosEventTaskRdy (EMOS_EVENT_T *pevent, void *msg, uint8 msk)
{
    EMOS_TCB_T *ptcb;
    uint8   x;
    uint8   y;
    uint8   bitx;
    uint8   bity;
    uint8   prio;

    /* Find the highest prio task waiting for message   */
    y    =  gEmosUnMapTbl[pevent->osEventGrp];            
    bity =  gEmosMapTbl[y];
    x    =  gEmosUnMapTbl[pevent->osEventTbl[y]];
    bitx =  gEmosMapTbl[x];
   
    /* Find priority of task getting the msg  */
    prio = (uint8)((y << 3) + x);

    /* Remove this task from the waiting list, if no task within a group, clear GRP*/
    if( (pevent->osEventTbl[y] &= ~bitx) == 0)
    {
        pevent->osEventGrp &= ~bity;
    }

    /* Point to this task's EMOS_TCB*/
    ptcb =  gEmosTCBPrioTbl[prio];
    
   /* Prevent OSTimeTick() from readying task*/       
    ptcb->osTCBDly =  0;                        
    ptcb->osTCBEventPtr = (EMOS_EVENT_T *)0; /* Unlink ECB from this task*/

    #if (EMOS_Q_EN && (EMOS_MAX_QS >= 2)) || EMOS_MBOX_EN
    ptcb->osTCBMsg       = msg;  /* Send message directly to waiting task*/
    #else
    msg                  = msg;  /* Prevent compiler warning if not used*/    
    #endif    
   
    ptcb->osTCBStat     &= ~msk; /* Clear bit associated with event type*/
    if (ptcb->osTCBStat == EMOS_STAT_RDY)
    {
        /* See if task is ready (could be susp'd) 
           Put task in the ready to run list */
        gEmosRdyGrp         |=  bity;                   
        gEmosRdyTbl[y]      |=  bitx;
    }
}
#endif


/**********************************************************************************************************
* MAKE TASK WAIT FOR EVENT TO OCCUR
* Description: This function is called by other EMOS services to suspend a task because an event has
*              not occurred.
* Arguments  : pevent is a pointer to the event control block for which the task will be waiting for.
* Returns    : none
* Note       : This function is INTERNAL to EMOS and your application should not call it.
**********************************************************************************************************/
#if  (EMOS_Q_EN && (EMOS_MAX_QS >= 2)) || EMOS_MBOX_EN || EMOS_SEM_EN
void  emosEventTaskWait (EMOS_EVENT_T *pevent)
{
     /* Store pointer to event control block in TCB*/
    gEmosTCBCur->osTCBEventPtr = pevent;           
    if ((gEmosRdyTbl[gEmosTCBCur->osTCBY] &= ~gEmosTCBCur->osTCBBitX) == 0)
    {
       /* Task in the Grp no longer ready*/
        gEmosRdyGrp &= ~gEmosTCBCur->osTCBBitY;
    }

    /*Put task in waiting list of this pevent*/
    pevent->osEventTbl[gEmosTCBCur->osTCBY] |= gEmosTCBCur->osTCBBitX;         
    pevent->osEventGrp |= gEmosTCBCur->osTCBBitY;
}
#endif


/**********************************************************************************************************
*  MAKE TASK READY TO RUN BASED ON EVENT TIMEOUT
* Description: This function is called by other EMOS services to make a task ready to run because a
*              timeout occurred.
* Arguments  : pevent   is a pointer to the event control block which is readying a task.
* Returns    : none
* Note       : This function is INTERNAL to EMOS and your application should not call it.
**********************************************************************************************************/
#if(EMOS_Q_EN && (EMOS_MAX_QS >= 2)) || EMOS_MBOX_EN || EMOS_SEM_EN
void  emosEventTo (EMOS_EVENT_T *pevent)
{
    if ((pevent->osEventTbl[gEmosTCBCur->osTCBY] &= ~gEmosTCBCur->osTCBBitX) == 0) 
    {
        pevent->osEventGrp &= ~gEmosTCBCur->osTCBBitY;
    }
    gEmosTCBCur->osTCBStat = EMOS_STAT_RDY;             /* Set status to ready*/
    gEmosTCBCur->osTCBEventPtr = (EMOS_EVENT_T *)0;     /* No longer waiting for event*/
}
#endif

/**********************************************************************************************************
* INITIALIZE EVENT CONTROL BLOCK'S WAIT LIST
* Description: This function is called by other EMOS services to initialize the event wait list.
* Arguments  : pevent    is a pointer to the event control block allocated to the event.
* Returns    : none
* Note       : This function is INTERNAL to EMOS and your application should not call it.
**********************************************************************************************************/
#if  (EMOS_Q_EN && (EMOS_MAX_QS >= 2)) || EMOS_MBOX_EN || EMOS_SEM_EN
void  emosEventWaitListInit (EMOS_EVENT_T *pevent)
{
    uint8 i;
 
    /* No task waiting on event*/
    pevent->osEventGrp = 0x00;                   
    for (i = 0; i < EMOS_EVENT_TBL_SIZE; i++) 
    {
        pevent->osEventTbl[i] = 0x00;
    }
}
#endif

/**********************************************************************************************************
* INITIALIZATION
* Description: This function is used to initialize the internals of EMOS and MUST be called prior to
*              creating any EMOS object and, prior to calling OSStart().
* Arguments  : none
* Returns    : none
********************************************************************************************************/
void emosInit (void)
{
    uint16 i = 0;

    #ifdef EMOS_CPU_MINGW_MODE
    /*Init the HookBegin at the beginning emosInit*/
    emosInitHookBegin();
    #endif

    gEmosTime        = 0L;   /* Clear the 32-bit system clock     */
    gEmosIntNesting  = 0;    /* Clear the interrupt nesting counter      */
    gEmosLockNesting = 0;    /* Clear the scheduling lock counter */
    
#if EMOS_TASK_CREATE_EN  || EMOS_TASK_CREATE_EXT_EN || EMOS_TASK_DEL_EN
    gEmosTaskCtr     = 0;   /* Clear the number of tasks*/
#endif

    gEmosRunning     = EMOS_FALSE; /* Indicate that multitasking not started   */
    gEmosIdleCtr     = 0L;    /* Clear the 32-bit idle counter     */
    
    #if EMOS_TASK_STAT_EN && EMOS_TASK_CREATE_EXT_EN
    gEmosIdleCtrRun  = 0L;
    gEmosIdleCtrMax  = 0L;
    gEmosIdleTickCnt = 0;
    gEmosStatRdy     = EMOS_FALSE;  /* Statistic task is not ready */
    #endif

    gEmosCtxSwCtr    = 0;  /* Clear the context switch counter  */
    gEmosRdyGrp      = 0;  /* Clear the ready list*/

    for (i = 0; i < EMOS_RDY_TBL_SIZE; i++)
    {
        gEmosRdyTbl[i] = 0;
    }
                
    gEmosPrioCur     = 0;
    gEmosPrioHighRdy = 0;       
    gEmosTCBHighRdy  = (EMOS_TCB_T *)0;  /* TCB Initialization*/
    gEmosTCBCur      = (EMOS_TCB_T *)0;
    gEmosTCBList     = (EMOS_TCB_T *)0;

    for (i = 0; i < (EMOS_LOWEST_PRIO + 1); i++)
    {                
     	/* Clear the priority table    */
        gEmosTCBPrioTbl[i] = (EMOS_TCB_T *)0;
    }

    /*Init the TCBList of tasks*/
    for (i = 0; i < (EMOS_MAX_TASKS + EMOS_N_SYS_TASKS - 1); i++)
    {  
        emosTCBTbl[i].osTCBNext = &emosTCBTbl[i + 1];
    }
        emosTCBTbl[EMOS_MAX_TASKS + EMOS_N_SYS_TASKS - 1].osTCBNext = (EMOS_TCB_T *)0;    /* Last EMOS_TCB*/
        gEmosTCBFreeList  = &emosTCBTbl[0];

    #if EMOS_MAX_EVENTS >= 2
    for (i = 0; i < (EMOS_MAX_EVENTS - 1); i++) 
    {   
      /* Init list of free EVENT control blocks  */
      gEmosEventTbl[i].osEventPtr = (EMOS_EVENT_T *)&gEmosEventTbl[i + 1];
    }    
      gEmosEventTbl[EMOS_MAX_EVENTS - 1].osEventPtr = (EMOS_EVENT_T *)0;
      gEmosEventFreeList = &gEmosEventTbl[0];    
    #endif


    /*EMOS Internal Modules Initialization*/
    #if EMOS_Q_EN && (EMOS_MAX_QS >= 2)
    /* Initialize the message queue structures*/
    emosQInit();         
    #endif
    
    #if EMOS_Q_EN && (EMOS_MAX_MSGQS >= 2)
    emosMsgQInit();
    #endif

    #if EMOS_MEM_EN && EMOS_MAX_MEM_PART >= 2
    /* Initialize the memory manager*/
    emosMemInit();       
    #endif    

#if 0
#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  */

⌨️ 快捷键说明

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