ralf htp
ralf htp

Reputation: 9422

How does Contiki OS process external interrupts?

It is possible to wake sensor nodes on external interrupts that are generated by peripheral sensors. The following explains how Contiki OS handles external interrupts. In case of the ATmega128RFA1 the external interrupts INT0 to INT4 are able to wake the MCU even from deep sleep.

Upvotes: 0

Views: 1689

Answers (1)

ralf htp
ralf htp

Reputation: 9422

an overview over processes and interupts in contiki is here:

https://github.com/contiki-os/contiki/wiki/Processes

http://de.slideshare.net/DingxinXu/contiki-introduction-iifrom-what-to-how

http://senstools.gforge.inria.fr/doku.php?id=os:contiki

contiki utilizes the ISR vectors of the MCU

this example is for ATmega128RFA1. the external interrupt is INT0 on PD0 (pin 25)

in the ISR the only action is to poll an associated contiki process. Internally this sends a poll request to the process. The process catches the poll request and then executes the calculations associated with the external interrupt. This proceeding prevents long lasting calculations in the ISR.

ISR :

ISR(INT0_vect)
{            

  process_poll(&extern_interupt_process);
  PRINTF("interrupt was triggered on INT0... \n");  

}

to enable the external interupts on INT0:

EIMSK = 0xb00000000; //disable interrupts before changing EICRA EICRA |= 0xb00000011; //EICRA 0000|0011 rising edge triggers interrupt int0 EIMSK |= 0xb00000001; // enable INT0 (datasheet p. 219 ff)

process :

PROCESS(extern_interupt_process, "external_interrupt_process");

PROCESS_THREAD(extern_interupt_process, ev, data)
{


  PROCESS_BEGIN();


  while(1) {

    PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);

    // process data here 

           }


  PROCESS_END();

}

use autostart_process() to start the extern_interrupt_process or start it manually in contiki-main.c

if the sensor has an open collector output activate the internal pull-up resistor and set the interrupt control register to trigger an interrupt on low-level (see this: wiring a sensor with open collector output)

DDRD  &= 0xb00000000;   // PD0 as input
PORTD |= 0xb00000001;  // enable internal pull-up on PD0
EIMSK &= 0xb00000000; //disable interrupts before changing EICRA
EICRA &= 0xb00000000; //EICRA 0000|0000 low-level triggers interrupt on int0
EIMSK |= 0xb00000001; // enable INT0` (datasheet p. 219 ff)

http://en.wikipedia.org/wiki/Open collector

Upvotes: 2

Related Questions