8 years ago.

Why this thread program does not work? please help

Hello I have written the following

#include "mbed.h"
#include "rtos.h"
 
InterruptIn mybutton(USER_BUTTON);
//DigitalOut myled(LED1);
//DigitalOut led2(PA_0);
 
DigitalOut myled(PA_0);
DigitalOut led2(LED1); 
 
float delay = 1.0; // 1 sec

Thread *p_thread=NULL;

void led2_thread(void const *args) {
    while (true) {
        led2 = !led2;
        Thread::wait(1000);
    }
}
 

int started=0;

void pressed()
{
   if(!started)
      {
         delay = 0.2; // 200 ms
           printf("\n\n+++ Create Thread! +++\n");
        started=1;   
  
       if(!( p_thread= new Thread(led2_thread)))
            printf("Something failed");
            
//        Thread thread(led2_thread);
        
       }      
   else
      {
        delay=1.0; 
           printf("\n\n--- Kill the Thread! ---\n");
 
        started=0;  
        
        delete (p_thread);
        p_thread=NULL;
       }    
    
}     
int main()
{
    mybutton.fall(&pressed);
    printf("\n\n*** RTOS third example ***\n");

    while (1) {
        myled = !myled;
        wait(delay);
    }
}

However even though apparently new does return a pointer (there is no message saying "smething failed") the LED does not blink, meaning the thread is not initiated.

Can someone help me with this?

EDIT: I added

 if((p_thread->get_state())==Thread::Inactive)
           printf("The thread is inactive\n");

and yes it seems that even though the thread is created, it is inactive. How can I make a thread active???

EDIT2: I found this excellent resource. (I also think that it should be incorporated into the Handbook) https://developer.mbed.org/questions/4632/Keeping-a-thread-object-alive-without-sp/

Steven Wilson made an excellent post there.

I continued experimenting with his post and I found This works

#include "mbed.h"
#include "rtos.h"
 
DigitalOut led1(LED1);
DigitalOut led2(PA_0);
 
void led2_thread(void const *args) 
{
    while (true) 
    {
        
        led2 = !led2;
        Thread::wait(1000);
    }
}
 
Thread *pThread=NULL;
 
void StartTheThread(void)
{
     
     pThread = new Thread(led2_thread); 

     printf("State: %d\n",pThread->get_state());
 //   Thread::wait(5000); //give the thread a chance to run
      printf("State: %d\n",pThread->get_state());
      
 printf("Bye Bye!\n");     
     
} 
int main() 
{
  StartTheThread(); 
   
    
    while (true) 
    {
        led1 = !led1;
        Thread::wait(500);
    }
}

As you see, calling the function StartTheThread starts the thread and this thread continues even after the function returns

However calling the function with interruptions

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

InterruptIn mybutton(USER_BUTTON); 
 
DigitalOut led1(LED1);
DigitalOut led2(PA_0);
 
void led2_thread(void const *args) 
{
    while (true) 
    {
        
        led2 = !led2;
        Thread::wait(1000);
    }
}
 
Thread *pThread=NULL;
 
void StartTheThread(void)
{
     
     pThread = new Thread(led2_thread); 

     printf("State: %d\n",pThread->get_state());
 //   Thread::wait(5000); //give the thread a chance to run
      printf("State: %d\n",pThread->get_state());
      
 printf("Bye Bye!\n");     
     
} 
int main() 
{
 //StartTheThread(); 
   
     mybutton.fall(&StartTheThread);   
    
    while (true) 
    {
        led1 = !led1;
        Thread::wait(500);
    }
}

makes the program fails. The thread is born dead - state 0-

Is there any way to activate the thread? Are interruptions incompatible with threads??

I will really really appreciate any answer.

Thanks

2 Answers

6 years, 6 months ago.

can some one please help me !!! I have a little confusion over how does thread works ....

my program is here:-

  1. include "mbed.h"
  2. include "rtos.h"
  3. include "C12832.h"

C12832 lcd(p5, p7, p6, p8, p11);

void lcd_thread(void const *args) { while(true) { lcd.cls(); lcd.locate(0,0); lcd.printf("Welcome to USA"); Thread::wait(1000);

} }

int main() { Thread thread(lcd_thread); while(true) { lcd.locate(0,20); lcd.printf("Hello"); Thread::wait(1000); } }

when i am running this i am getting absurd kind of out put in the LCD attached in my MBED KIT

Kindly help ...

6 years, 6 months ago.

Hi,

I suppose the lcd functions in lcd_thread and lcd functions in the main are causing lcd resource conflict. How about using "Semaphore" and call wait before start using lcd and release it after using it? For the details, please refer to https://docs.mbed.com/docs/vignesh/en/latest/api/classrtos_1_1Semaphore.html

moto

thnx for answering ...

i was trying using the threads to resolve the issue but it did not went right....is there anything else i can try over this if i want to stick in threads?

thanks

posted by Venkatesh Dixit 02 Oct 2017

Dont you need to start thread to make it running? Thread thread.start(lcd_thread); example

posted by Daniel Klioc 02 Oct 2017

Well, I tried myself with FRDM-KL25Z, but I could not make Semaphore work,
instead I used Mutex and it seems to be working.
But even with/without my program seems working so I can not tell if it will be any help for your case.
BTW, I don't think putting "lcd.cls()" in the while loop a good idea.
Following is my trial and since I don't have the lcd, I used my vt100 lib instead.

#include "mbed.h"
#include <Mutex.h>
#include "vt100.h"

#define USE_MUTX 1

vt100 *tty = 0 ;
Mutex *mutex = 0 ;

void lcd_thread(void const *args)
{
    int count = 0 ;
    
    while(true) {
#if USE_MUTEX
       mutex->lock(osWaitForever) ;
#endif
            tty->cls() ;
            tty->locate(0,0) ;
            printf("Welcome to Tokyo %d\n", count++) ;
#if USE_MUTEX
        mutex->unlock() ;
#endif
        Thread::wait(1000) ;
    }
}

// main() runs in its own thread in the OS
int main() {
    int count = 0 ;
    tty = new vt100() ;
    tty->cls() ;
    
    mutex = new Mutex(0) ; /* wait forever to get a semaphore */
    
    Thread thread(lcd_thread) ;
    
    while (true) {
#if USE_MUTEX
       mutex->lock(osWaitForever) ;
#endif
            tty->locate(0, 2) ;
            printf("Hello %d\n", count++) ;
#if USE_MUTEX
        mutex->unlock() ;
#endif
        Thread::wait(1000) ;    
    }
}

posted by Motoo Tanaka 02 Oct 2017

Hi, Venkatesh-san,

As you requested a sample which creates a race condition,
I tried one as below.

#include "mbed.h"
#include <Mutex.h>

DigitalOut led1(LED1, 1);

int use_mutex = 0 ;
Mutex *mutex = 0 ;

static int sub_thread_active = 0 ;
static int main_thread_active = 0 ;

int check_conflict(void)
{
    int result = 0 ;
    if (sub_thread_active && main_thread_active) {
        result = 1 ;
        led1 = 0 ; /* turn on led1 */
        printf("CONFLICT!\n") ;
    } else {
        result = 0 ;
        led1 = 1 ; /* turn off led1 */
    }
    return result ;
}

void sub_task(void)
{
    while(true) {
        if (use_mutex) { mutex->lock(osWaitForever) ; }
        
        sub_thread_active = 1 ; 
        check_conflict() ;       
        for (int i = 0 ; i < 40 ; i++) {
            putchar('-') ;
            Thread::wait(10) ;
        }
        putchar('\n') ;
        sub_thread_active = 0 ;
 
        if (use_mutex) { mutex->unlock() ; }
 
        Thread::wait(500) ;
    }
}

// main() runs in its own thread in the OS
int main() {
    char ans[32] ;
    
    printf("use mutex? > ") ; fflush(stdout) ;
    scanf("%s",ans) ;
    if ((ans[0] == 'y')||(ans[0] == 'Y')) {    
        use_mutex = 1 ;
        mutex = new Mutex(0) ; /* wait forever to get a mutex */
    }
 
    Thread thread(sub_task) ;
    
    while (true) {
        if (use_mutex) { mutex->lock(osWaitForever) ; }
        
        main_thread_active = 1 ;
        check_conflict() ;
        for (int i = 0 ; i < 30 ; i++) {
            putchar('+') ;
            Thread::wait(12) ;
        }
        putchar('\n') ;
        main_thread_active = 0 ;
        
        if (use_mutex) { mutex->unlock() ; }
        Thread::wait(1000) ;    
    }
}

moto

posted by Motoo Tanaka 03 Oct 2017