Unable to call private SerialBase functions

Hello Tzu-Hsuan,

How can I get 123456 in a different thread?

The following should work:

#include "mbed.h"

#define BUFF_LEN    32
#define MSG_LEN     64
#define DATA_LEN    MSG_LEN - 2

BufferedSerial      serial(STDIO_UART_TX, STDIO_UART_RX);
Thread              thread1;
Thread              thread2;
EventQueue          eventQueue;
Mutex               mutex;
ConditionVariable   cond(mutex);
char                recvBuff[BUFF_LEN] = { 0 };
size_t              recvLen;
char                message[MSG_LEN] = { 0 };

// The following variable is protected by locking the mutex
char                data[DATA_LEN] = { 0 };

void taskPrintData()
{
    mutex.lock();

    while (1) {
        // Wait for a condition to change
        cond.wait();

        // Now it is safe to access data in this thread
        printf("Data received: %s\r\n", data);
        memset(data, 0, DATA_LEN);  // empty data to make space for new data
    }
}

void onSerialReceived(void)
{
    while (serial.readable()) {
        // Read serial
        recvLen = serial.read(recvBuff, BUFF_LEN);

        if ((strlen(message) + recvLen) > MSG_LEN) {
            // too much data -> something went wrong
            memset(message, 0, MSG_LEN);
            break;
        }

        strcat(message, recvBuff);          // append received chars to message

        if (message[0] != 's') {
            // garbage message received
            memset(message, 0, MSG_LEN);
            break;
        }

        if (message[strlen(message) - 1] == '#') {
            // message complete
            mutex.lock();

            // copy the chars from the message to the data storage
            strcat(data, &message[1]);      // omit first char (which is 's')
            data[strlen(data) - 1] = '\0';  // delete last char (which is '#')
            memset(message, 0, MSG_LEN);

            // Signal for other threads that data has been received
            cond.notify_all();
            mutex.unlock();
            break;
        }
    }
    memset(recvBuff, 0, BUFF_LEN);
}

void onSigio(void)
{
    eventQueue.call(onSerialReceived);
}

int main()
{
    printf("Starting..\r\n");
    thread1.start(taskPrintData);
    thread2.start(callback(&eventQueue, &EventQueue::dispatch_forever));
    serial.sigio(callback(onSigio));

    while (1) {
        ThisThread::sleep_for(10ms);
    }
}

Make sure you don’t append anything to the s123456# message (no new line or carriage return etc.).
For more info about ConditionVariable read here.

Why we can’t use “attach” in BufferedSerial instead of using “sigio”?

Because the mbed team designed the BufferedSerial that way (no attach function is available).

I am not sure the timing to choose BufferedSerial or UnbufferedSerial even I read the API.

Unlike the BufferedSerial class, the UnbufferedSerial class does not use intermediary buffers to store bytes to transmit to or read from the hardware. The user application is responsible for processing each byte as it is received. The method to read data returns only one byte for every call. Therefore, we recommend you use this class when you need more control and for use in interrupt handlers with the RTOS. You can also use this class to write multiple bytes at once. Because it does not acquire a mutex lock, you must ensure only one instance uses the serial port.

For normal blocking applications that require a serial channel for something other than the console, BufferedSerial performs better than UnbufferedSerial and causes less CPU load and fewer latency issues. Only applications that are short of RAM and cannot afford buffering or that need more control of the serial port and use it from IRQ should use UnbufferedSerial.

Best regards, Zoltan