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

📄 driver.c

📁 一种操作系统源码核
💻 C
字号:
#if !defined(__EBOS_H)
#include "ebos.h"
#endif
/*
*********************************************************************************************************
*                                          driver COMPOENTimplement FILE 
*********************************************************************************************************
*/

static DRIVER_DCB DriverTable[MAX_DRIVER_NUM];
static void DriverCleanup(void *information);
static DRIVER_DCB *DriverFreeList;        //可用事件组列表


/*
*********************************************************************************************************
*                                      CREATE A driver and then places it on the list of created driveres.


*********************************************************************************************************
*/
static SIGNED _NewDriverId()
{
	static UNSIGNED Next_ID;
	UNSIGNED  id;			/* process id to return		*/
	UNSIGNED  i;
        
       	if(DriverFreeList){
	    	id=DriverFreeList->id;
	    	DriverFreeList=DriverFreeList->next;
	   
	    	return(id);
	}
	
	return(ERR_NO_DRIVER_SPACE);

}
//吵些设备共享相同涤娇谮,因此只需创建一个驱动器,设备之间用设备号区分
//
INT8 RegisterDriver (INT8U *name,INT8U number,void (*driver_entry)(UNSIGNED dev_id,INT8U argc,void **argv))
{
     	CHAR major_id;
     	SIGNED err;
     	if(dev_num<0 ||dev_num>MAX_MINOR_DEVICES) return  ERR_INVALID_VALUE;
     	if(name==NULL) return  ERR_INVALID_VALUE;
     	if(DriverTable[driver_ptr->id]==driver_ptr) return (driver_ptr->id);
	#if DEBUG
        	DebugLog(REGISTER_DRIVER,driver_ptr);//在日志中记录操作,时间等信息
     	#endif
     	EnLock();
     	major_id=_NewDriverId();
     	if(major_id<0){
         	UnLock();
         	return (major_id);
     	}    
       
     	UnLock();
     	driver_ptr->dvname=name;
     	driver_ptr->driver_entry=driver_entry;
     
     	DriverTable[major_id]=driver_ptr;
     	driver_ptr.state=D_ACTIVE;
     	driver_ptr->major_id=major_id;
     	driver_ptr->number=number;
     	driver_ptr->current_protect=NULL;
     	for(i=0;i<MAX_MINOR_DEVICES;i++)
          	driver_ptr->task_wait_header[i]=NULL;
     	return(major_id);
        
}
/*
*********************************************************************************************************
*                                      DELETE A driver  

*********************************************************************************************************
*/
STATUS UnRegisterDriver(INT8 major_id)
{
  	
     	STATUS state,oldstate; 
      	DRIVER_DCB *driver_ptr;
      	if (major_id<0 || major_id >MAX_DRIVER_NUM) {                                 /* Not allowed to Del idle task     */
	  	return (ERR_INVALID_DRIVER);
      	}
      	driver_ptr=DriverTable[major_id];
      	#if DEBUG
          	DebugLog(DELETE_TASK,dev_id);//在日志中记录操作,时间等信息
      	#endif 
      	DoProtect(driver_ptr); 
      	if (driver_ptr.state==D_FREE) {                                 /* Not allowed to delete idle driver     */
          	return (ERR_INVALID_DRIVER);
      	}
       	for(i=0;i<MAX_MINOR_DEVICES && driver_ptr->task_wait_header[i];i++){
          	while(driver_ptr->task_wait_header[i]){
     	  		state=_ResumeTask(driver_ptr->task_wait_header[i]->task_ptr,EVENT_SUSPEND);
	  		if(state==TRUE) oldstate =state;
	  		DelHead(&(void *)(driver_ptr->task_wait_header[i]));
		}
      	}	
 
       
      	UnProtect(driver_ptr); 
      	EnLock();
      	driver_ptr->next=DriverFreeList;
      	DriverFreeList=driver_ptr;
      	DriverTable[major_id].state=D_FREE;
      	UnLock();
      
      	if(oldstate==TRUE)
          	_ControlToSystem();
      	return (OK);     
      
}

STATUS InitDriver(INT16 dev_id,struct driver_parms *parm)
{
    	DRIVER_DCB *driver_ptr;
    	STATUS ret;
       	UCHAR *argv[2];
    	UCHAR major_id; 
    	major_id=(dev_id & 0xff00)>>8;
   	if (dev_id<0 || major_id >MAX_DRIVER_NUM) {                                 /* Not allowed to Del idle task     */
		return (ERR_INVALID_DRIVER);
        }
    
    	driver_ptr=DriverTable[major_id];
      	#if DEBUG
           	DebugLog(INIT_DRIVER,dev_id);//在日志中记录操作,时间等信息
     	#endif 
      	*argv[0]=INIT_DRIVER;
      	argv[1]=(INT8U *)parm;
     	DoProtect(driver_ptr); 
      	if (driver_ptr.state==D_FREE)                                  /* Not allowed to delete idle driver     */
        	return (ERR_INVALID_DRIVER);
      
      	ret=driver_ptr->driver_entry(dev_id,2,argv);   
      	UnProtect(driver_ptr);
       	return (ret);
	
}
STATUS InitDevice(INT16 dev_id)
{
    	DRIVER_DCB *driver_ptr;
    	STATUS ret;
    
    	UCHAR argv[1];
    	UCHAR major_id;
    
    	major_id=(dev_id & 0xff00)>>8;
    	if (dev_id<0 || major_id >MAX_DRIVER_NUM) {                                 /* Not allowed to Del idle task     */
		return (ERR_INVALID_DRIVER);
        }
    	driver_ptr=DriverTable[major_id];
 	#if DEBUG
           	DebugLog(DELETE_TASK,dev_id);//在日志中记录操作,时间等信息
     	#endif 
      	*argv[0]=INIT_DEVICE;
     	DoProtect(driver_ptr); 
      	if (driver_ptr.state==D_FREE)                                  /* Not allowed to delete idle driver     */
        	return (ERR_INVALID_DRIVER);
  
      	ret=driver_ptr->driver_entry(dev_id,1,argv);   
      	UnProtect(driver_ptr);
       	return (ret);
	
}
STATUS Dv_IoCtl(INT16 dev_id,INT8U arg1,INT8U arg2)
{
   	DRIVER_DCB *driver_ptr;
   	STATUS ret;
   	UCHAR argv[3];
        UCHAR major_id;
   	major_id=(dev_id & 0xff00)>>8;
   	if (dev_id<0 || major_id >MAX_DRIVER_NUM) {                                 /* Not allowed to Del idle task     */
      		return (ERR_INVALID_DRIVER);
   	}
   	driver_ptr=DriverTable[major_id];
   	*argv[0]=IO_CTL;
   	argv[1]=&arg1;
   	argv[2]=&arg2;
 	#if DEBUG
      		DebugLog(DELETE_TASK,dev_id);//在日志中记录操作,时间等信息
   	#endif 
   	DoProtect(driver_ptr);
   	if (driver_ptr.state==D_FREE)                                  /* Not allowed to delete idle driver     */
      		return (ERR_INVALID_DRIVER);
   	ret=driver_ptr->driver_entry(dev_id,3,argv); 
   	UnProtect(driver_ptr);
   	return ret;	
}
INT8  _AddWaitQueue(DRIVER_DCB * driver_ptr,SIGNED flag); 
{
    	WAIT_QUEUE *task_suspend;		
    	#if WAIT_QUEUE_ALLOC_MODE	
      		WAIT_QUEUE  driver_wait_queue;
      		task_suspend=&driver_wait_queue;
    	#else
      		task_suspend=WaitQueueFreeList;
      		WaitQueueFreeList=WaitQueueFreeList->queue_ptr;
    	#endif  	
    	if(flag==SUSPEND){
          	task_suspend->task_ptr=((TASK_TCB *)KERNAL.current_thread);
	  	task_suspend->driver_return_status=EVENT_SUSPEND;
          	AddList(&(void *)(driver_ptr->task_wait_header[driver_ptr->minor_id]),task_suspend,0);
          	UnProtect(driver_ptr)
          	_SuspendTask(KERNAL.current_thread,EVENT_SUSPEND,DriverCleanup,driver_ptr,flag);
          	_ControlToSystem();
          	DoProtect(driver_ptr);
	  	if(driver_ptr==NULL)
	     		return(ERR_DRIVER_DELETED);
	  	if (task_suspend->driver_return_status!=FINISHED){
	     		UnProtect(driver_ptr);
	    		 return(ERR_TIMEOUT);
	   	}
	   	DelList(&(void *)(driver_ptr->task_wait_header[driver_ptr->minor_id]),task_suspend);
	   	UnProtect(driver_ptr);
	   	return (OK);

    	}
    	else{
	  	UnProtect(driver_ptr);
	  	return (ERR_NOT_PRESENT);
    	}
}	 



INT16U Dv_Input(INT16 dev_id,INT8U *read_pointer,INT16U size,INT8 * buf,SIGNED flag)
{
    	DRIVER_DCB *driver_ptr;
    	STATUS ret=OK;
    	UCHAR *argv[4];
    	UCHAR major_id;
    	UCHAR minor_id;
       	if (dev_id<0 ||major_id >MAX_DRIVER_NUM) {                                 /* Not allowed to Del idle task     */
       		return (ERR_INVALID_DRIVER);
	}
        minor_id=(dev_id & 0x00ff);
    	major_id=(dev_id & 0xff00)>>8;
 	#if DEBUG
       		DebugLog(DELETE_TASK,dev_id);//在日志中记录操作,时间等信息
   	#endif 
    
    	*argv[0]=IO_INPUT;
    	argv[1]=read_pointer;
    	argv[2]=&size;
    	argv[3]=buf;
    	driver_ptr=DriverTable[major_id];
    	DoProtect(driver_ptr);
    	if (driver_ptr.state==D_FREE)                                  /* Not allowed to delete idle driver     */
        	return (ERR_INVALID_DRIVER);
        driver_ptr->driver_entry(dev_id,4,argv);    
    	if((driver_ptr->flag) & (1<< minor_id))//等待请求完成
         	ret=_AddWaitQueue(driver_ptr,flag);      
       	else        
      		UnProtect(driver_ptr);
      	return ret;
    		
}
INT16U Dv_Output(INT16 dev_id,INT16U arg1,SIGNED flag)
{
  	DRIVER_DCB *driver_ptr;
  	STATUS ret=OK;
  	UCHAR argv[2];
  	UCHAR major_id;
  	UCHAR minor_id;
  
  	if (dev_id<0 || major_id >MAX_DRIVER_NUM) {                                 /* Not allowed to Del idle task     */
      		return (ERR_INVALID_DRIVER);
  	}
  	minor_id=(dev_id & 0x00ff);
  	major_id=(dev_id & 0xff00)>>8;
  	driver_ptr=DriverTable[major_id];
  	*argv[0]=IO_OUTPUT;
  	argv[1]=&arg1;
  	#if DEBUG
      		DebugLog(DELETE_TASK,dev_id);//在日志中记录操作,时间等信息
  	#endif 
  	DoProtect(driver_ptr);
  	if (driver_ptr.state==D_FREE)                                  /* Not allowed to delete idle driver     */
      		return (ERR_INVALID_DRIVER);
  	driver_ptr->driver_entry(dev_id,2,argv); 
  	if((driver_ptr->flag) & (1<< minor_id)){
      		ret=_AddWaitQueue(driver_ptr,flag);    
  	}   
  	else  
      		UnProtect(driver_ptr);
      	return ret;
  		
}
void SetDriverFlag(INT16 dev_id,INT8U flag)
{

   	TASK_TCB * task_ptr;
   	STATUS status;
   	DRIVER_DCB *driver_ptr;
   	UCHAR major_id;
        UCHAR minor_id;
   	if (dev_id<0 || major_id >MAX_DRIVER_NUM) {                                 /* Not allowed to Del idle task     */
      		return (ERR_INVALID_DRIVER);
  	}
  	minor_id=(dev_id & 0x00ff);
  	major_id=(dev_id & 0xff00)>>8;
   	driver_ptr=DriverTable[major_id];
 	#if DEBUG
      		DebugLog(SET_DRIVER_FLAG,major_id);//在日志中记录操作,时间等信息
   	#endif
   	DoProtect(driver_ptr);
   	if (driver_ptr.state==D_FREE)                                  /* Not allowed to Del idle driver     */
      		return (ERR_INVALID_DRIVER);
   	if( driver_ptr->task_wait_header && flag==0){//有任务等待接收消息,恢复任务,消息放入邮箱中的任务的挂起结构的消息域
           	driver_ptr->task_wait_header->driver_return_status=FINISHED
           	task_ptr=(driver_ptr->task_wait_header)->task_ptr;
 	   	UnProtect(driver_ptr);
	   	status=_ResumeTask(task_ptr,EVENT_SUSPEND);
           	if (status==TRUE)
               		_ControlToSystem();
      
  	}
 	else{
      		if(flag)
        		(driver_ptr->flag | =(1<< minor_id);
      		else
        		(driver_ptr->flag & =~(1<< minor_id);
      		UnProtect(driver_ptr);
     
  	}
  	return (OK);	
}

STATUS Dv_Open(INT16 dev_id,INT8U mode)
{
    	DRIVER_DCB *driver_ptr;
    	STATUS ret;
    	UCHAR argv[1];
       	UCHAR major_id;
    	major_id=(dev_id & 0xff00)>>8;
    	if (dev_id<0 ||	major_id >MAX_DRIVER_NUM) {                                 /* Not allowed to Del idle task     */
		return (ERR_INVALID_DRIVER);
        }
    	driver_ptr=DriverTable[major_id];
     	*argv[0]=IO_OPEN;
     	argv[1]=&mode;
   	#if DEBUG
           	DebugLog(DELETE_TASK,dev_id);//在日志中记录操作,时间等信息
     	#endif 
     	DoProtect(driver_ptr);
      	if (driver_ptr.state==D_FREE)                                  /* Not allowed to delete idle driver     */
        	return (ERR_INVALID_DRIVER);
     
     	ret=driver_ptr->driver_entry(dev_id,2,argv); 
     	UnProtect(driver_ptr);
    	return ret;
}
STATUS Dv_Close(INT16 dev_id)
{
    	DRIVER_DCB *driver_ptr;
    	STATUS ret;
    	UCHAR argv[1];
   
    	UCHAR major_id;
    	major_id=(dev_id & 0xff00)>>8;
    	if (dev_id<0 ||	major_id >MAX_DRIVER_NUM) {                                 /* Not allowed to Del idle task     */
		return (ERR_INVALID_DRIVER);
        }
    	driver_ptr=DriverTable[major_id];
     	*argv[0]=IO_CLOSE;
  	#if DEBUG
           	DebugLog(DELETE_TASK,dev_id);//在日志中记录操作,时间等信息
     	#endif 
     	DoProtect(driver_ptr);
      	if (driver_ptr.state==D_FREE)                                  /* Not allowed to delete idle driver     */
        	return (ERR_INVALID_DRIVER);
   
     	ret=driver_ptr->driver_entry(dev_id,1,argv); 
     	UnProtect(driver_ptr);
    		return ret;
}

/*
*********************************************************************************************************
*                                    REMOVE A suspension BLOCK FROM A driver
CSC_Remove_From_List
*********************************************************************************************************
*/
static void DriverCleanup(void *information)
{
  	DRIVER_DCB *driver_ptr;
     	TASK_TCB *task_ptr;
    	WAIT_QUEUE *linknode;
     	driver_ptr=(DRIVER_DCB *)information;
      	UnProtect(driver_ptr);
     	EnLock();
       	for(i=0;i<MAX_MINOR_DEVICES && driver_ptr->task_wait_header[i];i++){
       
	 	linknode=driver_ptr->task_wait_header[i];
	 	do{
	    		task_ptr=linknode->task_ptr;
	    		if (task_ptr==((TASK_TCB *)KERNAL.current_thread))
	       			DelList(&(void *)(driver_ptr->task_wait_header[i]),linknode);
	    		linknode=(WAIT_QUEUE *)(linknode->next);
	    		if (linknode==NULL) break;
	  	}while(linknode!=driver_ptr->task_wait_header[i]);
     	}	  

   	UnLock();	


}

/*
*********************************************************************************************************
*                             This function initializes the data structures OF driver component

*********************************************************************************************************
*/
  void DriverInit(void)
  {
  	UNSIGNED i;
    	for(i=0;i<MAX_DRIVER_NUM;i++)
    		DriverTable[i]=NULL;
  }	

⌨️ 快捷键说明

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