createthreadenhanced.c
来自「zilog的实时操作系统RZK,可以移植到多种处理器上」· C语言 代码 · 共 302 行
C
302 行
/*
* File : CreateThread.c
*
* Description : Defines RZKCreateThread function.
*
* 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 files*/
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include "ZSysgen.h"
#include "ZTypes.h"
#include "ZThread.h"
#include "ZQueue.h"
#include "ZScheduler.h"
#include "externvar.h"
#include "ZInterrupt.h"
#include "ZRegion.h"
#define pCurrentThread ((RZK_TCB_t *) hCurrentThread)
#ifdef RZK_TOOLSMITH
#define INIT_STACK_OFFSET 27
#else
#define INIT_STACK_OFFSET 27
#endif
/* Globals */
extern RZK_THREAD_CB_t nTcb[]; /* Changed on 08-05-03 */
/*dependencies*/
/** extern functions */
extern void* RZKMemcpy(void *, const void *, RZK_LENGTH_t); // IAR port, UINT changed to RZK_LENGTH_t
//extern void RZKScheduler();
extern void RZKInitStackEnhanced(RZK_HANDLE_t *sp, RZK_TCB_t *pTCB, UINT8 nArgs, RZK_HANDLE_t *Args);
extern RZK_HANDLE_t AcquireControlBlock( RZK_TCB_t *, UINT, UINT) ;
extern void QueueAppend(RZK_TCB_t *pInsertionPosition,RZK_TCB_t *pObjectToAppend) ;
extern void DispatchQueueNodeAppend(RZK_TCB_t *pObjectToAppend) ;
extern void RZKSystemTimerIsrEntry();
/** extern variables */
extern RZK_THREADHANDLE_t hCurrentThread; /* declared in Scheduler.c */
extern RZK_DISPATCHQ_t DispatchQueue[DMAX_PRIORITY_P1];/*declared in DispatchQinit.c*/
extern RZK_TIMEQ_t TimeQueue[TMAX_QUEUE];
extern const UINT32 pMap[32];
extern volatile UINT32 DQPriorityBitMap;
extern UINT8 uRegBankBusyBitMap;
extern TICK_t uDefaultTimeSlice;
// CWD IMPLEMENTATION
extern INT8 fsCwdPath[] ;
extern UINT8 fsEnable ;
extern INT8 fsCwdArray[1][1] ;
// IAR port comment
//extern UINT nRzkMaxCwdPathLen ;
extern UINT8 fsInAppEntry ;
#ifdef RZK_NT
static INT nThread;
LPTHREAD_START_ROUTINE pEntryNT;
#endif
/* Function Definition */
/* Function : RZKCreateThread
*
* Description : This function Creates an RZK Thread.
*
* Inputs : RZK_NAME_t szName[8] NAME OF THE THREAD TO BE CREATED
* RZK_PTR_t pEntryPoint POINTER TO THE ENTRY POINT OF THE FUNCTION
* RZK_PTR_t pArgv POINTER TO THE LIST OF ARGUMENTS OF THE ENTRYPOINT FUNCTION
* RZK_PTR_t pCleanupFunctions POINTER TO THE CLEANUP FUNCTIONS
* int* pInitialStack CURRENT STACK POINTTER LOCATION
* RZK_THREAD_PRIORITY_t cPriority GLOBAL THREAD PRIORITY VARIABLE
* TICK_t tQuantum THREAD RUN TIME QUANTUM
* RZK_OPERATIONMODE_t uOperationMode OPERATION MODE FLAG FOR THE NEW THRAD
*
* Outputs : pTcb - Pointer to the TCB of type RZK_THREADHANDLE_t if success
* NULL - if unsuccessful
*
* Dependencies : None.
*/
RZK_THREADHANDLE_t RZKCreateThreadEnhanced
(
RZK_NAME_t szName[MAX_OBJECT_NAME_LEN],
// RZK_PTR_t pEntryPoint, // For IAR PORT
RZK_PTR_t pEntryPoint, // For IAR PORT
FNP_THREAD_ENTRY *pCleanupFunction, // IAR port
// VOID (**pCleanupFunction) (),
COUNT_t uStackSize,
RZK_THREAD_PRIORITY_t cPriority,
TICK_t tQuantum,
RZK_OPERATIONMODE_t uOperationMode,
UINT8 nArgs,
...
)
{
/* Start of the Create Thread Function. */
RZK_TCB_t *pTCB;
UINT8 *args;
CADDR_t pInitialStack;
args = &nArgs;
#ifdef RZK_DEBUG
if (pEntryPoint == NULL)
{
pCurrentThread->errNum = RZKERR_INVALID_ARGUMENTS;
return NULL;
}
if(pEntryPoint != (RZK_PTR_t)RZKSystemTimerIsrEntry)
if (cPriority < DMIN_PRIORITY || cPriority > DMAX_PRIORITY)
{
pCurrentThread->errNum = RZKERR_INVALID_PRIORITY;
return NULL;
}
if( (uOperationMode & RZK_THREAD_INTERRUPT) &&
(uOperationMode & RZK_THREAD_AUTOSTART) )
{
pCurrentThread->errNum = RZKERR_INVALID_ARGUMENTS;
return NULL;
}
#endif /* for RZK_DEBUG */
/* Call AcquireControlBlock Function */
pTCB = (RZK_TCB_t *) AcquireControlBlock( (RZK_TCB_t *)&nTcb[0], MAX_THREADS,sizeof(RZK_TCB_t)); /* &nTcb[0] Changed on 08-05-03 */
#ifndef RZK_PERFORMANCE
if (pTCB == NULL)
{
pCurrentThread->errNum = RZKERR_CB_UNAVAILABLE;
return NULL;
}
else pCurrentThread->errNum = RZKERR_SUCCESS;
#endif /* RZK_PERFORMANCE_DEBUG */
#ifdef RZK_KERNEL_AWARE
if(szName == NULL)
RZKMemcpy(pTCB->szName, "NoName", MAX_OBJECT_NAME_LEN);
else
RZKMemcpy(pTCB->szName, szName, MAX_OBJECT_NAME_LEN);
if(strlen((char *)szName) >= MAX_OBJECT_NAME_LEN)
{
pCurrentThread->errNum = RZKERR_INVALID_SIZE;
pTCB->uState = 0;
return NULL;
}
#endif /* KERNEL_AWARE */
/* Allocating stack size */
/* CR */
pTCB->uStackSize = uStackSize;
pTCB->pInitialStack = pInitialStack = malloc(uStackSize);
if (pInitialStack == NULL)
{
pCurrentThread->errNum = RZKERR_INVALID_STACK;
pTCB->uState = 0;
return NULL;
}
pInitialStack += uStackSize;
/* SETTING Tcb VALUES */
#ifdef RZK_DEBUG
pTCB ->magic_num = MAGIC_NUM_THREAD;
#endif
#ifdef RZK_NT
pEntryNT = (LPTHREAD_START_ROUTINE)pEntryPoint;
pTCB->hNTThread = (void *) CreateThread(NULL, 0, pEntryNT, NULL, CREATE_SUSPENDED |THREAD_SUSPEND_RESUME, &(pTCB->ThreadID[nThread++]));
#endif
/* setting the dispatch priority */
// pTCB->cDispPriority = (pTCB->RZK_INIT.cGlobalPriority = pTCB->cGlobalPriority = cPriority) >> 2;
/* Now only dispatch priroity concept remains in RZK1.1 release */
pTCB->cDispPriority = cPriority;
/* Setting the original priority and the inherited priority for priority inheritance */
#ifdef RZK_PRIORITYINHERITANCE
pTCB ->uOriginalPriority = pTCB-> cDispPriority;
pTCB ->cInheritedPriority = DMAX_PRIORITY;
pTCB ->pOwnedResNext = NULL;
#endif /* End of RZK_PRIORITYINHERITANCE */
/* setting the Operation Mode */
pTCB->uOperationMode = pTCB->RZK_INIT.uOperationMode = uOperationMode;
if ( tQuantum == (TICK_t ) 0 ) /* if tQuantum = 0, then default timeslice */
{
pTCB->RZK_INIT.tInitialQuantum = 0;
pTCB->tRRTime = pTCB->tQuantum = uDefaultTimeSlice;
}
else
pTCB->tRRTime = pTCB->RZK_INIT.tInitialQuantum = pTCB->tQuantum = tQuantum;
#ifdef RZK_STATISTIC
pTCB->RZK_STATISTICS.tTotalTimeRun = 0;
pTCB->RZK_STATISTICS.tActualTimeRun = 0;
pTCB->RZK_STATISTICS.nNumTimesBlocked = 0;
#endif
// pTCB->RZK_INIT.pArgv = pArg;
/* The program Counter will point to the start of the function.*/
pTCB->pFuncEntryPoint = pEntryPoint;
/* Also initialize the cleanup fuctions.*/
pTCB->pCleanupFunc = pCleanupFunction;
pTCB->hObject = NULL;
pTCB->uBankSelector = 0;
/* Initialize the adjacent threads while in resource queue to NULL*/
pTCB->pResNext = pTCB->pResPrevious = ( RZK_TCB_t *) NULL;
/* set the pBlockingResource to NULL*/
pTCB->pBlockingResource = NULL;
/* Some initializations when thread gets created. Old thread's values must not be retained here */
pTCB->tWaitTime = 0;
pTCB->errNum = RZKERR_SUCCESS;
pTCB->pMessage = NULL;
pTCB->uMessageSize = 0;
pTCB->eEventsReceived = 0;
pTCB->eEventsRequested = 0;
pTCB->etEventOperation = (RZK_EVENT_OPERATION_et) 0;
pTCB->uSegSize = 0;
pTCB->pSeg = NULL;
pTCB->pOwnedSegNext = NULL;
/* Some initializations when thread gets created. Old thread's values must not be retained here */
pTCB->hObject = (RZK_HANDLE_t) pTCB;
/*Initialize the stack pointer to the position of the pInitStack. */
#ifdef _IAR_CODE
if(nArgs > 3)
pInitialStack -= (INIT_STACK_OFFSET + ((nArgs - 3)*3)); //space for arguments
else
pInitialStack -= INIT_STACK_OFFSET; //space for arguments
#else
pInitialStack -= (INIT_STACK_OFFSET + (nArgs*3)); //space for arguments
#endif
RZKInitStackEnhanced((RZK_HANDLE_t *) pInitialStack, pTCB, nArgs,(RZK_HANDLE_t *)(&args[3]));
/* set CREATED field in uState also */
pTCB->uState = OBJECT_CREATED | OBJECT_BUSY | THREAD_INFINITESUSPEND;
// FS CWD related inheritation
if( fsEnable )
{
if( fsInAppEntry == RZK_TRUE )
{
// copy the configured string here...
RZKMemcpy( ( void * ) pTCB->pFSCwd, ( const void * ) fsCwdPath, nRzkMaxCwdPathLen ) ;
}
else
{
// copy the calling threads string here...
RZKMemcpy( ( void * ) pTCB->pFSCwd, ( const void * ) pCurrentThread->pFSCwd, nRzkMaxCwdPathLen ) ;
}
}
/* Below code gets executed only if there is no interrupt mode and AUTOSTART option is
specified for the thread */
if(pTCB->uOperationMode & RZK_THREAD_AUTOSTART)
/* IF Autostart, add the thread to Dispatch Queue */
{
UINTRMASK mInterruptMask;
mInterruptMask = RZKDisableInterrupts();
DispatchQueueNodeAppend(pTCB);
/* Set the RUNNING bit */
pTCB->uState = OBJECT_CREATED | OBJECT_BUSY | THREAD_RUNNING;
RZKEnableInterrupts(mInterruptMask);
mInterruptMask = RZKDisableInterrupts();
RZKScheduler();
RZKEnableInterrupts(mInterruptMask);
} /* End of AUTOSTART */
return ((RZK_THREADHANDLE_t) pTCB);
} /* End of CreateThread */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?