diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8fb29c1..15b303d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,4 +111,42 @@ jobs: - name: Print doxygen warnings if: ${{ failure() }} - run: cat ./doc/doxygen/doxygen_warnings.txt \ No newline at end of file + run: cat ./doc/doxygen/doxygen_warnings.txt + + # Build examples + build: + # The type of runner that the job will run on. + runs-on: ubuntu-latest + needs: intro + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Cache pip + uses: actions/cache@v3 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Cache PlatformIO + uses: actions/cache@v3 + with: + path: ~/.platformio + key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }} + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.9' + + - name: Install PlatformIO + run: | + python -m pip install --upgrade pip + pip install --upgrade platformio + + - name: Run tests on native environment + run: platformio ci examples\cpp\* --lib . -c platformio.ini -e esp32dev \ No newline at end of file diff --git a/examples/cpp/SerialMuxChannels.h b/examples/cpp/SerialMuxChannels.h new file mode 100644 index 0000000..7b1d216 --- /dev/null +++ b/examples/cpp/SerialMuxChannels.h @@ -0,0 +1,83 @@ +/* MIT License + * + * Copyright (c) 2023 Gabryel Reyes + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/******************************************************************************* + DESCRIPTION +*******************************************************************************/ +/** + * @brief Channel structure definition for the SerialMuxProt. + * @author Gabryel Reyes + */ +#ifndef SERIAL_MUX_CHANNELS_H +#define SERIAL_MUX_CHANNELS_H + +/****************************************************************************** + * Compile Switches + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ + +#include + +/****************************************************************************** + * Macros + *****************************************************************************/ + +/** Maximum number of SerialMuxProt Channels. */ +#define MAX_CHANNELS (2U) + +/** Name of Channel to send Timestamp to. */ +#define TIMESTAMP_CHANNEL_NAME "TIMESTAMP" + +/** DLC of Timestamp Channel */ +#define TIMESTAMP_CHANNEL_DLC (sizeof(Timestamp)) + +/** Name of Channel to send Counter to. */ +#define COUNTER_CHANNEL_NAME "COUNTER" + +/** DLC of Counter Channel */ +#define COUNTER_CHANNEL_DLC (sizeof(Counter)) + +/****************************************************************************** + * Types and Classes + *****************************************************************************/ + +/** Struct of the "Timestamp" channel payload. */ +typedef struct _Timestamp +{ + uint32_t timestamp; /**< Timestamp [ms]. */ +} __attribute__((packed)) Timestamp; + +/** Struct of the "Counter" channel payload. */ +typedef struct _Counter +{ + uint32_t count; /**< Count [digits]. */ +} __attribute__((packed)) Counter; + +/****************************************************************************** + * Functions + *****************************************************************************/ + +#endif /* SERIAL_MUX_CHANNELS_H */ diff --git a/examples/cpp/main.cpp b/examples/cpp/main.cpp new file mode 100644 index 0000000..970e33b --- /dev/null +++ b/examples/cpp/main.cpp @@ -0,0 +1,141 @@ +/* MIT License + * + * Copyright (c) 2023 Gabryel Reyes + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/******************************************************************************* + DESCRIPTION +*******************************************************************************/ +/** + * @brief SerialMuxProt Example + * @author Gabryel Reyes + */ + +/****************************************************************************** + * Includes + *****************************************************************************/ + +#include +#include +#include "SerialMuxChannels.h" + +/****************************************************************************** + * Compiler Switches + *****************************************************************************/ + +/****************************************************************************** + * Macros + *****************************************************************************/ + +/****************************************************************************** + * Types and classes + *****************************************************************************/ + +/****************************************************************************** + * Prototypes + *****************************************************************************/ + +static void gCounterChannelCallback(const uint8_t *payload, const uint8_t payloadSize); + +/****************************************************************************** + * Local Variables + *****************************************************************************/ + +/** Serial interface baudrate. */ +static const uint32_t SERIAL_BAUDRATE = 115200U; + +/** + * SerialMuxProt Server Instance. + * @note Serial is given as parameter to the constructor. This means, it cannot be used for other purposes. + * + * @tparam tMaxChannels set to MAX_CHANNELS, defined in SerialMuxChannels.h. + */ +SerialMuxProtServer gSmpServer(Serial); + +/** SerialMuxProt Channel id for sending timestamps. */ +uint8_t gSerialMuxProtChannelIdTimestamp = 0U; + +/****************************************************************************** + * Public Methods + *****************************************************************************/ + +/** + * Setup the application. + */ +void setup() +{ + /* Initialize Serial */ + Serial.begin(SERIAL_BAUDRATE); + + /* Create Channel for sending timestamps. */ + gSerialMuxProtChannelIdTimestamp = gSmpServer.createChannel(TIMESTAMP_CHANNEL_NAME, TIMESTAMP_CHANNEL_DLC); + + /* Subscribe to channel for receiving a counter. */ + gSmpServer.subscribeToChannel(COUNTER_CHANNEL_NAME, gCounterChannelCallback); +} + +/** + * Process the application periodically. + */ +void loop() +{ + /* Process SerialMuxProt. */ + gSmpServer.process(millis()); +} + +/****************************************************************************** + * Protected Methods + *****************************************************************************/ + +/****************************************************************************** + * Private Methods + *****************************************************************************/ + +/****************************************************************************** + * External Functions + *****************************************************************************/ + +/****************************************************************************** + * Local Functions + *****************************************************************************/ + +/** + * Receives a counter over SerialMuxProt channel. + * + * @param[in] payload Counter in digits. + * @param[in] payloadSize Size of one counter. + */ +void gCounterChannelCallback(const uint8_t *payload, const uint8_t payloadSize) +{ + if ((nullptr != payload) && (COUNTER_CHANNEL_DLC == payloadSize)) + { + const Counter *counterData = reinterpret_cast(payload); + + /* Send as many timestamps as the counter is set. */ + for (uint32_t i = 0U; i < counterData->count; i++) + { + Timestamp timestampData; + timestampData.timestamp = millis(); + gSmpServer.sendData(gSerialMuxProtChannelIdTimestamp, reinterpret_cast(×tampData), + sizeof(timestampData)); + } + } +} \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 64769dd..9f5120e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -22,3 +22,9 @@ check_src_filters = check_flags = clangtidy: --header-filter='' --checks=-*,clang-analyzer-*,performance-*,portability-*,readability-uppercase-literal-suffix,readability-redundant-control-flow --warnings-as-errors=-*,clang-analyzer-*,performance-*,portability-*,readability-uppercase-literal-suffix,readability-redundant-control-flow check_skip_packages = yes + +[env:esp32dev] +platform = espressif32 +board = esp32dev +framework = arduino +monitor_speed = 115200 \ No newline at end of file