8 years, 2 months ago.

Issue sharing data between threads within classes with memory pool and queue

Hi, I'm new with mbed RTOS and I'm facing some issues whith threads and message queues.

I'd like to use the nucleo F401RE board like a gateway between an other device and a computer. I created two threads within separated classes, one is for getting data from uart 6, and the other is for sending them to the computer serial.

The two threads are running fine separately but, when I try to share data between them with one memory pool and queue, they're blocking each other and nothing more happens.

Is it about mutex or my code ? Please take a look. Thanks a lot !

global.h

#include "mbed.h"
#include "rtos.h"
#include <string>

// The structure used to store data
struct message_t
{
    uint32_t counter;  
    string data;
};

main.cpp

#include "global.h"
#include "uart_thread.h"
#include "pc_thread.h"

int main (void) 
{
    MemoryPool<message_t, 50> *mpool = new MemoryPool<message_t, 50>();
    Queue<message_t, 50> *queue = new Queue<message_t, 50>();
    
    Uart_Thread *thread_1 = new Uart_Thread(6, mpool, queue);
    Pc_Thread *thread_2 = new Pc_Thread(mpool, queue);
    
    thread_1->start_thread();
    thread_2->start_thread();

}

Uart_Thread.h

#include "mbed.h"
#include "rtos.h"
#include "cmsis_os.h"
#include <string>
#include "Thread.h"
#include "global.h"

using namespace std;
using namespace rtos;

class Uart_Thread
{
    public:
    Uart_Thread(int uart_number, MemoryPool<message_t, 50> *mpool, Queue<message_t, 50> *queue);
    void start_thread() { m_thread = new Thread( &Uart_Thread::uart_thread, this); }

    private:
    static void uart_thread(void const *args)
	{
		Uart_Thread *instance = (Uart_Thread*)args;
		instance->get_frame();
	}
	
    void get_frame();

    Serial* m_uart;
    Thread* m_thread;
    MemoryPool<message_t, 50> *m_mpool;
    Queue<message_t, 50> *m_queue;
};

Thread.cpp

#include "uart_thread.h"

Uart_Thread::Uart_Thread(int uart_number, MemoryPool<message_t, 50> *mpool, Queue<message_t, 50> *queue) : m_mpool(mpool), m_queue(queue)
{
    /* Uart init*/
}

void Uart_Thread::get_frame()
{
    while (true)
    {     
		// [...]
		// get complete frame from uart
		// then store it in string from struct
    
        message_t *message = m_mpool->alloc();
        message->data = (str + "\n");
        osStatus stat = m_queue->put(message);    
    }
}

Pc_Thread.h

#include "mbed.h"
#include "cmsis_os.h"
#include "rtos.h"
#include <string>
#include "Thread.h"
#include "global.h"

using namespace std;
using namespace rtos;

class Pc_Thread
{
    public:
    Pc_Thread(MemoryPool<message_t, 50> *mpool, Queue<message_t, 50> *queue);
    void start_thread() { m_thread = new Thread( &Pc_Thread::pc_thread, this); }
    
    private:
    static void pc_thread(void const *args)
	{
		Pc_Thread *instance = (Pc_Thread*)args;
		instance->send_frame();
	}
	
    void send_frame();
    
    Serial* m_pc;
    Thread* m_thread;
    MemoryPool<message_t, 50> *m_mpool;
    Queue<message_t, 50> *m_queue;
};

Pc_Thread.cpp

#include "pc_thread.h"

Pc_Thread::Pc_Thread(MemoryPool<message_t, 50> *mpool, Queue<message_t, 50> *queue) : m_mpool(mpool), m_queue(queue)
{
    /* Uart Pc init*/
}

void Pc_Thread::send_frame()
{
	// send data to pc uart from queue when data available
    while (true)
    {
        osEvent evt = m_queue->get();
        if (evt.status == osEventMessage) 
        {
            message_t *message = (message_t*)evt.value.p;
            m_pc->printf((char*) message->data.c_str());
            
            m_mpool->free(message);
        }
    }
}

Question relating to:

Be the first to answer this question.