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

📄 smutillib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
字号:
/* smUtilLib.c - VxWorks shared memory utility library *//* Copyright 1984-1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01i,17mar99,dat	  added SM_INT_USER_1 and SM_INT_USER_2, spr 2580401h,08feb96,dat   fixed smUtilSoftTas, SPR #5888, fixed some		  compiler warnings.01g,12oct94,ism   added philm's workaround for SPR#257801f,12feb93,jdi   fixed parameter comments in smUtilIntGen() to keep mangen		  happy -- in case we ever publish this one.01e,23jun92,elh   cleanup, documentation.01d,02jun92,elh   the tree shuffle		  -changed includes to have absolute path from h/01c,27may92,elh	  fixed bug in smUtilIntRoutine && smUtilPollTask.01b,15may92,pme	  added smUtilIntConnect, smUtilIntRoutine, smUtilPollTask.01a,07feb92,elh	  created.*//*DESCRIPTIONThis module is the shared memory utility library.  It contains the routines needed of VxWorks by the shared memory libraries (smPktLib,smObjLib and smLib).  INTERNALThis file corresponds to the smUtilLib for sunOs.  If a change is madeto either file, ensure that both are updated if appropriate. Refer to smLib for more information about the layering of shared memory modules.SEE ALSO: if_sm, smPktLib, smLib, smObjLib*//* includes */#include "vxWorks.h"#include "smLib.h"#include "smUtilLib.h"#include "netinet/in.h"#include "iv.h"#include "vxLib.h"#include "taskLib.h"#include "logLib.h"#include "intLib.h"#include "stdio.h"#include "stdlib.h"#include "sysLib.h"/* defines */#define DEFAULT_TAS_CHECKS	10		/* rechecks for soft tas */#define TAS_CONST		0x80/* globals */int 		smUtilVerbose   = FALSE;	/* verbose mode */int 		smUtilTasChecks = DEFAULT_TAS_CHECKS;VOIDFUNCPTR	smUtilTasClearRtn = NULL;FUNCPTR		smUtilUser1Rtn = NULL; /* returns STATUS */FUNCPTR		smUtilUser2Rtn = NULL; /* returns STATUS */				/* number of times to recheck soft tas *//* list of shared memory event handling routines */SM_ROUTINE 	smUtilNetRoutine = { NULL, 0};SM_ROUTINE 	smUtilObjRoutine = { NULL, 0};/* poll task parameters */int     	smUtilPollTaskStackSize   = 0x2000;       /* stack size */int     	smUtilPollTaskOptions     = 0;            /* options */int     	smUtilPollTaskPriority    = 254;          /* priority *//* locals */LOCAL int	smUtilTasValue = 0;		/* special soft tas value */LOCAL int  	smUtilPollTaskID;               /* polling task id *//* forwards */LOCAL	void 	smUtilPollTask (void);/********************************************************************************* smUtilSoftTas - software emulation of test-and-set function** This routine emulates an inidivisable hardware test-and-set function.* The lock specified by <lockLocalAdrs> is read to confirm that it is* initially zero.  The lock is then set to a special value used only by* this cpu, and is repeatedly re-read to check if any other processor* has attempted to obtain access to the lock.  If no such conflict is* detected, this routine returns TRUE.** The number of checks made after setting the lock value may be changed* by setting the global variable, smUtilTasChecks.  The default number* is 10.** All the above is performed with interrupts disabled on the local processor.** RETURNS: TRUE if value successfully set (was previously not set), or*          FALSE if value already set or another CPU stole lock.*/BOOL smUtilSoftTas    (    volatile int * lockLocalAdrs	/* local address of lock variable */    )    {    FAST int	value;			/* value to place in lock variable */    FAST int	nChecks;		/* number of times to re-check lock */    FAST int	count;			/* running count of re-checks */    int		oldLvl;			/* previous interrupt level */    if (smUtilTasValue == 0)	smUtilTasValue =  htonl ((TAS_CONST + sysProcNumGet())<< 24);    value   = smUtilTasValue;			/* special value to write */    nChecks = smUtilTasChecks;			/* number of checks to do */    /* Lock out interrupts */    oldLvl = intLock ();    /* Test that lock variable is initially empty */    if (*lockLocalAdrs != 0)	{	intUnlock (oldLvl);	return (FALSE);				/* someone else has lock */	}    /* Set lock value */    *lockLocalAdrs = value;    /* Check that no one else is trying to take lock */    for (count = 0;  count < nChecks;  count++)	{	if (*lockLocalAdrs != value)	    {	    intUnlock (oldLvl);	    return (FALSE);			/* someone else stole lock */	    }	}    intUnlock (oldLvl);    return (TRUE);				/* exclusive access obtained */    }/********************************************************************************* smUtilDelay - delay ** RETURNS: OK if successful, otherwise ERROR. */STATUS smUtilDelay    (    char *	pAddr,			/* address */    int 	ticks           	/* number of ticks to delay */    )    {    return (taskDelay (ticks));    }/********************************************************************************* smUtilMemProbe - probe memory** This routine safely probes a location in memory.  ** RETURNS:* OK if the probe is successful, or ERROR if the probe caused a bus error or* an address misalignment.*/STATUS smUtilMemProbe    (    FAST char *		pAddr,    /* address to be probed          */    int 		op, 	  /* VX_READ or VX_WRITE           */    int 		size,     /* 1, 2, or 4                    */    FAST char *		pVal     /* where to return value,        */                       		 /* or ptr to value to be written */    )    {    if (smUtilVerbose)	printf ("smUtilMemProbe:op[%s] addr:[0x%x] size:[%d]\n", 		(op == VX_READ) ? "read" : "write", (UINT) pAddr, size);    return (vxMemProbe (pAddr, op, size, pVal));    }/********************************************************************************* smUtilRateGet - get the system clock rate** RETURNS: The number of ticks per second of the system clock.*/int smUtilRateGet (void)    {    return (sysClkRateGet ());    }/********************************************************************************* smUtilProcNumGet - get the processor number** RETURNS: The processor number for this CPU board.*/int smUtilProcNumGet (void)    {    return (sysProcNumGet ());    }/********************************************************************************* smUtilTas - shared memory hardware test-and-set function** RETURNS: TRUE if the value had not been set but is now, or*          FALSE if the value was set already.*/BOOL smUtilTas    (    char *	adrs			/* address to be tested and set */    )    {    return (sysBusTas (adrs));    }/********************************************************************************* smUtilTasClear - shared memory clear hardware test-and-set function** INTERNAL* The function pointer smUtilTasClearRtn is currently set by the BSPs * if a test-and-set clear routine is required of the board support package. * Ultimately, the desired solution is that each BSP will provide a sysBusTasClear* routine that can be called directly from smUtilTasClear.** RETURNS: N/A*/void smUtilTasClear    (    char *	adrs			/* address to be tested and set */    )    {    if (smUtilTasClearRtn != NULL)  	(*smUtilTasClearRtn) (adrs);    else	*adrs = 0;    }/********************************************************************************* smUtilIntGen - interrupt the destination cpu.** smUtilIntGen gets called by the shared memory libraries to interrupt a * cpu to notify it of an incoming packet or an event.  smUtilIntGen provides * the following methods for interrupting the destination CPU:* mail box interrupts (SM_INT_MAILBOX), bus interrupts (SM_INT_BUS),  user* defined procedure 1 (SM_INT_USER1), user defined procedure 2 (SM_INT_USER2),* and none (SM_INT_NONE).  Refer to smLib.h for these actual values.* * RETURNS: OK if successful, otherwise ERROR.*/STATUS smUtilIntGen    (    SM_CPU_DESC *	pCpuDesc,	/* local addr of destination */					/* cpu descriptor */    int			cpuNum 		/* destination cpu number */    )    {    int			bogus;		/* bogus space */    char * 		pMailbox = NULL;/* mailbox */    int			intType;	/* interrupt type */    int			intArg1;    int			intArg2;    int			intArg3;    intType = ntohl (pCpuDesc->intType);	/* byte swap */    /* polling needs no arguments */    if (intType == SM_INT_NONE)    	return (OK);				/* destination polling */    /* Bus interrupts use 2 arguments */    intArg1 = ntohl (pCpuDesc->intArg1);    intArg2 = ntohl (pCpuDesc->intArg2);    if (intType == SM_INT_BUS)	{	return (sysBusIntGen (intArg1, intArg2));	}    /* all other methods use all 3 arguments */    intArg3 = ntohl (pCpuDesc->intArg3);    if ((intType >= SM_INT_MAILBOX_1) && (intType <= SM_INT_MAILBOX_R4))	{	/* For mailboxes, arg1 is addrSpaceId, arg2 is address */	if (sysBusToLocalAdrs (intArg1, (char *) intArg2, &pMailbox) == ERROR)	    {	    if (smUtilVerbose)		logMsg ("smUtilIntGen:unable to calculate mailbox [0x%x]\n",			intArg2, 0, 0, 0, 0, 0);	    return (ERROR);	    }	}    switch (intType)	{    	case SM_INT_MAILBOX_1:	    *pMailbox = (char) intArg3;	    break;    	case SM_INT_MAILBOX_2:	    *(short *) pMailbox = intArg3;	    break;     	case SM_INT_MAILBOX_4:	    *(long *)  pMailbox = intArg3;	    break;    	case SM_INT_MAILBOX_R1:	    bogus = *(volatile char *) pMailbox;	    break;    	case SM_INT_MAILBOX_R2:	    bogus = *(volatile short *) pMailbox;	    break;    	case SM_INT_MAILBOX_R4:	    bogus = *(volatile long *) pMailbox;	    break;	case SM_INT_USER_1:	    if (smUtilUser1Rtn != NULL)		return (*smUtilUser1Rtn)(intArg1, intArg2, intArg3);	    return ERROR;	case SM_INT_USER_2:	    if (smUtilUser2Rtn != NULL)		return (*smUtilUser2Rtn)(intArg1, intArg2, intArg3);	    return ERROR;	default:	    printf ("smUtilIntGen:Unknown intType [%x]\n", intType);	    return (ERROR);			/* unknown interrupt type */	}    return (OK);    }/********************************************************************************* smUtilIntConnect - connect the shared memory interrupts** This routine connects up how this CPU (ie mailbox, bus or polling task) gets* notified of incomming shared memory packets or shared memory events.** RETURNS: OK if successful, otherwise ERROR.*/STATUS smUtilIntConnect    (    int			priorityType,	/* handler priority LOW or HIGH */    FUNCPTR		routine,	/* routine to connect */    int                 param,          /* unit number */    int                 intType,        /* interrupt method */    int                 intArg1,        /* interrupt argument #1 */    int                 intArg2,        /* interrupt argument #2 */    int                 intArg3         /* interrupt argument #3 */    )    {    STATUS              status = ERROR; /* return status */    if (priorityType == LOW_PRIORITY)	{	smUtilNetRoutine.routine = routine;	smUtilNetRoutine.param   = param;	}    else	{	smUtilObjRoutine.routine = routine;	smUtilObjRoutine.param   = param;	}    switch (intType)        {        case SM_INT_BUS:                        /* bus interrupts */            if ((intConnect (INUM_TO_IVEC (intArg2), smUtilIntRoutine, 0)		 != ERROR) && (sysIntEnable (intArg1) != ERROR))                status = OK;            break;        case SM_INT_NONE:                       /* polling */           if ((taskIdVerify (smUtilPollTaskID) == OK)   ||                ((smUtilPollTaskID =                 taskSpawn ("tsmPollTask", smUtilPollTaskPriority,                             smUtilPollTaskOptions, smUtilPollTaskStackSize,                             (FUNCPTR) smUtilPollTask, 0, 0, 0, 0, 0, 0, 0,                             0, 0, 0)) != ERROR))            	status = OK;            break;        case SM_INT_MAILBOX_1:                  /* mailbox interrupts */        case SM_INT_MAILBOX_2:        case SM_INT_MAILBOX_4:        case SM_INT_MAILBOX_R1:        case SM_INT_MAILBOX_R2:        case SM_INT_MAILBOX_R4:            if ((sysMailboxConnect ((FUNCPTR) smUtilIntRoutine, 0) != ERROR) &&                (sysMailboxEnable ((char *) intArg2) != ERROR))                {                status = OK;                }            break;        case SM_INT_USER_1:        case SM_INT_USER_2:	    /* No special action, user code does it all */	    break;        default:            logMsg ("smUtilIntConnect:Unknown interrupt type %d\n",                    intType, 0, 0, 0, 0, 0);            break;        }    return (status);    }/********************************************************************************* smUtilIntRoutine - generic shared memory interrupt handler** This routine is connected to the shared memory interrupts. It calls* dedicated handlers for incomming shared memory packets or shared* memory  objects events.** RETURNS: N/A*/void smUtilIntRoutine (void)    {    /* call each routine stored in the list */    if (smUtilObjRoutine.routine != NULL)	(* smUtilObjRoutine.routine) (smUtilObjRoutine.param);    if (smUtilNetRoutine.routine != NULL)	(* smUtilNetRoutine.routine) (smUtilNetRoutine.param);    }/********************************************************************************* smUtilPollTask - task level generic shared memory events handler** This task handles the shared memory events.  It calls dedicated * handlers for incomming shared memory packets or shared memory * objects events.** RETURNS: N/A*/LOCAL void smUtilPollTask (void)    {    FOREVER	{	if (smUtilObjRoutine.routine != NULL)	    (* smUtilObjRoutine.routine) (smUtilObjRoutine.param);	if (smUtilNetRoutine.routine != NULL)	    (* smUtilNetRoutine.routine) (smUtilNetRoutine.param);	}    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -