Notify_sendEvent的实现过程

 

.  Notify_sendEvent的实现过程

首先是从用户态的Notify_sendEvent函数开始

Int Notify_sendEvent (UInt16              procId,

                  UInt16              lineId,

                  UInt32              eventId,

                  UInt32              payload,

                  Bool                waitClear)

进入此函数后会将上面的参数进行封装,再调用

NotifyDrvUsr_ioctl (CMD_NOTIFY_SENDEVENT, &cmdArgs);

其中参数封装如下:

Notify_CmdArgsSendEvent cmdArgs;

cmdArgs.procId = procId;

cmdArgs.lineId    = lineId;

cmdArgs.eventId   = eventId;

cmdArgs.payload = payload;

cmdArgs.waitClear = waitClear;

再由ioctl进入内核态

ioctl (NotifyDrvUsr_handle, cmd, args);

再调用内核态的Notify_sendEvent函数

 Notify_sendEvent (srcArgs.procId,

                 srcArgs.lineId,

                 srcArgs.eventId,

                 srcArgs.payload,

                 srcArgs.waitClear);

进入Notify_sendEvent函数后做了以下事:

INotifyDriver_Handle driverHandle;

Notify_Object *     obj;

obj = Notify_module->notifyHandles [procId][lineId];

根据procIdlineId通过全局变量Notify_module找到对应的Notify_Object 数据

driverHandle = obj->driverHandle;

再通过Notify_Object 数据找到对应的INotifyDriver_Handle数据,该数据结构中包括的一个重要的函数指针结构体INotifyDriver_FxnTable

然后调用INotifyDriver_sendEvent函数继续往下走

INotifyDriver_sendEvent (driverHandle,

                      strippedEventId,

                      payload,

                      waitClear);

进入此函数主要执行了下面两步

INotifyDriver_Object * obj = (INotifyDriver_Object *) handle;

status = obj->fxnTable.sendEvent (obj->obj, eventId, payload, waitClear);

传进来的driverHandle(即obj)中fxnTable的函数指针是初始化过了的,其中obj->obj参数也初始化了的,她是struct NotifyDriverShm_Object_tag即(NotifyDriverShm_EventEntry)结构类型这两个的初始化我将在后面介绍,暂不考虑。

即进入了下面这个函数

Int  NotifyDriverShm_sendEvent (NotifyDriverShm_Handle handle,

                           UInt32              eventId,

                           UInt32              payload,

                           Bool                waitClear)

在这个函数中有下面几条重要的执行语句:

volatile NotifyDriverShm_EventEntry *  eventEntry;

obj = (NotifyDriverShm_Object *) handle;

eventEntry = EVENTENTRY (obj->otherEventChart, obj->eventEntrySize, eventId)

eventEntry->payload = payload;

eventEntry->flag    = NotifyDriverShm_UP;

ArchIpcInt_sendInterrupt (obj->remoteProcId,  obj->params.remoteIntId,  eventId);

上面主要实现就是找到远端对应eventIdNotifyDriverShm_EventEntry结构空间,并且将payload值存入该结构中,并赋相应的标志位,再通过ArchIpcInt_sendInterrupt 函数将eventId继续往下发。

则进入

Int32 ArchIpcInt_sendInterrupt    (UInt16 procId, UInt32 intId, UInt32 value)

这个函数很简单主要有下面一条语句:

ArchIpcInt_object.fxnTable->sendInterrupt(procId,  intId,  value); Dm8168IpcInt_setup

这个主要就是通过一个全局变量ArchIpcInt_object下的函数指针实现的,这个初始化主要在Dm8168IpcInt_setup这个函数中,这个sendInterrupt函数指针即对应的Dm8168IpcInt_sendInterrupt 函数

然后进入

Int32  Dm8168IpcInt_sendInterrupt (UInt16 procId, UInt32 intId,  UInt32 value) 

主要实现了下面两条语句

while (REG32(  Dm8168IpcInt_state.mailboxBase

                   + MAILBOX_MESSAGE_5_OFFSET) == 4);  (这个作用是什么?)

REG32(Dm8168IpcInt_state.mailboxBase + MAILBOX_MESSAGE_5_OFFSET)  = value;

即将enventId写入mailbox5中并产生中断通知vpss.

你可能感兴趣的:(Notify_sendEvent的实现过程)