Embedded Freaks..

November 17, 2008

Composite Pattern for C (AVR-GCC)

Filed under: avr, programming-tips — Tags: , — kunilkuda @ 5:41 pm

In java, you can have composite pattern easily using interface, like this:

Animal[] animals = new Animal[] { new Elephant(), new Cow(), new Cat() };
for(Animal currAnimal : animals) {
  // Do the stuff here
}

Now, I want to have the same thing for serial RX interrupt in AVR. Something like this:

ISR(USART0_RX_vect) {
  uint8_t data = UDR0;
  for(InterruptHandler currHandler: interruptHandlers) {
    currHandler.handle(data);
  }
}

By that way, I can chain the interrupt handler easily. Of course, mixing C and Java in C-compiler won’t be OK for AVR-GCC. But I found out some way to do the similar thing in C.


static void (*rxListener[])(uint8_t data) = {LoopbackListener_listen, LoopbackListener_listen};
#define LISTENER_NUM (sizeof(rxListener) / sizeof(void *))

ISR(USART0_RX_vect) {
  uint8_t data = UDR0;

  uint8_t iListener;
  for (iListener = 0; iListener < LISTENER_NUM; iListener++) {
    (*rxListener[iListener])(data);
  }
}

Assuming that LoopbackListener_listen() has the same interface as rxListener (void func(uint8_t data)), this method will chain the interrupt handler.

To make it easier to modify, we can place the chain list of the interrupt handler in separate header file, like this

// In header file
#define SERIAL_RX_LISTENER {LoopbackListener_listen, LoopbackListener_listen}

// In C file
static void (*rxListener[])(uint8_t data) = SERIAL_RX_LISTENER;
#define LISTENER_NUM (sizeof(rxListener) / sizeof(void *))

ISR(USART0_RX_vect) {
uint8_t data = UDR0;

uint8_t iListener;
for (iListener = 0; iListener &lt; LISTENER_NUM; iListener++) {
(*rxListener[iListener])(data);
}
}

So, finally, I can chain the interrupt handler, add/delete/ and modify it, easily.

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: