首先是从用户态的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];
根据procId和lineId通过全局变量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);
上面主要实现就是找到远端对应eventId的NotifyDriverShm_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.