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

📄 device.c

📁 日本著名的的嵌入式实时操作系统T-Kernel的源码及用户手册。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *---------------------------------------------------------------------- *    T-Kernel * *    Copyright (C) 2004 by Ken Sakamura. All rights reserved. *    T-Kernel is distributed under the T-License. *---------------------------------------------------------------------- * *    Version:   1.01.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2004/6/28. * *---------------------------------------------------------------------- *//* *	device.c (T-Kernel/SM) *	Device Management Function */#include "sysmgr.h"#include <sys/svc/ifdevmgr.h>/* Lock for device management exclusive control */EXPORT	FastMLock	DevMgrLock;/* Semaphore for device management synchronous control */EXPORT	ID		DevMgrSync;/* Device initial setting information */LOCAL	T_IDEV		DefaultIDev;/* * Initialization of device initial setting information */LOCAL ER initIDev( void ){	T_CMBF	cmbf;	INT	val[2];	ER	err;	/* Get system information */	err = _tk_get_cfn("TDEvtMbfSz", val, 2);	if ( err < 2 ) val[0] = -1;	if ( val[0] >= 0 ) {		/* Generate message buffer for event notification */		SetOBJNAME(cmbf.exinf, "DEvt");		cmbf.mbfatr = TA_TFIFO;		cmbf.bufsz  = val[0];		cmbf.maxmsz = val[1];		err = tk_cre_mbf(&cmbf);		if ( err < E_OK ) goto err_ret;		DefaultIDev.evtmbfid = err;	} else {		/* Do not use message buffer for event notification */		DefaultIDev.evtmbfid = 0;	}	return E_OK;err_ret:	DEBUG_PRINT(("initIDev err = %d\n", err));	return err;}/* * Unregister device initial setting information */LOCAL ER delIDev( void ){	ER	err, error = E_OK;	/* Delete message buffer for event notification */	if ( DefaultIDev.evtmbfid > 0 ) {		err = tk_del_mbf(DefaultIDev.evtmbfid);		if ( err < E_OK ) error = err;		DefaultIDev.evtmbfid = 0;	}#ifdef DEBUG	if ( error < E_OK ) DEBUG_PRINT(("delIDev error = %d\n", error));#endif	return error;}/* ------------------------------------------------------------------------ *//* *	Device registration management */EXPORT	DevCB		*DevCBtbl;	/* Device registration information					   table */EXPORT	QUEUE		UsedDevCB;	/* In-use queue */LOCAL	QUEUE		FreeDevCB;	/* Unused queue */LOCAL	INT			MaxRegDev;	/* Maximum number of device					   registrations */#define	MAX_UNIT	255		/* Maximum number of subunits *//* * Verify validity of device ID */Inline ER check_devid( ID devid ){	devid >>= 8;	if ( devid < 1 || devid > MaxRegDev ) return E_ID;	return E_OK;}/* * Initialization of device registration information table */LOCAL ER initDevCB( void ){	DevCB	*devcb;	INT	num;	ER	err;	/* Get system information */	err = _tk_get_cfn("TMaxRegDev", &MaxRegDev, 1);	if ( err < 1 ) { err = E_SYS; goto err_ret; }	num = MaxRegDev;	/* Generate device registration information table */	DevCBtbl= Imalloc(num * sizeof(DevCB));	if ( DevCBtbl == NULL ) { err = E_NOMEM; goto err_ret; }	QueInit(&UsedDevCB);	QueInit(&FreeDevCB);	devcb = DevCBtbl;	while ( num-- > 0 ) {		QueInsert(&devcb->q, &FreeDevCB);		devcb->devnm[0] = '\0';		devcb++;	}	return E_OK;err_ret:	DEBUG_PRINT(("initDevCB err = %d\n", err));	return err;}/* * Search registration device */EXPORT DevCB* searchDevCB( UB *devnm ){	QUEUE	*q;	DevCB	*devcb;	for ( q = UsedDevCB.next; q != &UsedDevCB; q = q->next ) {		devcb = (DevCB*)q;		if ( devcb->devnm[0] == devnm[0]		  && strcmp(devcb->devnm, devnm) == 0 ) {			return devcb; /* Found */		}	}	return NULL;}/* * Get DevCB for new registration */LOCAL DevCB* newDevCB( UB *devnm ){	DevCB	*devcb;	devcb = (DevCB*)QueRemoveNext(&FreeDevCB);	if ( devcb == NULL ) return NULL; /* No space */	strncpy(devcb->devnm, devnm, L_DEVNM+1);	QueInit(&devcb->openq);	QueInsert(&devcb->q, &UsedDevCB);	return devcb;}/* * Free DevCB */LOCAL void delDevCB( DevCB *devcb ){	QueRemove(&devcb->q);	QueInsert(&devcb->q, &FreeDevCB);	devcb->devnm[0] = '\0';}/* * Device registration */LOCAL ID _tk_def_dev( UB *devnm, T_DDEV *ddev, T_IDEV *idev, VP caller_gp ){	DevCB	*devcb;	INT	len, evttyp;	ER	err;	LockREG();	len = ChkSpaceBstrR(devnm, 0);	if ( len < E_OK ) { err = len; goto err_ret1; }	if ( len <= 0 || len > L_DEVNM ) { err = E_PAR; goto err_ret1; }	if ( ddev != NULL ) {		err = ChkSpaceR(ddev, sizeof(T_DDEV));		if ( err < E_OK ) goto err_ret1;		if ( ddev->nsub < 0		  || ddev->nsub > MAX_UNIT ) { err = E_PAR; goto err_ret1; }		/* Make sure that the length of the logical device name		   does not exceed the character limit */		if ( ddev->nsub > 0   ) ++len;		if ( ddev->nsub > 10  ) ++len;		if ( ddev->nsub > 100 ) ++len;		if ( len > L_DEVNM ) { err = E_PAR; goto err_ret1; }	}	if ( idev != NULL ) {		err = ChkSpaceRW(idev, sizeof(T_IDEV));		if ( err < E_OK ) goto err_ret1;	}	LockDM();	/* Search whether 'devnm' device is registered */	devcb = searchDevCB(devnm);	if ( devcb == NULL ) {		if ( ddev == NULL ) { err = E_NOEXS; goto err_ret2; }		/* Get 'devcb' for new registration because it is not		   registered */		devcb = newDevCB(devnm);		if ( devcb == NULL ) { err = E_LIMIT; goto err_ret2; }	}	if ( ddev != NULL ) {		/* Set/update device registration information */		devcb->ddev = *ddev;#if TA_GP		if ( (ddev->drvatr & TA_GP) == 0 ) {			/* Apply caller 'gp' if TA_GP is not specified */			devcb->ddev.gp = caller_gp;		}#endif		if ( idev != NULL ) {			/* Device initial setting information */			*idev = DefaultIDev;		}		evttyp = TSEVT_DEVICE_REGIST;	} else {		if ( !isQueEmpty(&devcb->openq) ) {			/* In use (open) */			err = E_BUSY; goto err_ret2;		}		/* Device unregistration */		delDevCB(devcb);		evttyp = TSEVT_DEVICE_DELETE;	}	UnlockDM();	UnlockREG();	/* Device registration/unregistration notification */	tk_evt_ssy(0, evttyp, 0, DID(devcb));	return DID(devcb);err_ret2:	UnlockDM();err_ret1:	UnlockREG();	DEBUG_PRINT(("_tk_def_dev err = %d\n", err));	return err;}/* * Check device initial information */LOCAL ER _tk_ref_idv( T_IDEV *idev ){	ER	err;	err = ChkSpaceRW(idev, sizeof(T_IDEV));	if ( err < E_OK ) goto err_ret;	LockDM();	*idev = DefaultIDev;	UnlockDM();	return E_OK;err_ret:	DEBUG_PRINT(("_tk_ref_idv err = %d\n", err));	return err;}/* ------------------------------------------------------------------------ *//* * Get logical device name *	Get the logical device name from *	the physical device name (pdevnm) and the subunit number (unitno). */LOCAL void logdevnm( UB *ldevnm, UB *pdevnm, INT unitno ){	UB	unostr[12], *cp;	strcpy(ldevnm, pdevnm);	if ( unitno > 0 ) {		cp = &unostr[11];		*cp = '\0';		while (*ldevnm != '\0') ++ldevnm;		--unitno;		do {			*--cp = '0' + (unitno % 10);			unitno /= 10;		} while (unitno);		strcat(ldevnm, cp);	}}/* * Get physical device name *	Get the subunit number (return value)  *	from the logical device name (ldevnm) and the physical *	device name (pdevnm). */EXPORT INT phydevnm( UB *pdevnm, UB *ldevnm ){	UB	c;	INT	unitno;	while ( (c = *ldevnm) != '\0' ) {		if ( c >= '0' && c <= '9' ) break;		*pdevnm++ = c;		ldevnm++;	}	*pdevnm = '\0';	unitno = 0;	if (c != '\0') {		while ( (c = *ldevnm) != '\0' ) {			unitno = unitno * 10 + (c - '0');			ldevnm++;		}		++unitno;	}	return unitno;}/* * Get device name */LOCAL ID _tk_get_dev( ID devid, UB *devnm )

⌨️ 快捷键说明

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