中断响应后函数调用:
ArchIpcInt_interruptRegister (obj->remoteProcId,
obj->params.localIntId,
_NotifyDriverShm_ISR,
(Ptr) obj);
这个函数在前面提到过,注册中断函数,即有中断时就调用_NotifyDriverShm_ISR函数。
这个处理感觉有点问题
Static Bool _NotifyDriverShm_ISR (Void * arg)
{
UInt32 payload = 0;
UInt32 i = 0;
volatile NotifyDriverShm_EventEntry * eventEntry;
NotifyDriverShm_Object * obj;
UInt32 eventId;
obj = (NotifyDriverShm_Object *) arg;
i = 0;
do{
eventId = obj->regChart [i];
eventEntry = EVENTENTRY (obj->selfEventChart, obj->eventEntrySize, (UInt32)eventId);
payload = eventEntry->payload;
eventEntry->flag = NotifyDriverShm_DOWN;
Notify_exec (obj->notifyHandle, eventId, payload);
}while()
...................
}
显然上面的这个函数是对数组regChart进行轮询,找出对应的eventId,再通过eventId找到对应的eventEntry,最后执行Notify_exec (obj->notifyHandle, eventId, payload);
Void Notify_exec (Notify_Object * obj, UInt32 eventId, UInt32 payload)
{
Notify_EventCallback * callback;
callback = &(obj->callbacks [eventId]);
callback->fnNotifyCbck (obj->remoteProcId,
obj->lineId,
eventId,
callback->cbckArg,
payload);
...........................................................
}
显然此函数是调用对应event的callbacks 函数,即Notify_execMany 函数。
Void Notify_execMany (UInt16 procId,
UInt16 lineId,
UInt32 eventId,
UArg arg,
UInt32 payload)
{
Notify_Object * obj = (Notify_Object *) arg;
List_Handle eventList;
List_Elem * listener;
eventList = &(obj->eventList [eventId]);
List_traverse (listener, eventList)
{
((Notify_EventListener *) listener)->callback.fnNotifyCbck (procId,
lineId,
eventId,
((Notify_EventListener *) listener)->callback.cbckArg,
payload);
}
......................................
}
即循环执行对应enventId的enventList链表中对应的函数,即为_Notify_drvCallback
Static Void _Notify_drvCallback (UInt16 procId,
UInt16 lineId,
UInt32 eventId,
UArg arg,
UInt32 payload)
{
NotifyDrv_EventCbck * cbck;
cbck = (NotifyDrv_EventCbck *) arg;
_NotifyDrv_addBufByPid (procId,
lineId,
cbck->pid,
eventId,
payload,
cbck->func,
cbck->param);
..............................
}
Static Int _NotifyDrv_addBufByPid (UInt16 procId,
UInt16 lineId,
UInt32 pid,
UInt32 eventId,
UInt32 data,
Notify_FnNotifyCbck cbFxn,
Ptr param)
{
NotifyDrv_EventPacket * uBuf = NULL;
if (NotifyDrv_state.eventState [i].pid == pid)
uBuf = (NotifyDrv_EventPacket *)
kmalloc (sizeof (NotifyDrv_EventPacket), GFP_ATOMIC);
uBuf->procId = procId;
uBuf->lineId = lineId;
uBuf->data = data;
uBuf->eventId = eventId;
uBuf->func = cbFxn;
uBuf->param = param;
uBuf->isExit = FALSE;
List_put (NotifyDrv_state.eventState [i].bufList, &(uBuf->element));
OsalSemaphore_post (NotifyDrv_state.eventState [i].semHandle);
if (isExit == TRUE)
{
OsalSemaphore_pend (NotifyDrv_state.eventState [i].terSemHandle,
OSALSEMAPHORE_WAIT_FOREVER) ;
}
.........................................
}
以上两个函数是将回调函数信息放在NotifyDrv_state.eventState [i].bufList中
Static Int NotifyDrv_read (struct file * filp, char * dst, size_t size, loff_t *offset)
{
NotifyDrv_EventPacket * uBuf = NULL;
NotifyDrv_EventPacket tBuf;
retVal = copy_from_user ((Ptr) &tBuf, (Ptr) dst, sizeof (NotifyDrv_EventPacket));
for (i = 0 ; i < MAX_PROCESSES ; i++)
{
if (NotifyDrv_state.eventState [i].pid == tBuf.pid)
{
flag = TRUE;
break;
}
}
status = OsalSemaphore_pend ( NotifyDrv_state.eventState [i].semHandle,
OSALSEMAPHORE_WAIT_FOREVER);
uBuf = (NotifyDrv_EventPacket *) List_get (NotifyDrv_state.eventState [i].bufList);
retVal = copy_to_user ((Ptr) dst, uBuf, sizeof (NotifyDrv_EventPacket));
if (uBuf->isExit == TRUE)
{
OsalSemaphore_post ( NotifyDrv_state.eventState [i].terSemHandle);
}
.................................
}
将回调函数信息由内核传到用户空间。
Void _NotifyDrvUsr_eventWorker (Void * arg)
{
while (status >= 0)
{
memset (&packet, 0, sizeof (NotifyDrv_EventPacket));
packet.pid = getpid ();
nRead = read (NotifyDrvUsr_handle, &packet, sizeof (NotifyDrv_EventPacket));
if (nRead == sizeof (NotifyDrv_EventPacket))
{
if (packet.isExit == TRUE)
{
pthread_exit (NULL);
}
if (packet.func != NULL)
{
packet.func (packet.procId,
packet.lineId,
packet.eventId,
packet.param,
packet.data);
}
}
}
..............................
}
用户空间中处理回调函数的一个线程。