Search code examples
c++rtosmbed

Using an RtosTimer inside a class


I'm trying to use an RtosTimer within a class but the mbed locks up. I think this is because I'm calling threadHelper each tick and its creating a new pointer whereas I actually want to call threadMethod each tick or call threadHeper each tick but use the same pointer.

Can anyone show me how I should be doing this?

The code below works for an RtosThread because threadHelper is only called once, but I need to use an Rtos Timer.

.h

#ifndef TEST_CLASS_H
#define TEST_CLASS_H

#include "mbed.h"
#include "rtos.h"

/** TestClass class.
 *  Used for demonstrating stuff.
 */
class TestClass
{
public:
    /** Create a TestClass object with the specified specifics
     *
     * @param led The LED pin.
     * @param flashRate The rate to flash the LED at in Hz.
     */
    TestClass(PinName led, float flashRate);

    /** Start flashing the LED using a Thread
     */
    void start();

private:
    //Member variables
    DigitalOut m_Led;
    float m_FlashRate;
    RtosTimer *m_rtosTimer;

    //Internal methods
    static void threadHelper(const void* arg);
    void threadMethod();
};

#endif

cpp

#include "TestClass.h"

TestClass::TestClass(PinName led, float flashRate) : m_Led(led, 0), m_FlashRate(flashRate)
{
    //NOTE: The RTOS hasn't started yet, so we can't create the internal thread here
}

void TestClass::start()
{
    m_rtosTimer = new RtosTimer(&TestClass::threadHelper, osTimerPeriodic, (void *)0);
    int updateTime = (1.0 / m_FlashRate) * 1000;
    m_rtosTimer->start(updateTime);
}

void TestClass::threadHelper(const void* arg)
{
    //Cast the argument to a TestClass instance pointer
    TestClass* instance = (TestClass*)arg;

    //Call the thread method for the TestClass instance
    instance ->threadMethod();
}

void TestClass::threadMethod()
{
    //Do some stuff
}

Thanks


Solution

  • The arg pointer passed to threadHelper() is the argument you passed ot the RtosTimer constructor - in this case a null-pointer. threadHelper() dereferences this null-pointer causing a runtime error.

    Instead:

    m_rtosTimer = new RtosTimer(&TestClass::threadHelper, osTimerPeriodic, (void*)this);