📄 rzksystemtimerisr.c
字号:
/*
* File : RZKSystemTimerIsr.c
*
* Description : This file contains the RZKSystemTimerIsr function which maintains
* RZK's timing related activities.
*
* Copyright 2004 ZiLOG Inc. ALL RIGHTS RESERVED.
*
* This file contains unpublished confidential and proprietary information
* of ZiLOG, Inc.
* NO PART OF THIS WORK MAY BE DUPLICATED, STORED, PUBLISHED OR DISCLOSED
* IN ANY FORM WITHOUT THE PRIOR WRITTEN CONSENT OF ZiLOG, INC.
* This is not a license and no use of any kind of this work is authorized
* in the absence of a written license granted by ZiLOG, Inc. in ZiLOG's
* sole discretion
*/
#include <stdio.h>
#include "ZSysgen.h"
#include "ZTypes.h"
#include "ZThread.h"
#include "ZQueue.h"
#include "ZMessageQ.h"
#include "ZScheduler.h"
#include "ZTimer.h"
#include "ZSemaphore.h"
#include "ZInterrupt.h"
#include "externvar.h"
/*Define the conditions to be checked as macros*/
RZK_THREADHANDLE_t hRRThread;
#define Q1EMPTY (pTimeQ1 == (RZK_TCB_t *) &TimeQueue[TIME_Q1])
#define Q2EMPTY (pTimeQ2 == (RZK_TCB_t *) &TimeQueue[TIME_Q2])
#define pRRThread ((RZK_TCB_t *) hRRThread)
#define pTimer ((RZK_TIMER_t *) pTimeQ1)
extern UINT8 bTaskChangeFlag;
TICK_t tRZKTicks;
//static TICK_t tDTicksModulo;
static TICK_t tRZKTicksModulo;
extern RZK_TIMEQ_t TimeQueue[];
extern RZK_DISPATCHQ_t DispatchQueue[];
extern const UINT32 pMap[32];
extern volatile UINT32 DQPriorityBitMap;
extern void RestorePriorityRecursive(RZK_HANDLE_t) ;
extern void DispatchQueueAppend(RZK_TCB_t *pObjectToRemove );
extern void DispatchQueueRemove(RZK_TCB_t *pObjectToRemove );
/* macros for determining the maximum and minimum time for timer objects */
#define MinTime(A,B) (((unsigned) A) < ((unsigned) B) ? (A) : (B))
#define MaxTime(A,B) (((unsigned) A) > ((unsigned) B) ? (A) : (B))
TIME_t tSystemTime;
TIME_t SysUpTime;
extern UINT8 cTim;
UINT32 RZKTicks;
/*
* Function : RZKSystemTimerIsr
*
* Description : This function is used to update the timer queue status and
* for system time keeping of the system.
*
* Inputs : None
*
* Outputs : None
*
* Dependencies : bTaskChangeFlag
*/
void RZKSystemTimerISR()
{
UINT16 uBlockingReason; // IAR changed from UCHAR to UINT16
RZK_TCB_t *pTimeQ1,*pTimeQ2;
// TICK_t tCurrentTicks; // IAR
UINT was_first_element;
pTimeQ1 = TimeQueue[TIME_Q1].pNext;
pTimeQ2 = TimeQueue[TIME_Q2].pNext;
#if RZK_DEVTICKS_PERSYSTICK > 1
if (tDTicksModulo < RZK_DEVTICKS_PERSYSTICK)
{
tDTicksModulo ++;
return;
}
/*reset the modulo count to zero*/
tDTicksModulo = 0;
#endif
tRZKTicks ++;
if ( (tRZKTicks%5) == 0)
RZKTicks++;
/* check whether time queues are empty,if not update the time ticks of the first element of both the queues*/
if(!Q1EMPTY)
{
-- (pTimeQ1->tWaitTime);
/* Now remove all the objects from the queue for which tWaitTime is zero*/
while(pTimeQ1->tWaitTime == 0 && !Q1EMPTY )
{
/* Remove the object from TQ1 */
QueueNodeRemove(pTimeQ1);
/* Check whether the object de-queued is thread object by checking it's uState.
If the object is a thread object add it to the dispatch queue */
if(!(pTimeQ1 -> uState & THREAD_RUNNING))
{
if(!(pTimeQ1->uState & THREAD_INFINITESUSPEND))
{
UINTRMASK mInterruptMask;
mInterruptMask = RZKDisableInterrupts();
DispatchQueueNodeAppend(pTimeQ1);
RZKEnableInterrupts(mInterruptMask);
pTimeQ1->uState |= THREAD_RUNNING;
bTaskChangeFlag = RZK_TRUE;
}
pTimeQ1->uState &= ~(THREAD_BLOCKEDSUSPEND);
pTimeQ1->uBlockingReason = 0;
/*AJ $ 15Sep05 $CR#### $ suspended thread does not return 'Err timeout' bug */
pTimeQ1->errNum = RZKERR_TIMEOUT;
}
else /* The object being removed is timer object */
{
/*If the timer is enabled execute the timer function and update the statistics */
/* execute the timer function */
// tCurrentTicks = tRZKTicks;
// IAR changed
(*pTimer->pFuncPtr)();
// (*((void(*)())(pTimer->pFuncPtr)))();
/* Update the statistics of the thread */
#ifdef RZK_STATISTIC
if(pTimer->uFuncExecutionCount == 0)
{
pTimer->tFirstTimeOfFuncEntry = tRZKTicks;
}
else
{
pTimer->tMinTimeOfFuncEntry = MinTime((tRZKTicks - pTimer->tPrevTimeOfFuncEntry),pTimer->tMinTimeOfFuncEntry);
pTimer->tMaxTimeOfFuncEntry = MaxTime((tRZKTicks - pTimer->tPrevTimeOfFuncEntry),pTimer->tMaxTimeOfFuncEntry);
}
pTimer->uFuncExecutionCount ++;
pTimer ->tPrevTimeOfFuncEntry = tRZKTicks;
#endif
if(pTimer->tPeriod != MAX_INFINITE_SUSPEND)
{
pTimer->tWaitTime = pTimer->tPeriod;
AddToTimeQ1((RZK_TCB_t *) pTimer);
}
} /* end of timer object operation */
/* Make pTimeQ1 point to the next element in the queue */
pTimeQ1 = TimeQueue[TIME_Q1].pNext;
}/*End of while loop*/
}/*End of If loop for checking Q1 not empty */
/*Checking the TimeQ2*/
if(!Q2EMPTY)
{
--(pTimeQ2->tWaitTime);
while((pTimeQ2->tWaitTime == 0) && !Q2EMPTY)
{
/* store the ublocking reason temporarily */
uBlockingReason = pTimeQ2->uBlockingReason;
#ifdef RZK_PRIORITYINHERITANCE
was_first_element = (((RZK_SEMAPHORE_t *)(pTimeQ2->pBlockingResource))->pResNext == pTimeQ2);
#endif
/*Remove the thread from the resource queue */
RemoveFromResourceQueue(pTimeQ2->pBlockingResource,pTimeQ2);
#ifdef RZK_PRIORITYINHERITANCE
/* If the blocking resource is a binary
semaphore and priority inheritance enabled, then restore the priority of the owner thread recursively*/
if(((((RZK_SEMAPHORE_t *)(pTimeQ2->pBlockingResource))->uState) & OBJECT_PRIORITY_INHERITANCE)&& (was_first_element))
{
/* restores both the inherited and dispatch priority recursively */
RestorePriorityRecursive(((RZK_SEMAPHORE_t*)(pTimeQ2->pBlockingResource))->pOwnerThread);
}
#endif/* end of RZK_PRIORITYINHERITANCE*/
/* Update the thread status and remove from TQ2*/
UpdateThreadStatus(pTimeQ2,RZKERR_TIMEOUT);
/* Check whether the thread being removed is the only one in the resource queue
If so set the etWaitingQueue to MESSAGE_NONE*/
if((((RZK_MESSAGEQUEUE_t*)pTimeQ2->pBlockingResource)->pResNext == NULL) && (uBlockingReason &(BLOCK_POSTMESSAGEQUEUE |BLOCK_PENDMESSAGEQUEUE | BLOCK_POSTMAILBOX | BLOCK_PENDMAILBOX)))
{
((RZK_MESSAGEQUEUE_t*)pTimeQ2->pBlockingResource)->etWaitingQueue = MESSAGE_NONE;
}
/* Set the task change flag to indcate that a change in context is required*/
bTaskChangeFlag = RZK_TRUE;
pTimeQ2 = TimeQueue[TIME_Q2].pNext;
} /* End of while loop*/
} /*End of if loop to check queue not empty condition*/
/* Update the Round Robin time for the currently
running thread if it is enabled*/
if(pRRThread->uState & THREAD_RUNNING)
{
if((pRRThread->uOperationMode & (RZK_THREAD_ROUNDROBIN |
RZK_THREAD_PREEMPTION))== (RZK_THREAD_ROUNDROBIN |RZK_THREAD_PREEMPTION))
{
/*If the round robin time has reached zero then de-queue it
from the dispatch queue and append it to the end of the same */
if(--pRRThread->tRRTime == 0)
{
/* Remove the thread from dispatch queue and append it to the end
of the same. */
UINTRMASK mInterruptMask;
mInterruptMask = RZKDisableInterrupts();
DispatchQueueRemove(pRRThread);
DispatchQueueAppend(pRRThread);
RZKEnableInterrupts(mInterruptMask);
pRRThread->tRRTime = pRRThread->tQuantum;
bTaskChangeFlag = RZK_TRUE;
}
}
}
/*Update the system time */
if (tRZKTicksModulo != RZK_SYSTICKS_INSEC)
{
tRZKTicksModulo++ ;/*Defined as a global*/
}
else
{
tRZKTicksModulo = 1;
/* Increment the system time */
tSystemTime ++;
}
SysUpTime++;
}/*End of ISR */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -