From 1541cbc829a599873ba7092994bbacd467ee43f3 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Tue, 19 Oct 2021 06:23:13 +0200 Subject: [PATCH 1/5] The user can't be bothered with the cumbersome #ifdef logic, rather directly instead the SerialDispatcher within the library and make it available via extern declaration. --- src/io/serial/SerialDispatcher.cpp | 16 ++++++++++++++++ src/io/serial/SerialDispatcher.h | 7 +++++++ 2 files changed, 23 insertions(+) diff --git a/src/io/serial/SerialDispatcher.cpp b/src/io/serial/SerialDispatcher.cpp index 7fb6dea..cc7a41b 100644 --- a/src/io/serial/SerialDispatcher.cpp +++ b/src/io/serial/SerialDispatcher.cpp @@ -332,3 +332,19 @@ void SerialDispatcher::handleSerialReader() }); } } + +/************************************************************************************** + * INCLUDE + **************************************************************************************/ + +#include + +/************************************************************************************** + * GLOBAL VARIABLE DECLARATION + **************************************************************************************/ + +#ifdef ARDUINO_PORTENTA_H7_M4 + SerialDispatcher Serial(Serial1); /* No SerialUSB for Portenta H7 / M4 Core */ +#else + SerialDispatcher Serial(SerialUSB); +#endif diff --git a/src/io/serial/SerialDispatcher.h b/src/io/serial/SerialDispatcher.h index ca17793..0072f87 100644 --- a/src/io/serial/SerialDispatcher.h +++ b/src/io/serial/SerialDispatcher.h @@ -102,4 +102,11 @@ class SerialDispatcher : public arduino::HardwareSerial void handleSerialReader(); }; +/************************************************************************************** + * EXTERN DECLARATION + **************************************************************************************/ + +#undef Serial +extern SerialDispatcher Serial; + #endif /* SERIAL_DISPATCHER_H_ */ From 07d98380c92c0a3b8addf814e2a0ec5bcdabcc0f Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Tue, 19 Oct 2021 06:24:36 +0200 Subject: [PATCH 2/5] Use Arduino_Threads for Threadsafe_Serial_Write. --- .../SharedVariables.h | 0 .../Threadsafe_Serial_Writer/Thread_1.inot | 14 ++++ .../Threadsafe_Serial_Writer/Thread_2.inot | 14 ++++ .../Threadsafe_Serial_Writer/Thread_3.inot | 14 ++++ .../Threadsafe_Serial_Writer.ino | 75 +++++-------------- 5 files changed, 60 insertions(+), 57 deletions(-) create mode 100644 examples/Threadsafe_IO/Threadsafe_Serial_Writer/SharedVariables.h create mode 100644 examples/Threadsafe_IO/Threadsafe_Serial_Writer/Thread_1.inot create mode 100644 examples/Threadsafe_IO/Threadsafe_Serial_Writer/Thread_2.inot create mode 100644 examples/Threadsafe_IO/Threadsafe_Serial_Writer/Thread_3.inot diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_Writer/SharedVariables.h b/examples/Threadsafe_IO/Threadsafe_Serial_Writer/SharedVariables.h new file mode 100644 index 0000000..e69de29 diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_Writer/Thread_1.inot b/examples/Threadsafe_IO/Threadsafe_Serial_Writer/Thread_1.inot new file mode 100644 index 0000000..71039e4 --- /dev/null +++ b/examples/Threadsafe_IO/Threadsafe_Serial_Writer/Thread_1.inot @@ -0,0 +1,14 @@ +void setup() +{ + Serial.begin(9600); +} + +void loop() +{ + Serial.block(); + Serial.print("["); + Serial.print(millis()); + Serial.print("] Thread #1: Lorem ipsum ..."); + Serial.println(); + Serial.unblock(); +} diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_Writer/Thread_2.inot b/examples/Threadsafe_IO/Threadsafe_Serial_Writer/Thread_2.inot new file mode 100644 index 0000000..d02c9cd --- /dev/null +++ b/examples/Threadsafe_IO/Threadsafe_Serial_Writer/Thread_2.inot @@ -0,0 +1,14 @@ +void setup() +{ + Serial.begin(9600); +} + +void loop() +{ + Serial.block(); + Serial.print("["); + Serial.print(millis()); + Serial.print("] Thread #2: Lorem ipsum ..."); + Serial.println(); + Serial.unblock(); +} diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_Writer/Thread_3.inot b/examples/Threadsafe_IO/Threadsafe_Serial_Writer/Thread_3.inot new file mode 100644 index 0000000..4591cf0 --- /dev/null +++ b/examples/Threadsafe_IO/Threadsafe_Serial_Writer/Thread_3.inot @@ -0,0 +1,14 @@ +void setup() +{ + Serial.begin(9600); +} + +void loop() +{ + Serial.block(); + Serial.print("["); + Serial.print(millis()); + Serial.print("] Thread #3: Lorem ipsum ..."); + Serial.println(); + Serial.unblock(); +} diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_Writer/Threadsafe_Serial_Writer.ino b/examples/Threadsafe_IO/Threadsafe_Serial_Writer/Threadsafe_Serial_Writer.ino index f5b47c2..050f438 100644 --- a/examples/Threadsafe_IO/Threadsafe_Serial_Writer/Threadsafe_Serial_Writer.ino +++ b/examples/Threadsafe_IO/Threadsafe_Serial_Writer/Threadsafe_Serial_Writer.ino @@ -4,71 +4,32 @@ #include -/************************************************************************************** - * CONSTANTS - **************************************************************************************/ - -static size_t constexpr NUM_THREADS = 5; - -/************************************************************************************** - * FUNCTION DECLARATION - **************************************************************************************/ - -void serial_thread_func(); - -/************************************************************************************** - * GLOBAL VARIABLES - **************************************************************************************/ - -static char thread_name[NUM_THREADS][32]; -#undef Serial -#ifdef ARDUINO_PORTENTA_H7_M4 - SerialDispatcher Serial(Serial1); /* No SerialUSB for Portenta H7 / M4 Core */ -#else - SerialDispatcher Serial(SerialUSB); -#endif - /************************************************************************************** * SETUP/LOOP **************************************************************************************/ void setup() { - /* Fire up some threads all accessing the LSM6DSOX */ - for(size_t i = 0; i < NUM_THREADS; i++) - { - snprintf(thread_name[i], sizeof(thread_name[i]), "Thread #%02d", i); - rtos::Thread * t = new rtos::Thread(osPriorityNormal, OS_STACK_SIZE, nullptr, thread_name[i]); - t->start(serial_thread_func); - } -} - -void loop() -{ + Serial.begin(9600); + while (!Serial) { } + Thread_1.start(); + Thread_2.start(); + Thread_3.start(); } -/************************************************************************************** - * FUNCTION DEFINITION - **************************************************************************************/ - -void serial_thread_func() +void loop() { - Serial.begin(9600); - - for(;;) - { - /* Sleep between 5 and 500 ms */ - rtos::ThisThread::sleep_for(rtos::Kernel::Clock::duration_u32(random(5,500))); - /* Print thread id and chip id value to serial. */ - char msg[64] = {0}; - snprintf(msg, sizeof(msg), "[%05lu] %s: Lorem ipsum ...", millis(), rtos::ThisThread::get_name()); - /* Every Serial.print/println() encapsulated between - * block/unblock statements will only be printed after - * a block statement has occurred. - */ - Serial.block(); - Serial.println(msg); - Serial.unblock(); - } + Serial.block(); + Serial.print("["); + Serial.print(millis()); + Serial.print("] Thread #0: Lorem ipsum ..."); + Serial.println(); + Serial.unblock(); + + /* If we don't hand back control then the main thread + * will hog the CPU and all other thread's won't get + * time to be executed. + */ + rtos::ThisThread::yield(); } From 01c27b091c38f46d16013a308a3493b84d2692c3 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Tue, 19 Oct 2021 06:39:40 +0200 Subject: [PATCH 3/5] Use Arduino_Threads for Threadsafe_Serial_Reader. --- .../SharedVariables.h | 0 .../Threadsafe_Serial_Reader/Thread_1.inot | 28 ++++++ .../Threadsafe_Serial_Reader/Thread_2.inot | 28 ++++++ .../Threadsafe_Serial_Reader/Thread_3.inot | 28 ++++++ .../Threadsafe_Serial_Reader.ino | 86 ++++++------------- 5 files changed, 112 insertions(+), 58 deletions(-) create mode 100644 examples/Threadsafe_IO/Threadsafe_Serial_Reader/SharedVariables.h create mode 100644 examples/Threadsafe_IO/Threadsafe_Serial_Reader/Thread_1.inot create mode 100644 examples/Threadsafe_IO/Threadsafe_Serial_Reader/Thread_2.inot create mode 100644 examples/Threadsafe_IO/Threadsafe_Serial_Reader/Thread_3.inot diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_Reader/SharedVariables.h b/examples/Threadsafe_IO/Threadsafe_Serial_Reader/SharedVariables.h new file mode 100644 index 0000000..e69de29 diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_Reader/Thread_1.inot b/examples/Threadsafe_IO/Threadsafe_Serial_Reader/Thread_1.inot new file mode 100644 index 0000000..04e9bf5 --- /dev/null +++ b/examples/Threadsafe_IO/Threadsafe_Serial_Reader/Thread_1.inot @@ -0,0 +1,28 @@ +void setup() +{ + Serial.begin(9600); + + Serial.block(); + Serial.println("Thread #1 started."); + Serial.unblock(); +} + +void loop() +{ + /* Read data from the serial interface into a String. */ + String serial_msg; + while (Serial.available()) + serial_msg += (char)Serial.read(); + + /* Print thread id and chip id value to serial. */ + if (serial_msg.length()) + { + Serial.block(); + Serial.print("["); + Serial.print(millis()); + Serial.print("] Thread #1: "); + Serial.print(serial_msg); + Serial.println(); + Serial.unblock(); + } +} diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_Reader/Thread_2.inot b/examples/Threadsafe_IO/Threadsafe_Serial_Reader/Thread_2.inot new file mode 100644 index 0000000..e5940c2 --- /dev/null +++ b/examples/Threadsafe_IO/Threadsafe_Serial_Reader/Thread_2.inot @@ -0,0 +1,28 @@ +void setup() +{ + Serial.begin(9600); + + Serial.block(); + Serial.println("Thread #2 started."); + Serial.unblock(); +} + +void loop() +{ + /* Read data from the serial interface into a String. */ + String serial_msg; + while (Serial.available()) + serial_msg += (char)Serial.read(); + + /* Print thread id and chip id value to serial. */ + if (serial_msg.length()) + { + Serial.block(); + Serial.print("["); + Serial.print(millis()); + Serial.print("] Thread #2: "); + Serial.print(serial_msg); + Serial.println(); + Serial.unblock(); + } +} diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_Reader/Thread_3.inot b/examples/Threadsafe_IO/Threadsafe_Serial_Reader/Thread_3.inot new file mode 100644 index 0000000..3a21fa2 --- /dev/null +++ b/examples/Threadsafe_IO/Threadsafe_Serial_Reader/Thread_3.inot @@ -0,0 +1,28 @@ +void setup() +{ + Serial.begin(9600); + + Serial.block(); + Serial.println("Thread #3 started."); + Serial.unblock(); +} + +void loop() +{ + /* Read data from the serial interface into a String. */ + String serial_msg; + while (Serial.available()) + serial_msg += (char)Serial.read(); + + /* Print thread id and chip id value to serial. */ + if (serial_msg.length()) + { + Serial.block(); + Serial.print("["); + Serial.print(millis()); + Serial.print("] Thread #3: "); + Serial.print(serial_msg); + Serial.println(); + Serial.unblock(); + } +} diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_Reader/Threadsafe_Serial_Reader.ino b/examples/Threadsafe_IO/Threadsafe_Serial_Reader/Threadsafe_Serial_Reader.ino index 5fbf546..2ddc81d 100644 --- a/examples/Threadsafe_IO/Threadsafe_Serial_Reader/Threadsafe_Serial_Reader.ino +++ b/examples/Threadsafe_IO/Threadsafe_Serial_Reader/Threadsafe_Serial_Reader.ino @@ -4,76 +4,46 @@ #include -/************************************************************************************** - * CONSTANTS - **************************************************************************************/ - -static size_t constexpr NUM_THREADS = 5; - -/************************************************************************************** - * FUNCTION DECLARATION - **************************************************************************************/ - -void serial_thread_func(); - -/************************************************************************************** - * GLOBAL VARIABLES - **************************************************************************************/ - -static char thread_name[NUM_THREADS][32]; -#undef Serial -#ifdef ARDUINO_PORTENTA_H7_M4 - SerialDispatcher Serial(Serial1); /* No SerialUSB for Portenta H7 / M4 Core */ -#else - SerialDispatcher Serial(SerialUSB); -#endif - /************************************************************************************** * SETUP/LOOP **************************************************************************************/ void setup() { - /* Fire up some threads all accessing the LSM6DSOX */ - for(size_t i = 0; i < NUM_THREADS; i++) - { - snprintf(thread_name[i], sizeof(thread_name[i]), "Thread #%02d", i); - rtos::Thread * t = new rtos::Thread(osPriorityNormal, OS_STACK_SIZE, nullptr, thread_name[i]); - t->start(serial_thread_func); - } -} + Serial.begin(9600); + while (!Serial) { } -void loop() -{ + Thread_1.start(); + Thread_2.start(); + Thread_3.start(); + Serial.block(); + Serial.println("Thread #0 started."); + Serial.unblock(); } -/************************************************************************************** - * FUNCTION DEFINITION - **************************************************************************************/ - -void serial_thread_func() +void loop() { - Serial.begin(9600); + /* Read data from the serial interface into a String. */ + String serial_msg; + while (Serial.available()) + serial_msg += (char)Serial.read(); - for(;;) + /* Print thread id and chip id value to serial. */ + if (serial_msg.length()) { - /* Sleep between 5 and 500 ms */ - rtos::ThisThread::sleep_for(rtos::Kernel::Clock::duration_u32(random(5,500))); - - /* Read data from the serial interface into a String. */ - String serial_msg; - while (Serial.available()) - serial_msg += (char)Serial.read(); - - /* Print thread id and chip id value to serial. */ - if (serial_msg.length()) - { - char msg[64] = {0}; - snprintf(msg, sizeof(msg), "[%05lu] %s: %s ...", millis(), rtos::ThisThread::get_name(), serial_msg.c_str()); - Serial.block(); - Serial.println(msg); - Serial.unblock(); - } + Serial.block(); + Serial.print("["); + Serial.print(millis()); + Serial.print("] Thread #0: "); + Serial.print(serial_msg); + Serial.println(); + Serial.unblock(); } + + /* If we don't hand back control then the main thread + * will hog the CPU and all other thread's won't get + * time to be executed. + */ + rtos::ThisThread::yield(); } From 70eaaf2ed55ab98f003ff35413e4d2eb1387f9ca Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Tue, 19 Oct 2021 08:36:12 +0200 Subject: [PATCH 4/5] Use Arduino_Threads for Threadsafe_Serial_GlobalPrefixSuffix. --- .../SharedVariables.h | 0 .../Thread_1.inot | 11 ++++ .../Thread_2.inot | 11 ++++ .../Thread_3.inot | 11 ++++ .../Threadsafe_Serial_GlobalPrefixSuffix.ino | 60 +++++-------------- 5 files changed, 48 insertions(+), 45 deletions(-) create mode 100644 examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/SharedVariables.h create mode 100644 examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Thread_1.inot create mode 100644 examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Thread_2.inot create mode 100644 examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Thread_3.inot diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/SharedVariables.h b/examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/SharedVariables.h new file mode 100644 index 0000000..e69de29 diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Thread_1.inot b/examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Thread_1.inot new file mode 100644 index 0000000..3de8ac9 --- /dev/null +++ b/examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Thread_1.inot @@ -0,0 +1,11 @@ +void setup() +{ + Serial.begin(9600); +} + +void loop() +{ + Serial.block(); + Serial.println("Thread #1: Lorem ipsum ..."); + Serial.unblock(); +} diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Thread_2.inot b/examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Thread_2.inot new file mode 100644 index 0000000..12731f0 --- /dev/null +++ b/examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Thread_2.inot @@ -0,0 +1,11 @@ +void setup() +{ + Serial.begin(9600); +} + +void loop() +{ + Serial.block(); + Serial.println("Thread #2: Lorem ipsum ..."); + Serial.unblock(); +} diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Thread_3.inot b/examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Thread_3.inot new file mode 100644 index 0000000..eccc6e8 --- /dev/null +++ b/examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Thread_3.inot @@ -0,0 +1,11 @@ +void setup() +{ + Serial.begin(9600); +} + +void loop() +{ + Serial.block(); + Serial.println("Thread #3: Lorem ipsum ..."); + Serial.unblock(); +} diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Threadsafe_Serial_GlobalPrefixSuffix.ino b/examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Threadsafe_Serial_GlobalPrefixSuffix.ino index 94ac3bd..12e302a 100644 --- a/examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Threadsafe_Serial_GlobalPrefixSuffix.ino +++ b/examples/Threadsafe_IO/Threadsafe_Serial_GlobalPrefixSuffix/Threadsafe_Serial_GlobalPrefixSuffix.ino @@ -3,32 +3,12 @@ **************************************************************************************/ #include - -/************************************************************************************** - * CONSTANTS - **************************************************************************************/ - -static size_t constexpr NUM_THREADS = 5; - /************************************************************************************** * FUNCTION DECLARATION **************************************************************************************/ String serial_log_message_prefix(String const & /* msg */); String serial_log_message_suffix(String const & prefix, String const & msg); -void serial_thread_func(); - -/************************************************************************************** - * GLOBAL VARIABLES - **************************************************************************************/ - -static char thread_name[NUM_THREADS][32]; -#undef Serial -#ifdef ARDUINO_PORTENTA_H7_M4 - SerialDispatcher Serial(Serial1); /* No SerialUSB for Portenta H7 / M4 Core */ -#else - SerialDispatcher Serial(SerialUSB); -#endif /************************************************************************************** * SETUP/LOOP @@ -36,21 +16,28 @@ static char thread_name[NUM_THREADS][32]; void setup() { + Serial.begin(9600); + while (!Serial) { } + Serial.global_prefix(serial_log_message_prefix); Serial.global_suffix(serial_log_message_suffix); - /* Fire up some threads all accessing the LSM6DSOX */ - for(size_t i = 0; i < NUM_THREADS; i++) - { - snprintf(thread_name[i], sizeof(thread_name[i]), "Thread #%02d", i); - rtos::Thread * t = new rtos::Thread(osPriorityNormal, OS_STACK_SIZE, nullptr, thread_name[i]); - t->start(serial_thread_func); - } + Thread_1.start(); + Thread_2.start(); + Thread_3.start(); } void loop() { - + Serial.block(); + Serial.println("Thread #0: Lorem ipsum ..."); + Serial.unblock(); + + /* If we don't hand back control then the main thread + * will hog the CPU and all other thread's won't get + * time to be executed. + */ + rtos::ThisThread::yield(); } /************************************************************************************** @@ -68,20 +55,3 @@ String serial_log_message_suffix(String const & prefix, String const & msg) { return String("\r\n"); } - -void serial_thread_func() -{ - Serial.begin(9600); - - for(;;) - { - /* Sleep between 5 and 500 ms */ - rtos::ThisThread::sleep_for(rtos::Kernel::Clock::duration_u32(random(5,500))); - /* Print a unbroken log message including thread name and timestamp as a prefix. */ - Serial.block(); - Serial.print(rtos::ThisThread::get_name()); - Serial.print(": "); - Serial.print("Lorem ipsum ..."); - Serial.unblock(); - } -} From b6ce5377b9c7377cb94b57e79a3b7e3983ae8023 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Tue, 19 Oct 2021 09:03:21 +0200 Subject: [PATCH 5/5] Use Arduino_Threads for Threadsafe_Serial_ProtocolWrapping. --- .../GPS_Thread.inot | 64 +++++++++++ .../SharedVariables.h | 0 .../Threadsafe_Serial_ProtocolWrapping.ino | 100 ++---------------- 3 files changed, 72 insertions(+), 92 deletions(-) create mode 100644 examples/Threadsafe_IO/Threadsafe_Serial_ProtocolWrapping/GPS_Thread.inot create mode 100644 examples/Threadsafe_IO/Threadsafe_Serial_ProtocolWrapping/SharedVariables.h diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_ProtocolWrapping/GPS_Thread.inot b/examples/Threadsafe_IO/Threadsafe_Serial_ProtocolWrapping/GPS_Thread.inot new file mode 100644 index 0000000..85a99a5 --- /dev/null +++ b/examples/Threadsafe_IO/Threadsafe_Serial_ProtocolWrapping/GPS_Thread.inot @@ -0,0 +1,64 @@ +/************************************************************************************** + * FUNCTION DEFINITION + **************************************************************************************/ + +static String nmea_message_prefix(String const & /* msg */) +{ + return String("$"); +} + +static String nmea_message_suffix(String const & prefix, String const & msg) +{ + /* NMEA checksum is calculated over the complete message + * starting with '$' and ending with the end of the message. + */ + byte checksum = 0; + std::for_each(msg.c_str(), + msg.c_str() + msg.length(), + [&checksum](char const c) + { + checksum ^= static_cast(c); + }); + /* Assemble the footer of the NMEA message. */ + char footer[16] = {0}; + snprintf(footer, sizeof(footer), "*%02X\r\n", checksum); + return String(footer); +} + +/************************************************************************************** + * SETUP/LOOP + **************************************************************************************/ + +void setup() +{ + Serial.begin(9600); + + Serial.prefix(nmea_message_prefix); + Serial.suffix(nmea_message_suffix); +} + +void loop() +{ + /* Sleep between 5 and 500 ms */ + rtos::ThisThread::sleep_for(rtos::Kernel::Clock::duration_u32(random(5,500))); + + /* Print a fake NMEA GPRMC message: + * $GPRMC,062101.714,A,5001.869,N,01912.114,E,955535.7,116.2,290520,000.0,W*45\r\n + */ + Serial.block(); + + Serial.print("GPRMC,"); + Serial.print(millis()); + Serial.print(",A,"); + Serial.print("5001.869,"); + Serial.print("N,"); + Serial.print("01912.114,"); + Serial.print("E,"); + Serial.print("955535.7,"); + Serial.print("116.2,"); + Serial.print("290520,"); + Serial.print("000.0,"); + Serial.print("W"); + + Serial.unblock(); +} diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_ProtocolWrapping/SharedVariables.h b/examples/Threadsafe_IO/Threadsafe_Serial_ProtocolWrapping/SharedVariables.h new file mode 100644 index 0000000..e69de29 diff --git a/examples/Threadsafe_IO/Threadsafe_Serial_ProtocolWrapping/Threadsafe_Serial_ProtocolWrapping.ino b/examples/Threadsafe_IO/Threadsafe_Serial_ProtocolWrapping/Threadsafe_Serial_ProtocolWrapping.ino index af200e8..090ba04 100644 --- a/examples/Threadsafe_IO/Threadsafe_Serial_ProtocolWrapping/Threadsafe_Serial_ProtocolWrapping.ino +++ b/examples/Threadsafe_IO/Threadsafe_Serial_ProtocolWrapping/Threadsafe_Serial_ProtocolWrapping.ino @@ -4,107 +4,23 @@ #include -/************************************************************************************** - * CONSTANTS - **************************************************************************************/ - -static size_t constexpr NUM_THREADS = 5; - -/************************************************************************************** - * FUNCTION DECLARATION - **************************************************************************************/ - -void serial_thread_func(); - -/************************************************************************************** - * GLOBAL VARIABLES - **************************************************************************************/ - -static char thread_name[NUM_THREADS][32]; -#undef Serial -#ifdef ARDUINO_PORTENTA_H7_M4 - SerialDispatcher Serial(Serial1); /* No SerialUSB for Portenta H7 / M4 Core */ -#else - SerialDispatcher Serial(SerialUSB); -#endif - /************************************************************************************** * SETUP/LOOP **************************************************************************************/ void setup() { - /* Fire up some threads all accessing the LSM6DSOX */ - for(size_t i = 0; i < NUM_THREADS; i++) - { - snprintf(thread_name[i], sizeof(thread_name[i]), "Thread #%02d", i); - rtos::Thread * t = new rtos::Thread(osPriorityNormal, OS_STACK_SIZE, nullptr, thread_name[i]); - t->start(serial_thread_func); - } -} - -void loop() -{ - -} - -/************************************************************************************** - * FUNCTION DEFINITION - **************************************************************************************/ + Serial.begin(9600); + while (!Serial) { } -String nmea_message_prefix(String const & /* msg */) -{ - return String("$"); + GPS_Thread.start(); } -String nmea_message_suffix(String const & prefix, String const & msg) +void loop() { - /* NMEA checksum is calculated over the complete message - * starting with '$' and ending with the end of the message. + /* If we don't hand back control then the main thread + * will hog the CPU and all other thread's won't get + * time to be executed. */ - byte checksum = 0; - std::for_each(msg.c_str(), - msg.c_str() + msg.length(), - [&checksum](char const c) - { - checksum ^= static_cast(c); - }); - /* Assemble the footer of the NMEA message. */ - char footer[16] = {0}; - snprintf(footer, sizeof(footer), "*%02X\r\n", checksum); - return String(footer); -} - -void serial_thread_func() -{ - Serial.begin(9600); - - Serial.prefix(nmea_message_prefix); - Serial.suffix(nmea_message_suffix); - - for(;;) - { - /* Sleep between 5 and 500 ms */ - rtos::ThisThread::sleep_for(rtos::Kernel::Clock::duration_u32(random(5,500))); - - /* Print a fake NMEA GPRMC message: - * $GPRMC,062101.714,A,5001.869,N,01912.114,E,955535.7,116.2,290520,000.0,W*45\r\n - */ - Serial.block(); - - Serial.print("GPRMC,"); - Serial.print(millis()); - Serial.print(",A,"); - Serial.print("5001.869,"); - Serial.print("N,"); - Serial.print("01912.114,"); - Serial.print("E,"); - Serial.print("955535.7,"); - Serial.print("116.2,"); - Serial.print("290520,"); - Serial.print("000.0,"); - Serial.print("W"); - - Serial.unblock(); - } + rtos::ThisThread::yield(); }