Passing arguments and mbed::Callback to a Thread constructor.

28 Feb 2019

Hi,

I just got started with mbed, i'm using:

  • mbed IDE.
  • Nucleo-F401RE.

I'm trying to create a Thread passing an argument to it by using the following Thread constructor:

Thread (T *argument, void(T::*task)(), osPriority priority=osPriorityNormal, uint32_t stack_size=OS_STACK_SIZE, unsigned char *stack_mem=NULL)

This is my code:

#include "mbed.h"
#include "stats_report.h"

DigitalOut led1(LED1);

void led_thread(uint8_t toggle_time)
{

    while (true) {
        led1 = !led1;
        wait(toggle_time);
    }
}

uint8_t green_led_toggle_time = 1;

// main() runs in its own thread in the OS
int main(void)
{
    Thread thread(
        &green_led_toggle_time,
        led_thread,
        osPriorityNormal            /* thread priority */,
        OS_STACK_SIZE               /* stack_size */,
        NULL                        /* stack_mem */
    );

    while (true) {

    }
}

I'm having the following error:

Quote:

no matching constructor for initialization of rtos::Thread

I haven't been able to find examples similar to what i want to do, maybe my google-foo isn't working tho.

28 Feb 2019

I think i found the issue,

It seems that the constructor i was trying to use is marked as deprecated, is that right?

/media/uploads/C47D/mbed.png

So i have to use thread.start(led_thread).

01 Mar 2019

Hello Carlos,

Deprecated means that there is a better way to do it, but it still should work. The problem here is that a pointer shall be passed to the task rather than a value. Try:

void led_thread(uint8_t* toggle_time)
{
    while (true) {
        led1 = !led1;
        wait(*toggle_time);
    }
}

And to avoid the 'deprecated' message:

Thread thread;

uint8_t green_led_toggle_time = 1;

int main(void)
{
//    Thread thread(
//        &green_led_toggle_time,
//        led_thread,
//        osPriorityNormal            /* thread priority */,
//        OS_STACK_SIZE               /* stack_size */,
//        NULL                        /* stack_mem */
//    );
    
    
    thread.start(callback(led_thread, &green_led_toggle_time));

    while (true) {

    }
}
04 Mar 2019

Hi,

Zoltan Fegyver wrote:

The problem here is that a pointer shall be passed to the task rather than a value.

Thanks for the help, indeed passing the argument as a pointer solves the issue. This is the program i ended up with:

/* mbed Microcontroller Library
 * Copyright (c) 2018 ARM Limited
 * SPDX-License-Identifier: Apache-2.0
 */

#include "mbed.h"
#include "stats_report.h"

DigitalOut led1(LED1);

#define SLEEP_TIME                  500
#define PRINT_AFTER_N_LOOPS         20

uint8_t green_toggle_time = 5;

void led_thread(uint8_t *toggle_time)
{
    while (true) {
        led1 = !led1;
        wait(*toggle_time);
    }
}

// main() runs in its own thread in the OS
int main(void)
{
    Thread thread(
        &green_toggle_time,
        led_thread,
        osPriorityNormal            /* thread priority */,
        OS_STACK_SIZE               /* stack_size */,
        NULL                        /* stack_mem */
    );

    SystemReport sys_state( SLEEP_TIME * PRINT_AFTER_N_LOOPS);

    int count = 0;
    while (true) {
        wait_ms(SLEEP_TIME);

        if ((0 == count) || (PRINT_AFTER_N_LOOPS == count)) {
            // Following the main thread wait, report on the current system status
            sys_state.report_state();
            count = 0;
        }
        ++count;
    }
}

One more question, does thread.start(callback(...)) is the new syntax for what i am trying to do?

05 Mar 2019
06 Mar 2019

Thanks for the links, i will check them out. I think the main question is solved now, thanks for the help!