6 years, 8 months ago.

Thread called only once

Hi, I am using STM Nucleo F767ZI development board. Here in this experiment, I am trying to operate two servos together and separately. But when the thread is called once for both the servo functions, it is not executing the second time and henceforth. I tried using software reset but it didn't help? What could be the correct solution? The code for the same experiment is provided below.

**code**

#include "mbed.h"
#include "Servo.h"
Serial pc(USBTX, USBRX); 
Servo servo1(PB_15); //10cc 
Servo servo2(PB_13); //5cc
Thread a;
Thread b;

void func_servo1()                                 
{     
    servo1.Enable(1500,20000);
    servo1.SetPosition(1090);
    wait_ms(3500);
    servo1.SetPosition(1500);
    wait_ms(3500);
    servo1.Disable();
}

void func_servo2()                                 
{     
    servo2.Enable(1500,20000);
    servo2.SetPosition(1200);
    wait_ms(2800);
    servo2.SetPosition(1500);
    wait_ms(2800);
    servo2.Disable();
}

int main() 
{    
    int op;
    //int servo1_time, servo2_time;
    servo1.Enable(1500,20000);
    servo2.Enable(1500,20000);
    while(1)
    {
        pc.printf("\n\r Press 1 for 10cc, 2 for 5cc, 3 for both: ");
        pc.scanf("%d", &op);
        switch(op)
        {
            case 1: pc.printf("\n\r Running Servo1 10cc");
                    func_servo1();
                    break;
            case 2: pc.printf("\n\r Running Servo2 5cc");
                    func_servo2();
                    break;
            case 3: pc.printf("\n\r Running Servo1 10cc and Servo2 5cc");
                    a.start(func_servo1);
                    b.start(func_servo2);
                    break;
            default: pc.printf("\n\r Error! Enter again.");                          
        }
    }
}

1 Answer

6 years, 8 months ago.

Hi, if I understand your issue, you want to use case 3 again and again. You can try this...

//Repalce
Thread a;
Thread b;
//to
Thread* a;
Thread* b;

and

//Repalce
            case 3: pc.printf("\n\r Running Servo1 10cc and Servo2 5cc");
                    a.start(func_servo1);
                    b.start(func_servo2);
                    break;
//to
            case 3: pc.printf("\n\r Running Servo1 10cc and Servo2 5cc");
                    a = new Thread;
                    b = new Thread;
                    a->start(func_servo1);
                    b->start(func_servo2);
                    break;

I not say, this is correct but working.

Accepted Answer

Thank you. Your solution did work. This was just a test code. In the main code around 20 different threads are used and they are executed many times. Will this solution work for all of them?

posted by Rishabh Gupta 16 Mar 2018

I'm not an expert on Mbed RTOS threads but unless I'm missing something this solution is going to leak memory, the old expired threads are never getting deleted. You need to delete the old threads before creating new ones.

Something like:

Thread* a = null;
Thread* b = null;

case 3: pc.printf("\n\r Running Servo1 10cc and Servo2 5cc");
                   if (a)  // if the thread exists
                     a.join();  // wait for it to finish
                   if (b)
                     b.join();
                   delete a; // free up the memory allocated to the thread
                   delete b;
                    a = new Thread; // now it's safe to create a new one
                    b = new Thread;
                    a->start(func_servo1);
                    b->start(func_servo2);
                    break;

If you try starting the threads a second time while they are still running this will block until the current ones terminate. For your example threads this isn't much of an issue but for others it may be. In that case you may need to first signal the thread that it should terminate as soon as possible and then wait for it.

posted by Andy A 16 Mar 2018