Using RTOS thread within class?

11 May 2013

Hello there,

after a break I'm starting working with mbed again - many things I knew before have disappeared...

Using RTOS is totally new for me, I tried a few samples and I thought I could use this in my project. I want to use a thread within a class, instead of a ticker. Using a ticker works by writing

 ti_refr.attach(this,&QDisp::update,0.1);

(for example).

This doesn't work if I transfer this technique using threads (for example):

Thread thread(this,&CLASS::DoThings);
// or
thread = new Thread(this,&CLASS::DoThings);

I always get error messages like: "no instance of constructor "rtos::Thread::Thread" matches the argument list" .

How is it done the right way?

Thanks in advance!

Michael

16 May 2013

I have the same problem. It would be great if one of the mbed experts could answer this question.

Regards.

21 May 2013

I usually do it with a static callback, an idea I copied from donatien:

In header:

#define START_THREAD 1

class MyClass {

   ...other stuff...

   static void threadStarter(void const *p);

   void threadWorker();

   Thread _thread;
};

So, you've got a signal START_THREAD which will be used to start a static thread, you've got a static function called threadStarter which will be called in the constructor of the object, and you've got threadWorker which will be called by threadStarter on the object. This might not make sense yet, but it will.

In the constructor you construct the thread, passing in the static callback, and a copy of the object pointer:

MyClass::MyClass(...args...)
   : _thread(&MyClass::threadStarter, this, osPriorityNormal,1024),
   ...args... {
   // constructor stuff
   _thread.signal_set(START_THREAD);  
}

At the end of the constructor, you send a message to the static thread for it to start. The starter looks like this:

void MyClass::threadStarter(void const *p) {
  MyClass *instance = (MyClass*)p;
  instance->threadWorker();
}

So it casts the pointer for the invoking object to the proper type, then calls the worker thread. The worker thread looks like this:

void MyClass::threadWorker() {
  _thread.signal_wait(START_THREAD);
  while(1) {
    // do stuff  
   }
}

The worker thread waits for the appropriate signal to ensure that the constructor has completely finished. You could do everything in the static callback, on the instance, but by calling threadWorker, you then have a proper class context so can access private members etc.

You can also imagine starting the thread later, but in this way you have the thread starting when the class is fully constructed, which makes some kind of sense.

HTH

21 May 2013

Hello Ashley,

thanks for the hint - not easy to understand on the first sight, but things slightly become clear :-)

I'll use it as a first start!

Michael

12 Mar 2015

Ashley,

I re-created your code and it crashes when _thread is instantiated in the initializer list. Do you know why this is?

13 Mar 2015

Hi,

Any idea how to adapt this for an rtos timer?

Thanks

02 Apr 2016

I have the same problem, system crashes when the "thread worker" is started.

any ideas how to solve this ?

/C

02 Jun 2016

I'm modify this library that blink leds use threads. You can edit the libary to run other function. https://developer.mbed.org/users/AVELARDEV/code/LibThreadProcess/