📄 tmc.c
字号:
/* Resume the timer task. */
TMC_Timer_Expiration();
/* Determine if the time-slice timer has expired. */
task = TMT_Retrieve_TS_Task();
if (task)
{
NU_SUPERV_USER_VARIABLES
/* Switch to supervisor mode
Note that this HISR function can make the switch to supervisor mode
this is only possible because the code lives within the kernel */
NU_SUPERVISOR_MODE();
/* Reset the time-slice state. */
TMD_Time_Slice_State = TM_NOT_ACTIVE;
/* Process the time-slice. */
TCC_Time_Slice(task);
/* Clear the time slice task pointer. */
TMD_Time_Slice_Task = NU_NULL;
/* Return to user mode */
NU_USER_MODE();
}
}
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* TMC_Timer_Expiration */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for processing all task timer */
/* expirations. This includes application timers and basic task */
/* timers that are used for task sleeping and timeouts. */
/* */
/* CALLED BY */
/* */
/* None */
/* */
/* CALLS */
/* */
/* expiration_function Application specified timer */
/* expiration function */
/* TCC_Task_Timeout Task timeout function */
/* TCT_System_Protect Protect active timer list */
/* TCT_Unprotect Release protection of list */
/* TMC_Stop_Timer Stop timer */
/* TMC_Start_Timer Start timer */
/* TMT_Disable_Timer Disable timer */
/* TMT_Enable_Timer Enable timer */
/* */
/* INPUTS */
/* */
/* None */
/* */
/* OUTPUTS */
/* */
/* None */
/* */
/*************************************************************************/
VOID TMC_Timer_Expiration(VOID)
{
R1 TM_TCB *timer; /* Pointer to timer */
R2 TM_APP_TCB *app_timer; /* Pointer to app timer */
INT done; /* Expiration completion */
INT type = 0; /* Type of expiration */
VOID *pointer = NU_NULL; /* Pointer type */
UNSIGNED id = 0; /* Application timer ID */
/* Expiration routine ptr */
VOID (*expiration_routine)(UNSIGNED)= NU_NULL;
NU_SUPERV_USER_VARIABLES
/* Switch to supervisor mode */
NU_SUPERVISOR_MODE();
/* Use system protect to protect the active timer list. */
TCT_System_Protect();
/* Reset the timer state flag. */
TMT_Disable_Timer();
/* Set the busy flag to indicate that the list is being processed. */
TMD_Active_List_Busy = NU_TRUE;
/* Update the head of the list with the timer expiration
value. */
timer = TMD_Active_Timers_List;
if (timer)
{
/* Adjust the active timer's remaining time value. Note that
TMD_Timer_Start is never greater than the value in the first
timer location. */
if (timer -> tm_remaining_time > TMD_Timer_Start)
/* Timer has not expired. Simply subtract the last timer
value. */
timer -> tm_remaining_time = timer -> tm_remaining_time -
TMD_Timer_Start;
else
/* Clear the remaining time field of the timer. */
timer -> tm_remaining_time = 0;
}
/* Release protection, but keep the busy flag set to prevent
activating new timers. */
TCT_Unprotect();
/* Find expired timers. Note that the expired timers have values of
0 in the remaining time field. */
done = NU_FALSE;
do
{
/* Protect against list access. */
TCT_System_Protect();
/* Pickup the head of the active list. */
timer = TMD_Active_Timers_List;
/* Determine if the timer now at the head of the list has
expired. Processing continues until the list is empty or
until a non-expired timer is at the front of the list. */
if ((timer) && (timer -> tm_remaining_time == 0))
{
/* Timer has expired. Determine which type of timer has
expired. */
if (timer -> tm_timer_type == TM_APPL_TIMER)
{
/* Application timer has expired. */
type = TM_APPL_TIMER;
/* Pickup the pointer to the application timer control
block. */
app_timer = (TM_APP_TCB *) timer -> tm_information;
/* Increment the number of expirations. */
app_timer -> tm_expirations++;
#ifdef NU_PROFILE_PLUS
PRF_PLUS_TMC_TIMER_EXPIRATION_0
#endif /* NU_PROFILE_PLUS */
/* Move the expiration information into local variables
in case they get corrupted before this expiration can
be processed. Expirations are processed without the
list protection in force. */
id = app_timer -> tm_expiration_id;
expiration_routine = app_timer -> tm_expiration_routine;
/* Clear the enabled flag and remove the timer from the
list. */
app_timer -> tm_enabled = NU_FALSE;
TMC_Stop_Timer(timer);
/* Determine if this timer should be started again. */
if (app_timer -> tm_reschedule_time)
{
/* Timer needs to be rescheduled. */
/* Setup the enable flag to show that the timer is
enabled. */
app_timer -> tm_enabled = NU_TRUE;
/* Call the start timer function to actually enable
the timer. This also puts it in the proper place
on the list. */
TMC_Start_Timer(timer,app_timer -> tm_reschedule_time);
}
}
else
{
/* Task timer has expired (sleeps and timeouts). */
type = TM_TASK_TIMER;
/* Remove the timer from the list. */
TMC_Stop_Timer(timer);
/* Save-off the task control block pointer. */
pointer = timer -> tm_information;
}
}
else
/* Processing is now complete- no more expired timers on the
list. */
done = NU_TRUE;
/* Release protection of active list. */
TCT_Unprotect();
/* Determine if a timer expiration needs to be finished. Note
that the actual expiration processing is done with protection
disabled. This prevents deadlock situations from arising. */
if (!done)
{
/* Determine which type of timer has expired. */
if (type == TM_APPL_TIMER)
/* Call application timer's expiration function. */
(*(expiration_routine)) (id);
else
/* Call the task timeout function in the thread control
function. */
TCC_Task_Timeout((NU_TASK *) pointer);
}
} while (!done);
/* Protect the active list again. */
TCT_System_Protect();
/* Clear the busy flag to indicate that list processing is complete. */
TMD_Active_List_Busy = NU_FALSE;
/* Determine if a new timer should be enabled. */
if (TMD_Active_Timers_List)
{
/* Yes, a new timer should be activated. */
/* Pickup the new timer expiration value. */
TMD_Timer_Start = TMD_Active_Timers_List -> tm_remaining_time;
/* Start the new timer. */
TMT_Enable_Timer(TMD_Timer_Start);
}
/* Release protection of the active timer list. */
TCT_Unprotect();
/* Return to user mode */
NU_USER_MODE();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -