Is anyone actually using the QP event-drive framework?

I haven't seen any posts about it, and didn't even know it was available, until I stumbled across a link on Element14.com

How much code & data space are available (on an Uno) after the framework is loaded & initialized? I would suspect that one would need to start with a 2560 to do anything practical, but I'd like to hear from someone who is actually using this framework.

http://arduino.cc/playground/Code/QP

Huh, I've never heard of this. I haven't seen anybody around here really talking about it.

I don't have an uno, although I do have a duemilanove which runs off of the same microcontroller as the UNO, so I may give it a go tomorrow and I'll let you know how it goes.

funkyguy4000: Huh, I've never heard of this. I haven't seen anybody around here really talking about it.

I don't have an uno, although I do have a duemilanove which runs off of the same microcontroller as the UNO, so I may give it a go tomorrow and I'll let you know how it goes.

The docs on Arduino.cc are hard to find unless you know what you're looking for. I wouldn't be surprised if a lot of people didn't know about this framework.

I use a simplified version: event processing and state machine. In my case, the whole application fits fairly easily on an ATtiny85 processor. I have no idea how expensive the complete framework is.

whats the simplified version called?

No name. I modified QP for my own use.

Looks like a great article. You can always use a bigger processor, like an Atmega1284P with 128K of program memory.

I ran across this the other day too, and found this thread while looking for opinions on it. It seems to fit my idea of how to program a microcontroller, probably because I did some real-time programming a long time ago. Compared to the stuff I used to do this seems luxurious -- a pub/sub interrupt handler, event queuing, a choice of pre-emptive or not, etc.

One of the docs says it takes 1-2k of flash, so it's apparently not too heavy.

If I have time I'll try it out and post my findings.

I haven't seen QP before. I wrote a cooperative task scheduler for the Arduino a whole ago, not as comprehensive as QP judging from the documentation (for example, no preemption), but lightweight and adequate for the projects I build. One day I may get around to publishing it.

The QP examples seemed overly complex, so I made a try at coding a simple blink sketch last night, but so far I’ve had no luck at runtime. It compiles, but it doesn’t even output the serial stuff during setup (BSP_init does that). The led doesn’t blink.

It is a lot of code to set up resources and manage the control flow. I’m also learning the Arduino IDE, so I’m not even sure which files it’s linking to, but I copied a couple to this sketch from the Dining Philosophers QP example.

In any case this attempt just has two states, on and off, and sets up timer events to trigger the transitions. I did learn a bit about how periodic events are set up, and how the class is written to accept events and do state transitions, but it looks like I’m still in the dark about getting it initialized.

#include <qp_port.h>
#include “bsp.h”
#include <qf.h>

enum DPPSignals {
ON_SIG,
OFF_SIG
};

#define BLINK_PERIOD 100
#define ON_TIME 50

class Blinker :
public QP::QActive {
private**:**
uint8_t led_num; // led to blink
QP::QTimeEvt off_timeEvt;
QP::QTimeEvt on_timeEvt;

public**:**
Blinker()
:
QActive((QP::QStateHandler)&Blinker::initial),
off_timeEvt(OFF_SIG),
on_timeEvt(ON_SIG),
led_num(13) // constant for now
{
}

protected**:**
static QP::QState initial (Blinker *me, QP::QEvent const *e) {
me->subscribe(ON_SIG); // subscribe to HUNGRY
me->subscribe(OFF_SIG); // subscribe to DONE
me->off_timeEvt.postEvery( me, BLINK_PERIOD );
me->on_timeEvt.postEvery( me, BLINK_PERIOD );
me->off_timeEvt.rearm( ON_TIME ); // rephase by ON_TIME
return Q_TRAN(&Blinker::off);
};

static QP::QState on (Blinker *me, QP::QEvent const *e) {
switch (e->sig) {
case OFF_SIG:
return Q_TRAN( &Blinker::off );
default:
{
digitalWrite( 13, HIGH );
return Q_HANDLED();
}
}
};
static QP::QState off (Blinker *me, QP::QEvent const *e) {
switch (e->sig) {
case ON_SIG:
return Q_TRAN( &Blinker::on );
default:
{
digitalWrite( 13, LOW );
return Q_HANDLED();
}
}
};
};

static QP::QEvent const *l_blinkQueueSto[5]; // queue for blinker
static QP::QSubscrList l_subscrSto[10];
static QF_MPOOL_EL(QP::QEvt) l_smlPoolSto[5];//storage for small epool

// the one true blinker
static Blinker l_Blinker;
QP::QActive * const AO_Blinker = &l_Blinker;

void setup() {
pinMode(13, OUTPUT);

QP::QF::init(); // initialize the framework and the underlying RT kernel

BSP_init(); // initialize the BSP

// initialize event pools…
QP::QF::poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0]));

QP::QF::psInit(l_subscrSto, Q_DIM(l_subscrSto)); // init publish-subscribe

// start the active objects…

AO_Blinker->start(1,
l_blinkQueueSto, Q_DIM(l_blinkQueueSto),
(void *)0, 0U);
}