From d2c912e10e08bdc5c0b5d023704db2872d218aa8 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Wed, 22 Sep 2021 12:16:36 +0200 Subject: [PATCH 1/3] Removing thread-safe Serial and thread-safe Wire since those will be handled by Arduino_ThreadsafeIO --- src/Arduino_Threads.h | 3 - src/Serial.cpp | 3 - src/SerialDispatcher.h | 199 ----------------------------------------- src/Wire.cpp | 11 --- src/Wire.h | 178 ------------------------------------ 5 files changed, 394 deletions(-) delete mode 100644 src/Serial.cpp delete mode 100644 src/SerialDispatcher.h delete mode 100644 src/Wire.cpp delete mode 100644 src/Wire.h diff --git a/src/Arduino_Threads.h b/src/Arduino_Threads.h index f176365..98f51d0 100644 --- a/src/Arduino_Threads.h +++ b/src/Arduino_Threads.h @@ -305,7 +305,4 @@ private: \ }; \ CONCAT(tabname,Class) tabname; -#include "Wire.h" -#include "SerialDispatcher.h" - #endif /* ARDUINO_THREADS_H_ */ diff --git a/src/Serial.cpp b/src/Serial.cpp deleted file mode 100644 index 9553c59..0000000 --- a/src/Serial.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "SerialDispatcher.h" - -SerialClassDispatcher Serial(SerialUSB); \ No newline at end of file diff --git a/src/SerialDispatcher.h b/src/SerialDispatcher.h deleted file mode 100644 index 43acedf..0000000 --- a/src/SerialDispatcher.h +++ /dev/null @@ -1,199 +0,0 @@ -#ifndef __SERIAL_DISPATCHER_H__ -#define __SERIAL_DISPATCHER_H__ - -#include "Arduino.h" -#undef Serial -#include "api/RingBuffer.h" - -struct _sinkBuffers { - osThreadId_t id; - bool reader; - bool raw; - rtos::Semaphore* sem; - RingBuffer rxBuffer; - RingBuffer txBuffer; -}; - -#define READ_READY_UNBLOCK (1 << 1) - -class SerialClassDispatcher : public HardwareSerial { - public: - SerialClassDispatcher(HardwareSerial& _serial) : serial(_serial) { - - } - void begin(unsigned long baudrate) { - if (!begun) { - serial.begin(baudrate); - begun = true; - printer.start(mbed::callback(this, &SerialClassDispatcher::timedPrint)); - } - sinkBuffers[users].id = rtos::ThisThread::get_id(); - sinkBuffers[users].sem = new rtos::Semaphore(1); - sinkBuffers[users].raw = false; - users++; - } - - void begin(unsigned long baudrate, uint16_t config) { - if (!begun) { - serial.begin(baudrate, config); - begun = true; - } - sinkBuffers[users].id = rtos::ThisThread::get_id(); - sinkBuffers[users].sem = new rtos::Semaphore(1); - sinkBuffers[users].raw = false; - users++; - } - - using Print::write; // pull in write(str) and write(buf, size) from Print - - operator bool() { - return serial; - } - - void tags(bool enable = true) { - print_tags = enable; - } - - void end() { - if (users == 0) { - serial.end(); - } else { - users--; - } - } - - size_t write(uint8_t data) { - findSemaphore(rtos::ThisThread::get_id())->acquire(); - findThreadTxBuffer(rtos::ThisThread::get_id()).store_char(data); - findSemaphore(rtos::ThisThread::get_id())->release(); - unlock_print.set(READ_READY_UNBLOCK); - } - - size_t write(const uint8_t* data, size_t len) { - findSemaphore(rtos::ThisThread::get_id())->acquire(); - for (int i=0; irelease(); - unlock_print.set(READ_READY_UNBLOCK); - } - - void flushReadBuffer() { - while (serial.available()) { - int c = serial.read(); - for (int i = 0; i < users; i++) { - if (sinkBuffers[i].reader) { - sinkBuffers[i].rxBuffer.store_char(c); - } - } - } - } - - int read() { - *isReader(rtos::ThisThread::get_id()) = true; - flushReadBuffer(); - return findThreadRxBuffer(rtos::ThisThread::get_id()).read_char(); - } - - int peek() { - *isReader(rtos::ThisThread::get_id()) = true; - flushReadBuffer(); - return findThreadRxBuffer(rtos::ThisThread::get_id()).peek(); - } - - void raw(bool _raw = true) { - *isRaw(rtos::ThisThread::get_id()) = _raw; - } - - void flush() { - serial.flush(); - } - - int available() { - *isReader(rtos::ThisThread::get_id()) = true; - flushReadBuffer(); - return findThreadRxBuffer(rtos::ThisThread::get_id()).available(); - } - - private: - - void timedPrint() { - while (1) { - unlock_print.wait_any(READ_READY_UNBLOCK, osWaitForever, true); - for (int i = 0; i < users; i++) { - sinkBuffers[i].sem->acquire(); - // Implementation "leak", should be changed at RingBuffer API level - int c = sinkBuffers[i].txBuffer._iHead == 0 ? - sinkBuffers[i].txBuffer._aucBuffer[sizeof(sinkBuffers[i].txBuffer._aucBuffer) -1] : - sinkBuffers[i].txBuffer._aucBuffer[sinkBuffers[i].txBuffer._iHead - 1]; - if ((!sinkBuffers[i].raw && (c == '\n' /*|| c == '\r' */|| c == '\0')) || - sinkBuffers[i].raw || !sinkBuffers[i].txBuffer.availableForStore()) { - if (sinkBuffers[i].txBuffer.available() && print_tags) { - serial.print("["); - serial.print(i); - serial.print("] "); - } - while (sinkBuffers[i].txBuffer.available()) { - serial.write(sinkBuffers[i].txBuffer.read_char()); - } - } - sinkBuffers[i].sem->release(); - } - } - } - - bool* isReader(osThreadId_t id) { - for (int i = 0; i < 10; i++) { - if (id == sinkBuffers[i].id) { - return &sinkBuffers[i].reader; - } - } - } - - bool* isRaw(osThreadId_t id) { - for (int i = 0; i < 10; i++) { - if (id == sinkBuffers[i].id) { - return &sinkBuffers[i].raw; - } - } - } - - rtos::Semaphore* findSemaphore(osThreadId_t id) { - for (int i = 0; i < 10; i++) { - if (id == sinkBuffers[i].id) { - return sinkBuffers[i].sem; - } - } - } - - RingBuffer& findThreadTxBuffer(osThreadId_t id) { - for (int i = 0; i < 10; i++) { - if (id == sinkBuffers[i].id) { - return sinkBuffers[i].txBuffer; - } - } - } - - RingBuffer& findThreadRxBuffer(osThreadId_t id) { - for (int i = 0; i < 10; i++) { - if (id == sinkBuffers[i].id) { - return sinkBuffers[i].rxBuffer; - } - } - } - - private: - HardwareSerial& serial; - int users = 0; - bool begun = false; - int currentClock = 400000; - struct _sinkBuffers sinkBuffers[10]; - osThreadId_t currentThread; - rtos::Thread printer; - rtos::EventFlags unlock_print; - bool print_tags = false; -}; - -extern SerialClassDispatcher Serial; - -#endif \ No newline at end of file diff --git a/src/Wire.cpp b/src/Wire.cpp deleted file mode 100644 index aed2f05..0000000 --- a/src/Wire.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "Wire.h" -#define Wire WireReal -#define Wire1 WireReal1 -#include "../Wire/Wire.cpp" -#undef Wire -#undef Wire1 - -WireClassDispatcher Wire(WireReal); -WireClassDispatcher Wire1(WireReal1); -//WireClassDispatcher Wire(WireReal); -//WireClassDispatcher Wire1(Wire1Real); \ No newline at end of file diff --git a/src/Wire.h b/src/Wire.h deleted file mode 100644 index 2827d64..0000000 --- a/src/Wire.h +++ /dev/null @@ -1,178 +0,0 @@ -#ifndef __WIRE_WRAPPER_H__ -#define __WIRE_WRAPPER_H__ - -#include "Portenta_System.h" // just a trick to allow including the real Wire.h -#define Wire WireReal -#define Wire1 WireReal1 -#include "../Wire/Wire.h" -#undef Wire -#undef Wire1 -#include "api/RingBuffer.h" - -struct requiredClocks { - osThreadId_t id; - int clock; - RingBuffer rxBuffer; - bool transaction; -}; - -class WireClassDispatcher : public HardwareI2C { - public: - WireClassDispatcher(HardwareI2C& _wire) : wire(_wire) { - sem = new rtos::Semaphore(1); - } - void begin() { - sem->acquire(); - if (!begun) { - wire.begin(); - begun = true; - } - idClock[users].id = rtos::ThisThread::get_id(); - idClock[users].clock = currentClock; - users++; - sem->release(); - } - void begin(uint8_t) { - /*doNothing*/ - } - void onReceive(void (*)(int)) { - /*doNothing*/ - } - void onRequest(void (*)()) { - /*doNothing*/ - } - - void end() { - if (users == 0) { - wire.end(); - } else { - users--; - } - } - - void setClock(uint32_t freq) { - // must be called on a per-thread basis - if (freq != currentClock) { - wire.setClock(freq); - currentClock = freq; - *findThreadClock(rtos::ThisThread::get_id()) = currentClock; - } - } - - void beginTransmission(uint8_t address) { - //lock to caller thread until endTransmission(true) is called - sem->acquire(); - int freq = *findThreadClock(rtos::ThisThread::get_id()); - if (freq != currentClock) { - setClock(freq); - } - currentThread = rtos::ThisThread::get_id(); - wire.beginTransmission(address); - } - - uint8_t endTransmission(bool stopBit) { - uint8_t res = wire.endTransmission(stopBit); - if (stopBit) { - sem->release(); - *transactionInProgress(rtos::ThisThread::get_id()) = false; - } else { - *transactionInProgress(rtos::ThisThread::get_id()) = true; - } - return res; - } - - uint8_t endTransmission(void) { - return endTransmission(true); - } - - size_t requestFrom(uint8_t address, size_t len, bool stopBit) { - if (!*transactionInProgress(rtos::ThisThread::get_id())) { - sem->acquire(); - } - uint8_t ret = wire.requestFrom(address, len, stopBit); - if (ret > 0) { - while (wire.available()) { - findThreadRxBuffer(rtos::ThisThread::get_id()).store_char(wire.read()); - } - } - if (stopBit) { - *transactionInProgress(rtos::ThisThread::get_id()) = false; - sem->release(); - } else { - *transactionInProgress(rtos::ThisThread::get_id()) = true; - } - return ret; - } - - size_t requestFrom(uint8_t address, size_t len) { - return requestFrom(address, len, true); - } - - size_t write(uint8_t data) { - if (currentThread != rtos::ThisThread::get_id()) { - return 0; - } - return wire.write(data); - } - - size_t write(const uint8_t* data, int len) { - if (currentThread != rtos::ThisThread::get_id()) { - return 0; - } - return wire.write(data, len); - } - - int read() { - return findThreadRxBuffer(rtos::ThisThread::get_id()).read_char(); - } - - int peek() { - return findThreadRxBuffer(rtos::ThisThread::get_id()).peek(); - } - - void flush() { - } - - int available() { - return findThreadRxBuffer(rtos::ThisThread::get_id()).available(); - } - - private: - int* findThreadClock(osThreadId_t id) { - for (int i = 0; i < 10; i++) { - if (id == idClock[i].id) { - return &idClock[i].clock; - } - } - } - bool* transactionInProgress(osThreadId_t id) { - for (int i = 0; i < 10; i++) { - if (id == idClock[i].id) { - return &idClock[i].transaction; - } - } - } - RingBuffer& findThreadRxBuffer(osThreadId_t id) { - for (int i = 0; i < 10; i++) { - if (id == idClock[i].id) { - return idClock[i].rxBuffer; - } - } - } - - private: - HardwareI2C& wire; - int users = 0; - bool begun = false; - rtos::Semaphore* sem; - int currentClock = 400000; - struct requiredClocks idClock[10]; - osThreadId_t currentThread; -}; - -extern WireClassDispatcher Wire; -extern WireClassDispatcher Wire1; - -#define TwoWire WireClassDispatcher - -#endif \ No newline at end of file From cebb167fc4e3470f6c597918881e2ffc4f3dd009 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 23 Sep 2021 07:31:01 +0200 Subject: [PATCH 2/3] Fix CI: Add missing include --- src/Arduino_Threads.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Arduino_Threads.h b/src/Arduino_Threads.h index 98f51d0..2684e3e 100644 --- a/src/Arduino_Threads.h +++ b/src/Arduino_Threads.h @@ -1,6 +1,7 @@ #ifndef ARDUINO_THREADS_H_ #define ARDUINO_THREADS_H_ +#include #include #define SOURCE(name, type) \ From 67d38f54f58753d04049718ff8cbd566a10991fb Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 23 Sep 2021 10:16:04 +0200 Subject: [PATCH 3/3] Adding missing header --- src/Arduino_Threads.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Arduino_Threads.h b/src/Arduino_Threads.h index 2684e3e..7d45abc 100644 --- a/src/Arduino_Threads.h +++ b/src/Arduino_Threads.h @@ -1,6 +1,7 @@ #ifndef ARDUINO_THREADS_H_ #define ARDUINO_THREADS_H_ +#include #include #include