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

📄 os_core.c

📁 完整的ucos实例
💻 C
📖 第 1 页 / 共 4 页
字号:
/* 
********************************************************************************************************* 
*                                                uC/OS-II 
*                                          The Real-Time Kernel 
*                                             CORE FUNCTIONS 
* 
*                          (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL 
*                                           All Rights Reserved 
* 
* File : OS_CORE.C 
* By   : Jean J. Labrosse 
********************************************************************************************************* 
*/ 
 
#ifndef  OS_MASTER_FILE 
#define  OS_GLOBALS 
#include "includes.h" 
#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 
********************************************************************************************************* 
*/ 
 
INT8U  const  OSMapTbl[]   = {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) 
********************************************************************************************************* 
*/ 
 
INT8U  const  OSUnMapTbl[] = { 
    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x00 to 0x0F                             */ 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x10 to 0x1F                             */ 
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x20 to 0x2F                             */ 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x30 to 0x3F                             */ 
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x40 to 0x4F                             */ 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x50 to 0x5F                             */ 
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x60 to 0x6F                             */ 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x70 to 0x7F                             */ 
    7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x80 to 0x8F                             */ 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x90 to 0x9F                             */ 
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xA0 to 0xAF                             */ 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xB0 to 0xBF                             */ 
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xC0 to 0xCF                             */ 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xD0 to 0xDF                             */ 
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xE0 to 0xEF                             */ 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0        /* 0xF0 to 0xFF                             */ 
}; 
 
/* 
********************************************************************************************************* 
*                                       FUNCTION PROTOTYPES 
********************************************************************************************************* 
*/ 
static  void  OS_InitEventList(void); 
static  void  OS_InitMisc(void); 
static  void  OS_InitRdyList(void); 
static  void  OS_InitTaskIdle(void); 
static  void  OS_InitTaskStat(void); 
static  void  OS_InitTCBList(void); 
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                             INITIALIZATION 
* 
* Description: This function is used to initialize the internals of uC/OS-II and MUST be called prior to 
*              creating any uC/OS-II object and, prior to calling OSStart(). 
* 
* Arguments  : none 
* 
* Returns    : none 
********************************************************************************************************* 
*/ 
 
void  OSInit (void) 
{ 
#if OS_VERSION >= 204 
    OSInitHookBegin();                                           /* Call port specific initialization code   */ 
#endif 
 
    OS_InitMisc();                                               /* Initialize miscellaneous variables       */ 
 
    OS_InitRdyList();                                            /* Initialize the Ready List                */ 
    OS_InitTCBList();                                            /* Initialize the free list of OS_TCBs      */ 
    OS_InitEventList();                                          /* Initialize the free list of OS_EVENTs    */ 
 
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) 
    OS_FlagInit();                                               /* Initialize the event flag structures     */ 
#endif 
 
#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0) 
    OS_MemInit();                                                /* Initialize the memory manager            */ 
#endif 
 
#if (OS_Q_EN > 0) && (OS_MAX_QS > 0) 
    OS_QInit();                                                  /* Initialize the message queue structures  */ 
#endif 
 
    OS_InitTaskIdle();                                           /* Create the Idle Task                     */ 
#if OS_TASK_STAT_EN > 0 
    OS_InitTaskStat();                                           /* Create the Statistic Task                */ 
#endif 
 
#if OS_VERSION >= 204 
    OSInitHookEnd();                                             /* Call port specific init. code            */ 
#endif 
} 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                              ENTER ISR 
* 
* Description: This function is used to notify uC/OS-II that you are about to service an interrupt 
*              service routine (ISR).  This allows uC/OS-II to keep track of interrupt nesting and thus 
*              only perform rescheduling at the last nested ISR. 
* 
* Arguments  : none 
* 
* Returns    : none 
* 
* Notes      : 1) This function should be called ith interrupts already disabled 
*              2) Your ISR can directly increment OSIntNesting without calling this function because 
*                 OSIntNesting has been declared 'global'.   
*              3) You MUST still call OSIntExit() even though you increment OSIntNesting directly. 
*              4) 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. 
*              5) You are allowed to nest interrupts up to 255 levels deep. 
*              6) I removed the OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL() around the increment because 
*                 OSIntEnter() is always called with interrupts disabled. 
********************************************************************************************************* 
*/ 
 
void  OSIntEnter (void) 
{ 
    if (OSRunning == TRUE) { 
        if (OSIntNesting < 255) { 
            OSIntNesting++;                      /* Increment ISR nesting level                        */ 
        } 
    } 
} 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                               EXIT ISR 
* 
* Description: This function is used to notify uC/OS-II that you have completed serviving an ISR.  When 
*              the last nested ISR has completed, uC/OS-II 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 OS_SchedLock()) 
********************************************************************************************************* 
*/ 
 
void  OSIntExit (void) 
{ 
#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */ 
    OS_CPU_SR  cpu_sr; 
#endif 
     
     
    if (OSRunning == TRUE) { 
        OS_ENTER_CRITICAL(); 
        if (OSIntNesting > 0) {                            /* Prevent OSIntNesting from wrapping       */ 
            OSIntNesting--; 
        } 
        if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Reschedule only if all ISRs complete ... */ 
            OSIntExitY    = OSUnMapTbl[OSRdyGrp];          /* ... and not locked.                      */ 
            OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]); 
            if (OSPrioHighRdy != OSPrioCur) {              /* No Ctx Sw if current task is highest rdy */ 
                OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy]; 
                OSCtxSwCtr++;                              /* Keep track of the number of ctx switches */ 
                OSIntCtxSw();                              /* Perform interrupt level ctx switch       */ 
            } 
        } 
        OS_EXIT_CRITICAL(); 
    } 
} 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                          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(). 
********************************************************************************************************* 
*/ 
 
#if OS_SCHED_LOCK_EN > 0 
void  OSSchedLock (void) 
{ 
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */ 
    OS_CPU_SR  cpu_sr; 
#endif     
     
     
    if (OSRunning == TRUE) {                     /* Make sure multitasking is running                  */ 
        OS_ENTER_CRITICAL(); 
        if (OSLockNesting < 255) {               /* Prevent OSLockNesting from wrapping back to 0      */ 
            OSLockNesting++;                     /* Increment lock nesting level                       */ 
        } 
        OS_EXIT_CRITICAL(); 
    } 
} 
#endif     
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                          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(). 
********************************************************************************************************* 
*/ 
 
#if OS_SCHED_LOCK_EN > 0 
void  OSSchedUnlock (void) 
{ 
#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */ 
    OS_CPU_SR  cpu_sr; 
#endif     
     
     
    if (OSRunning == TRUE) {                                   /* Make sure multitasking is running    */ 
        OS_ENTER_CRITICAL(); 
        if (OSLockNesting > 0) {                               /* Do not decrement if already 0        */ 
            OSLockNesting--;                                   /* Decrement lock nesting level         */ 
            if ((OSLockNesting == 0) && (OSIntNesting == 0)) { /* See if sched. enabled and not an ISR */ 
                OS_EXIT_CRITICAL(); 
                OS_Sched();                                    /* See if a HPT is ready                */ 
            } else { 
                OS_EXIT_CRITICAL(); 
            } 
        } else { 
            OS_EXIT_CRITICAL(); 
        } 
    } 
} 
#endif     
 
/*$PAGE*/ 
/* 
********************************************************************************************************* 
*                                          START MULTITASKING 
* 
* Description: This function is used to start the multitasking process which lets uC/OS-II manages the 
*              task that you have created.  Before you can call OSStart(), you MUST have called OSInit() 

⌨️ 快捷键说明

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