📄 driver.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 + -