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