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

📄 rzksystemtimerisr.c

📁 zilog的实时操作系统RZK,可以移植到多种处理器上
💻 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 + -