分享

中断响应后函数调用

 昵称17328427 2014-09-28

中断响应后函数调用:

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);

...........................................................

}

显然此函数是调用对应eventcallbacks 函数,即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);

    }

......................................

}

即循环执行对应enventIdenventList链表中对应的函数,即为_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);

         }

      }

  }

..............................

}

用户空间中处理回调函数的一个线程。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多