diff --git a/shared/emulator.hpp b/shared/emulator.hpp index 2be7cb6..9ac682e 100644 --- a/shared/emulator.hpp +++ b/shared/emulator.hpp @@ -227,6 +227,8 @@ friend class ArduinoSimulationController; logtime_t mPinWriteDelay; logtime_t mPinSetModeDelay; + std::deque mSerialData; + void reset() { mCurrentTime = 0; @@ -616,6 +618,50 @@ friend class ArduinoSimulationController; { return mEnableSerial; } + + /** + * Enqueue additional serial data to be read by the emulated code. + */ + void addSerialData(const std::string& str) + { + for (char c : str) { + mSerialData.push_back(c); + } + } + + /** + * Return number of bytes enqueued in serial buffer. + */ + std::size_t serialDataAvailable() const + { + return mSerialData.size(); + } + + /** + * Return the next byte (char) to be read from the serial buffer. + */ + char peekSerial() const + { + if (mSerialData.empty()) { + return '\0'; + } + + return mSerialData.front(); + } + + /** + * Return and pop one char from the serial data buffer. + */ + char readSerial() + { + if (mSerialData.empty()) { + return '\0'; + } + + char res = mSerialData.front(); + mSerialData.pop_front(); + return res; + } }; #endif diff --git a/shared/interface.cpp b/shared/interface.cpp index e488a89..dc04fca 100644 --- a/shared/interface.cpp +++ b/shared/interface.cpp @@ -268,4 +268,48 @@ void SerialMock::println(const char* val) } } +std::size_t SerialMock::available() const +{ + if (!emulator.isSerialEnabled()) { + throw ArduinoEmulatorException("The Serial interface is disabled in the emulator."); + } + return emulator.serialDataAvailable(); +} + +int SerialMock::peek() const +{ + if (!emulator.isSerialEnabled()) { + throw ArduinoEmulatorException("The Serial interface is disabled in the emulator."); + } + if (emulator.serialDataAvailable() == 0) { + return -1; + } + return emulator.peekSerial(); +} + +int SerialMock::read() +{ + if (!emulator.isSerialEnabled()) { + throw ArduinoEmulatorException("The Serial interface is disabled in the emulator."); + } + if (emulator.serialDataAvailable() == 0) { + return -1; + } + return emulator.readSerial(); + +} + +std::size_t SerialMock::readBytes(char* buffer, std::size_t length) +{ + if (!emulator.isSerialEnabled()) { + throw ArduinoEmulatorException("The Serial interface is disabled in the emulator."); + } + length = std::min(length, emulator.serialDataAvailable()); + for (std::size_t i = 0; i < length; ++i) { + buffer[i] = emulator.readSerial(); + } + return length; +} + + SerialMock Serial; diff --git a/shared/interface.hpp b/shared/interface.hpp index d14ec8c..a062b77 100644 --- a/shared/interface.hpp +++ b/shared/interface.hpp @@ -194,6 +194,7 @@ enum SerialPrintFormat { HEX, }; +// A subset of Serial class class SerialMock { public: @@ -221,6 +222,11 @@ class SerialMock void println(unsigned long long val, SerialPrintFormat format = DEC); void println(double val); void println(const char* val); + + std::size_t available() const; + int peek() const; + int read(); + std::size_t readBytes(char* buffer, std::size_t length); }; extern SerialMock Serial;