Chibios C++ Notifications templates

I’ve found myself using memory pools + mailboxes a lot to pass data between different processes.

For example, I read sensors, pass the data to a process which filters that, and then pass the result to another process which saves it.

Originally I had one memory pool / mailbox per server process, but I found that limiting for several reasons – I didn’t want the main server thread to have to wait if a client was being slow processing the data, and I wanted the client to have control over how much data it needed buffering. So instead I swapped it around, and created a few helper classes for automating the process.

Firstly I define a message:

class SensorData : public NotifierMsg<SensorData> {
public:
    int16_t _acc[3], _gyro[3], _mag[3];
    float acc[3], gyro[3], mag[3];
    systime_t time;
    uint32_t status;
    bool_t magData(void);
};

Then the server:

class SensorHandler : public EnhancedThread<256>, public Notifier<SensorData> {
private:
    Sensor *acc, *mag, *gyro;
protected:
    virtual msg_t Main(void);
public:
    SensorHandler(Sensor*, Sensor*, Sensor*);
};

And then start the process:

SensorHandler sensors( acc, gyro, mag);

The client thread registers a listener on the server, specifying a cache of 2:

Listener<SensorData, 2> sensor_listener(&sensors);

Then in my server thread I populate the message and ‘broadcast’ it:

d.status = (gyro->getData(d._gyro, d.gyro) << SENS_GYR_DATA) |
(acc->getData(d._acc, d.acc) << SENS_ACC_DATA) |
(mag->getData(d._mag, d.mag) << SENS_MAG_DATA);

/* broadcast data */
Notifier::broadcast(&d);

Meanwhile I create a client Listener, and handle the data:

Listener<SensorData, 2> sensor_listener(&sensors);
int i=0;

i = 99;
while(true) {
    SensorData *data = sensor_listener.getData();
    if(++i == 100) {
        cPrintf("[%d %d %d] ", data->_acc[0], data->_acc[1], data->_acc[2]);
        cPrintf("[%d %d %d]\r\n", data->_gyro[0], data->_gyro[1], data->_gyro[2]);
        i = 0;
    }
    sensor_listener.releaseData(data);
}

The full code can be found on GitHub.

Leave a Reply

Your email address will not be published. Required fields are marked *