中断响应后函数调用: 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); } } } .............................. } 用户空间中处理回调函数的一个线程。 |
|
来自: 昵称17328427 > 《待分类1》