📄 os_core.c
字号:
if (dflt_time_quanta > (OS_TICK)0) {
OSSchedRoundRobinDfltTimeQuanta = dflt_time_quanta;
} else {
OSSchedRoundRobinDfltTimeQuanta = (OS_TICK)(OSCfg_TickRate_Hz / (OS_RATE_HZ)10);
}
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* YIELD CPU WHEN TASK NO LONGER NEEDS THE TIME SLICE
*
* Description: This function is called to give up the CPU when it is done executing before its time slice expires.
*
* Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE The call was successful
* OS_ERR_ROUND_ROBIN_1 Only 1 task at this priority, nothing to yield to
* OS_ERR_ROUND_ROBIN_DISABLED Round Robin is not enabled
* OS_ERR_SCHED_LOCKED The scheduler has been locked
* OS_ERR_YIELD_ISR Can't be called from an ISR
*
* Returns : none
*
* Note(s) : 1) This function MUST be called from a task.
************************************************************************************************************************
*/
#if OS_CFG_SCHED_ROUND_ROBIN_EN > 0u
void OSSchedRoundRobinYield (OS_ERR *p_err)
{
OS_RDY_LIST *p_rdy_list;
OS_TCB *p_tcb;
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Can't call this function from an ISR */
*p_err = OS_ERR_YIELD_ISR;
return;
}
#endif
if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* Can't yield if the scheduler is locked */
*p_err = OS_ERR_SCHED_LOCKED;
return;
}
if (OSSchedRoundRobinEn != DEF_TRUE) { /* Make sure round-robin has been enabled */
*p_err = OS_ERR_ROUND_ROBIN_DISABLED;
return;
}
CPU_CRITICAL_ENTER();
p_rdy_list = &OSRdyList[OSPrioCur]; /* Can't yield if it's the only task at that priority */
if (p_rdy_list->NbrEntries < (OS_OBJ_QTY)2) {
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_ROUND_ROBIN_1;
return;
}
OS_RdyListMoveHeadToTail(p_rdy_list); /* Move current OS_TCB to the end of the list */
p_tcb = p_rdy_list->HeadPtr; /* Point to new OS_TCB at head of the list */
if (p_tcb->TimeQuanta == (OS_TICK)0) { /* See if we need to use the default time slice */
p_tcb->TimeQuantaCtr = OSSchedRoundRobinDfltTimeQuanta;
} else {
p_tcb->TimeQuantaCtr = p_tcb->TimeQuanta; /* Load time slice counter with new time */
}
CPU_CRITICAL_EXIT();
OSSched(); /* Run new task */
*p_err = OS_ERR_NONE;
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* START MULTITASKING
*
* Description: This function is used to start the multitasking process which lets uC/OS-III manages the task that you
* created. Before you can call OSStart(), you MUST have called OSInit() and you MUST have created at least
* one application task.
*
* Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_FATAL_RETURN OS was running and OSStart() returned.
* OS_ERR_OS_RUNNING OS is already running, OSStart() has no effect
*
* Returns : none
*
* Note(s) : 1) OSStartHighRdy() MUST:
* a) Call OSTaskSwHook() then,
* b) Load the context of the task pointed to by OSTCBHighRdyPtr.
* c) Execute the task.
*
* 2) OSStart() is not supposed to return. If it does, that would be considered a fatal error.
************************************************************************************************************************
*/
void OSStart (OS_ERR *p_err)
{
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
if (OSRunning == OS_STATE_OS_STOPPED) {
OSPrioHighRdy = OS_PrioGetHighest(); /* Find the highest priority */
OSPrioCur = OSPrioHighRdy;
OSTCBHighRdyPtr = OSRdyList[OSPrioHighRdy].HeadPtr;
OSTCBCurPtr = OSTCBHighRdyPtr;
OSRunning = OS_STATE_OS_RUNNING;
OSStartHighRdy(); /* Execute target specific code to start task */
*p_err = OS_ERR_FATAL_RETURN; /* OSStart() is not supposed to return */
} else {
*p_err = OS_ERR_OS_RUNNING; /* OS is already running */
}
}
/*$PAGE*/
/*
************************************************************************************************************************
* GET VERSION
*
* Description: This function is used to return the version number of uC/OS-III. The returned value corresponds to
* uC/OS-III's version number multiplied by 10000. In other words, version 3.01.02 would be returned as 30102.
*
* Arguments : p_err is a pointer to a variable that will receive an error code. However, OSVersion() set this
* variable to
*
* OS_ERR_NONE
*
* Returns : The version number of uC/OS-III multiplied by 10000.
************************************************************************************************************************
*/
CPU_INT16U OSVersion (OS_ERR *p_err)
{
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return ((CPU_INT16U)0u);
}
#endif
*p_err = OS_ERR_NONE;
return (OS_VERSION);
}
/*$PAGE*/
/*
************************************************************************************************************************
* IDLE TASK
*
* Description: This task is internal to uC/OS-III and executes whenever no other higher priority tasks executes because
* they are ALL waiting for event(s) to occur.
*
* Arguments : p_arg is an argument passed to the task when the task is created.
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
*
* 2) OSIdleTaskHook() is called after the critical section to ensure that interrupts will be enabled for at
* least a few instructions. On some processors (ex. Philips XA), enabling and then disabling interrupts
* doesn't allow the processor enough time to have interrupts enabled before they were disabled again.
* uC/OS-III would thus never recognize interrupts.
*
* 3) This hook has been added to allow you to do such things as STOP the CPU to conserve power.
************************************************************************************************************************
*/
void OS_IdleTask (void *p_arg)
{
CPU_SR_ALLOC();
p_arg = p_arg; /* Prevent compiler warning for not using 'p_arg' */
while (DEF_ON) {
CPU_CRITICAL_ENTER();
OSIdleTaskCtr++;
#if OS_CFG_STAT_TASK_EN > 0u
OSStatTaskCtr++;
#endif
CPU_CRITICAL_EXIT();
OSIdleTaskHook(); /* Call user definable HOOK */
}
}
/*$PAGE*/
/*
************************************************************************************************************************
* INITIALIZE THE IDLE TASK
*
* Description: This function initializes the idle task
*
* Arguments : p_err is a pointer to a variable that will contain an error code returned by this function.
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_IdleTaskInit (OS_ERR *p_err)
{
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
OSIdleTaskCtr = (OS_IDLE_CTR)0;
/* ---------------- CREATE THE IDLE TASK ---------------- */
OSTaskCreate((OS_TCB *)&OSIdleTaskTCB,
(CPU_CHAR *)((void *)"uC/OS-III Idle Task"),
(OS_TASK_PTR)OS_IdleTask,
(void *)0,
(OS_PRIO )(OS_CFG_PRIO_MAX - 1u),
(CPU_STK *)OSCfg_IdleTaskStkBasePtr,
(CPU_STK_SIZE)OSCfg_IdleTaskStkLimit,
(CPU_STK_SIZE)OSCfg_IdleTaskStkSize,
(OS_MSG_QTY )0u,
(OS_TICK )0u,
(void *)0,
(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
(OS_ERR *)p_err);
}
/*$PAGE*/
/*
************************************************************************************************************************
* BLOCK A TASK PENDING ON EVENT
*
* Description: This function is called to place a task in the blocked state waiting for an event to occur. This function
* exist because it is common to a number of OSxxxPend() services.
*
* Arguments : p_pend_data is a pointer to an object used to link the task being blocked to the list of task(s)
* ----------- pending on the desired object.
* p_obj is a pointer to the object to pend on. If there are no object used to pend on then
* ----- the caller must pass a NULL pointer.
*
* pending_on Specifies what the task will be pending on:
*
* OS_TASK_PEND_ON_FLAG
* OS_TASK_PEND_ON_TASK_Q <- No object (pending for a message sent to the task)
* OS_TASK_PEND_ON_MUTEX
* OS_TASK_PEND_ON_Q
* OS_TASK_PEND_ON_SEM
* OS_TASK_PEND_ON_TASK_SEM <- No object (pending on a signal sent to the task)
*
* timeout Is the amount of time the task will wait for the event to occur.
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_Pend (OS_PEND_DATA *p_pend_data,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -