1.3. Event Taking Configuration

Event taking is an asynchronous activity. Before taking event data the GGLT driver requires two user supplied call back functions. One is a memory allocator and the other is an event handler.

1.3.1. Memory Allocation Callback

When an event is detected the GGLT driver calls a user supplied memory allocator to retrieve storage for the event. The function signature of the memory allocator is identical to malloc(). This allows the user to manager memory however they want.

Currently the driver requests 4K of memory for each event, but this is subject to change. The following code shows a very simple implementation of a memory allocator and how to set it in the GGLT driver.


  /* 
     event handling memory allocator

     Current implementation is a simple wrapper around malloc().
     Good enough for debugging a couple events at time.

  */
  static void *evAlloc( size_t nBytes) {

    unsigned int *p;
    p = (unsigned int *)malloc(nBytes);
    printf("evAlloc: allocated %d bytes @ addr 0x%08x\n", nBytes, (unsigned int)p);
    return (void *) p;
  }

  ...

  /* set memory allocator callback */
  status = ggEvtSetAllocate( gg, evAlloc);	

1.3.2. Event Handler Callback

After allocating storage the event the GGLT driver reads the event data from the LAT COMM I/O Board and into the allocated buffer. Next the GGLT driver calls a user supplied event handler, passing in the buffer, the buffer length in bytes and a status code.

A sample event handler is shown below that simply prints the event data as a list of unsigned ints. Note that the return value from the event handler controls further event processing. If the return value is non-zero no further event processing will occur.


  /* 
     the return value of evHandler controls further event processing.
     returning any value other than G_OK will terminate event processing
     and cause the ggEvtWait() function to return (returning non G_OK
     value returned by evHandler).
  */
  static int evHandler( void *buf, size_t nBytes, int status) {
    
    int i;
    unsigned int *pEv = (unsigned int *)buf;

    for ( i = 0;  i < nBytes/sizeof(unsigned int) ; i++) {
       printf("evHandler(): \t event payload 32-bit word 0x%08x, %d\n", *pEv++, i);
    }
    
    ...

  /* set event handler callback routine */
  status = ggEvtSetHandler( gg, evHandler);

A simple ASCII based event decoder is provided by the EVUT CMX package.

1.3.3. Event Loop

Once the call back functions are in place the user is ready to enter the event processing loop. The event processing loop continually processes events until the event handler ( see Section 1.3.2 ) returns a non-zero value. This allows the user to control the termination of event processing in the event handler callback.

Entering the event processing loop looks like:


  /* enter event processing loop */
  status = ggEvtWait( gg);

The function ggEvtWait() does not return until the event handler returns a non-zero value. The value returned by ggEvtWait() is the same non-zero value that the event handler returned.