📄 emos_core.c
字号:
/****************************************************************************
*
* (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 + -