From 89dd97be6474811c22d80dae6ed838d54ccc45e4 Mon Sep 17 00:00:00 2001 From: developer Date: Thu, 3 Oct 2024 20:04:50 +0530 Subject: [PATCH 01/30] added enum for unsupported file insert but not mounted --- .vscode/settings.json | 5 +++++ includes/constants/StorageState.h | 2 +- includes/utils/StorageUSB.h | 1 + src/constants/StorageType.cpp | 6 +++++- src/utils/StorageUSB.cpp | 32 +++++++++++++++++++++++++++++-- 5 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a76d018 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "stdexcept": "cpp" + } +} \ No newline at end of file diff --git a/includes/constants/StorageState.h b/includes/constants/StorageState.h index 592bf89..b2621af 100644 --- a/includes/constants/StorageState.h +++ b/includes/constants/StorageState.h @@ -12,7 +12,7 @@ namespace apra { enum STORAGE_STATE { - STORAGE_INSERTED, STORAGE_MOUNTED, STORAGE_UNSAFE_EJECT, STORAGE_SAFE_EJECT + STORAGE_INSERTED, STORAGE_INSERTED_UNMOUNTED, STORAGE_MOUNTED, STORAGE_UNSAFE_EJECT, STORAGE_SAFE_EJECT }; } diff --git a/includes/utils/StorageUSB.h b/includes/utils/StorageUSB.h index a49897f..b3d3fa9 100644 --- a/includes/utils/StorageUSB.h +++ b/includes/utils/StorageUSB.h @@ -47,6 +47,7 @@ class StorageUSB bool mountWithoutPrivilege(StorageMinimalInfo storageDevice); StorageMinimalInfo getHighCapacityPartition(std::string deviceNode); bool isDeviceNodeConnected(); + void checkDeviceNode(); bool m_shouldPrint; std::vector m_supportedTypes; diff --git a/src/constants/StorageType.cpp b/src/constants/StorageType.cpp index 5ca6c29..b80e2b9 100644 --- a/src/constants/StorageType.cpp +++ b/src/constants/StorageType.cpp @@ -35,10 +35,14 @@ STORAGE_TYPE STORAGE_TYPE_STRING::getEnum(std::string typeStr) { return EXT4; } - else + else if (typeStr == getString(FAT32)) { return FAT32; } + else + { + return static_cast(-1); + } } } /* namespace apra */ diff --git a/src/utils/StorageUSB.cpp b/src/utils/StorageUSB.cpp index e4b5787..0e21d87 100644 --- a/src/utils/StorageUSB.cpp +++ b/src/utils/StorageUSB.cpp @@ -21,6 +21,8 @@ #include "utils/Utils.h" #include #include "utils/Macro.h" +#include +#include #define MAX_BUF_LEN 1024 @@ -32,7 +34,7 @@ StorageUSB::StorageUSB(string mountPath, vector supportedTypes, bool shouldPrint, bool skipMount) : m_shouldPrint(shouldPrint), m_supportedTypes(supportedTypes), m_mountPoint( mountPath), m_deviceNode(), m_partitionNode(), m_skipMount( - skipMount), m_state(STORAGE_SAFE_EJECT), m_manualPath(mountPath) + skipMount), m_state(STORAGE_SAFE_EJECT), m_manualPath(mountPath), m_fsFormat("") { // TODO Auto-generated constructor stub string error; @@ -154,6 +156,7 @@ string StorageUSB::mountDevice() { string usbMountPath; string devNode = insertCheck(); + bool isSupportedFs = false; if (m_skipMount) { StorageMinimalInfo highPartition = getHighCapacityPartition(devNode); @@ -163,6 +166,13 @@ string StorageUSB::mountDevice() m_mountPoint = usbMountPath; m_partitionNode = highPartition.m_partition; } + STORAGE_TYPE type = STORAGE_TYPE_STRING::getEnum(highPartition.m_fsType); + + auto it = std::find(m_supportedTypes.begin(), + m_supportedTypes.end(), + type); + + isSupportedFs = (it != m_supportedTypes.end()); } else { @@ -171,7 +181,11 @@ string StorageUSB::mountDevice() usbMountPath = m_mountPoint; } } - if (!usbMountPath.empty()) + if (!isSupportedFs) + { + m_state = STORAGE_INSERTED_UNMOUNTED; + } + else if (!usbMountPath.empty()) { m_state = STORAGE_MOUNTED; } @@ -621,6 +635,20 @@ bool StorageUSB::getStorageInfo(uint64_t &freeSpaceInMB, return true; } +void StorageUSB::checkDeviceNode() +{ + struct stat buffer; + string path = m_partitionNode; + if (path.length() && stat(path.c_str(), &buffer) == 0) + { + if (S_ISBLK(buffer.st_mode)) + { + return; + } + } + m_state = STORAGE_SAFE_EJECT; +} + } /* namespace apra */ From 30bc5bda84d1fa80112358cb2a121382cfdfc1ae Mon Sep 17 00:00:00 2001 From: Yashraj <88146397+yashrajsapra@users.noreply.github.com> Date: Mon, 5 Aug 2024 21:47:37 +0530 Subject: [PATCH 02/30] Create c-cpp.yml --- .github/workflows/c-cpp.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/c-cpp.yml diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml new file mode 100644 index 0000000..6a9c312 --- /dev/null +++ b/.github/workflows/c-cpp.yml @@ -0,0 +1,23 @@ +name: C/C++ CI + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: configure + run: ./configure + - name: make + run: make + - name: make check + run: make check + - name: make distcheck + run: make distcheck From 96c637757b851b78717efab33f89278bd7ef3c96 Mon Sep 17 00:00:00 2001 From: Yashraj <88146397+yashrajsapra@users.noreply.github.com> Date: Mon, 5 Aug 2024 21:51:13 +0530 Subject: [PATCH 03/30] Update c-cpp.yml --- .github/workflows/c-cpp.yml | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 6a9c312..92cc98b 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -8,16 +8,27 @@ on: jobs: build: - runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: configure - run: ./configure - - name: make - run: make - - name: make check - run: make check - - name: make distcheck - run: make distcheck + - name: Install CMake + run: sudo apt-get update && sudo apt-get install -y cmake + - name: Create build directory + run: mkdir -p build + - name: Configure + run: | + cd build + cmake .. + - name: Build + run: | + cd build + make + - name: Make check + run: | + cd build + make check + - name: Make distcheck + run: | + cd build + make distcheck From 7386cbd0c590ded09e8748de9887bfabe3190960 Mon Sep 17 00:00:00 2001 From: Yashraj <88146397+yashrajsapra@users.noreply.github.com> Date: Mon, 5 Aug 2024 21:53:02 +0530 Subject: [PATCH 04/30] Update c-cpp.yml --- .github/workflows/c-cpp.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 92cc98b..d5cab60 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -12,8 +12,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Install CMake - run: sudo apt-get update && sudo apt-get install -y cmake + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y cmake libudev-dev - name: Create build directory run: mkdir -p build - name: Configure From b02c406f1badc311cd911ee4cad9b84589524b00 Mon Sep 17 00:00:00 2001 From: Yashraj <88146397+yashrajsapra@users.noreply.github.com> Date: Mon, 5 Aug 2024 21:57:14 +0530 Subject: [PATCH 05/30] Update c-cpp.yml --- .github/workflows/c-cpp.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index d5cab60..c94eece 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -26,11 +26,8 @@ jobs: run: | cd build make - - name: Make check - run: | - cd build - make check - - name: Make distcheck - run: | - cd build - make distcheck + - name: Publish artifact + uses: actions/upload-artifact@v3 + with: + name: libApraUtils + path: build/libApraUtils.a From 183971f87d85160307e2bb0e19054a5bcf33f1fc Mon Sep 17 00:00:00 2001 From: Omkar Mujumdar Date: Fri, 7 Nov 2025 19:34:22 +0530 Subject: [PATCH 06/30] Update c-cpp.yml --- .github/workflows/c-cpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index c94eece..ba94cb6 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -27,7 +27,7 @@ jobs: cd build make - name: Publish artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: libApraUtils path: build/libApraUtils.a From c8d25b3839caa2942eea12fb634888e15c357240 Mon Sep 17 00:00:00 2001 From: Omkar Mujumdar Date: Thu, 8 Aug 2024 23:22:24 +0530 Subject: [PATCH 07/30] Initial version of Generic I2C interface for async communication --- includes/constants/EventCallbacks.h | 20 ++ includes/constants/I2CMessageType.h | 21 ++ includes/controllers/I2CInterface.h | 58 ++++ includes/models/I2CMessage.h | 60 ++++ includes/models/I2CTransactionMessage.h | 44 +++ src/controllers/I2CInterface.cpp | 391 ++++++++++++++++++++++++ src/models/I2CMessage.cpp | 112 +++++++ src/models/I2CTransactionMessage.cpp | 78 +++++ 8 files changed, 784 insertions(+) create mode 100644 includes/constants/EventCallbacks.h create mode 100644 includes/constants/I2CMessageType.h create mode 100644 includes/controllers/I2CInterface.h create mode 100644 includes/models/I2CMessage.h create mode 100644 includes/models/I2CTransactionMessage.h create mode 100644 src/controllers/I2CInterface.cpp create mode 100644 src/models/I2CMessage.cpp create mode 100644 src/models/I2CTransactionMessage.cpp diff --git a/includes/constants/EventCallbacks.h b/includes/constants/EventCallbacks.h new file mode 100644 index 0000000..e3a6486 --- /dev/null +++ b/includes/constants/EventCallbacks.h @@ -0,0 +1,20 @@ +/* + * EventCallbackI2C.h + * + * Created on: Aug 7, 2024 + * Author: developer + */ + +#ifndef INCLUDES_CALLBACK_EVENTCALLBACKS_H_ +#define INCLUDES_CALLBACK_EVENTCALLBACKS_H_ + +namespace apra +{ + +class I2C_Transaction_Message; + +} // namespace apra + +typedef void* I2CEventCallback(void *context, apra::I2C_Transaction_Message message); + +#endif /* INCLUDES_CALLBACK_EVENTCALLBACKS_H_ */ diff --git a/includes/constants/I2CMessageType.h b/includes/constants/I2CMessageType.h new file mode 100644 index 0000000..18911ef --- /dev/null +++ b/includes/constants/I2CMessageType.h @@ -0,0 +1,21 @@ +/* + * I2CMessageType.h + * + * Created on: Aug 5, 2024 + * Author: developer + */ + +#ifndef INCLUDES_CONSTANTS_I2CMESSAGETYPE_H_ +#define INCLUDES_CONSTANTS_I2CMESSAGETYPE_H_ + +namespace apra +{ + +enum I2C_MESSAGE_TYPE +{ + I2C_WRITE, I2C_READ, I2C_READ_COMPARE_EQUAL, I2C_READ_COMPARE_NOT_EQUAL +}; + +} /* namespace apra */ + +#endif /* INCLUDES_CONSTANTS_I2CMESSAGETYPE_H_ */ diff --git a/includes/controllers/I2CInterface.h b/includes/controllers/I2CInterface.h new file mode 100644 index 0000000..81f698b --- /dev/null +++ b/includes/controllers/I2CInterface.h @@ -0,0 +1,58 @@ +/* + * I2CInterface.h + * + * Created on: Aug 5, 2024 + * Author: developer + */ + +#ifndef SRC_CONTROLLERS_I2CINTERFACE_H_ +#define SRC_CONTROLLERS_I2CINTERFACE_H_ + +#include +#include +#include +#include +#include "utils/I2CBus.h" +#include "utils/Mutex.h" + +namespace apra +{ + +class I2C_Interface: public ProcessThread +{ +public: + I2C_Interface(string i2cPath, string name, uint64_t fpsHz, + bool shouldPrint); + virtual ~I2C_Interface(); + virtual void process(Message *obj); + uint64_t registerEvent(I2C_Transaction_Message message); + void unregisterEvent(uint64_t messageHandle); + I2CError reSetupI2CBus(); + bool isSuccessfullSetup(); +protected: + virtual void processEvents(); + virtual void processSingleEvent(); + void processEvent(); + void processMessage(I2C_Transaction_Message *txMessage); + void processI2CTransaction(I2C_Transaction_Message *txMessage); + + I2CError performRead(uint8_t chipNumber, I2C_Message &message); + I2CError performCompareRead(uint8_t chipNumber, I2C_Message &message, + bool compareEquals); + I2CError performWrite(uint8_t chipNumber, I2C_Message &message); + void performTransactionDelay(const uint64_t timeDelay); + uint64_t getNormalizedDelay(int64_t largerTime, int64_t smallerTime, uint64_t timeDelay); + + string m_i2cPath; + I2C_Bus m_i2cBus; + map m_registeredEvents; + vector m_processedEvents; + apra::Mutex m_eventMessageLock; + int64_t m_lastProcessedEventTs; + bool m_setupSuccess; + apra::Mutex m_processLock; +}; + +} /* namespace apra */ + +#endif /* SRC_CONTROLLERS_I2CINTERFACE_H_ */ diff --git a/includes/models/I2CMessage.h b/includes/models/I2CMessage.h new file mode 100644 index 0000000..0e389c4 --- /dev/null +++ b/includes/models/I2CMessage.h @@ -0,0 +1,60 @@ +/* + * I2CMessage.h + * + * Created on: Aug 5, 2024 + * Author: developer + */ + +#ifndef SRC_MODELS_I2CMESSAGE_H_ +#define SRC_MODELS_I2CMESSAGE_H_ + +#include +#include +#include +#include + +#define I2C_RETRY_FAILURE_DELAY 5000 + +using namespace std; +namespace apra +{ +class I2C_Message +{ +public: + I2C_Message(); + virtual ~I2C_Message(); + void configureWrite(vector registerNumber, vector data); + void configureWrite(uint64_t registerNumber, uint64_t data, + uint64_t registerSize, uint64_t dataSize); + void configureRead(vector registerNumber, uint64_t dataSize); + void configureRead(uint64_t registerNumber, uint64_t registerSize, + uint64_t dataSize); + void configureReadWithComparison(vector registerNumber, + uint64_t dataSize, const vector dataCompare, + bool compareEquals); + void configureReadWithComparison(uint64_t registerNumber, + uint64_t registerSize, uint64_t dataSize, + const uint64_t dataCompare, bool compareEquals); + void addDelay(uint64_t delayInUsec); + void setRetries(uint64_t retryCount); + uint64_t getCombinedData(); + uint64_t getCombinedRegister(); + + I2CError m_error; + I2C_MESSAGE_TYPE m_type; + vector m_registerNumber; + vector m_data; + vector m_compareData; + uint64_t m_retryCount; + uint64_t m_delayInUsec; + uint64_t m_retryDelayInUsec; + bool m_allowOtherProcessOnIdle; +protected: + uint64_t m_registerSize; + uint64_t m_dataSize; + +}; + +} /* namespace apra */ + +#endif /* SRC_MODELS_I2CMESSAGE_H_ */ diff --git a/includes/models/I2CTransactionMessage.h b/includes/models/I2CTransactionMessage.h new file mode 100644 index 0000000..8df3aed --- /dev/null +++ b/includes/models/I2CTransactionMessage.h @@ -0,0 +1,44 @@ +/* + * I2CTransactionMessage.h + * + * Created on: Aug 5, 2024 + * Author: developer + */ + +#ifndef INCLUDES_MODELS_I2CTRANSACTIONMESSAGE_H_ +#define INCLUDES_MODELS_I2CTRANSACTIONMESSAGE_H_ + +#include +#include +#include +#include "constants/EventCallbacks.h" + +namespace apra +{ +class I2C_Transaction_Message: public Message +{ +public: + I2C_Transaction_Message(); + I2C_Transaction_Message(uint8_t chipNumber, + vector messageQueue, + uint64_t transactionDelayUsec = 0); + virtual ~I2C_Transaction_Message(); + I2C_Transaction_Message& operator=(const I2C_Transaction_Message &other); + I2CError getError(); + void setError(I2CError error); + vector& getAllMessages(); + void registerEventHandle(I2CEventCallback *callback, void *context); + void publishTransaction(); + I2CError m_error; + uint8_t m_chipNumber; + bool m_stopOnAnyTransactionFailure; + uint64_t m_transactionDelayUsec; + vector m_messages; +protected: + void *m_callbackContext; + I2CEventCallback *m_callback; +}; + +} /* namespace apra */ + +#endif /* INCLUDES_MODELS_I2CTRANSACTIONMESSAGE_H_ */ diff --git a/src/controllers/I2CInterface.cpp b/src/controllers/I2CInterface.cpp new file mode 100644 index 0000000..1274a59 --- /dev/null +++ b/src/controllers/I2CInterface.cpp @@ -0,0 +1,391 @@ +/* + * I2CInterface.cpp + * + * Created on: Aug 5, 2024 + * Author: Apra Labs + */ + +#include +#include "utils/Macro.h" +#include "utils/ScopeLock.h" +#include "controllers/I2CInterface.h" + +namespace apra +{ + +I2C_Interface::I2C_Interface(string i2cPath, string name, uint64_t fpsHz, + bool shouldPrint) : + ProcessThread(name, fpsHz), m_i2cPath(i2cPath), m_i2cBus(i2cPath, + shouldPrint), m_lastProcessedEventTs(0), m_setupSuccess(false) +{ + // TODO Auto-generated constructor stub + I2CError i2cError = m_i2cBus.openBus(); + if (i2cError.isError()) + { + string error = "Unable to open i2c bus " + m_i2cPath + "\n"; + error += i2cError.getMessage() + "\n"; + error += i2cError.getDebugMessage(); + throw std::invalid_argument(error); + } + else + { + m_setupSuccess = true; + } +} + +I2C_Interface::~I2C_Interface() +{ + // TODO Auto-generated destructor stub + m_i2cBus.closeBus(); +} + +I2CError I2C_Interface::reSetupI2CBus() +{ + I2CError response; + m_i2cBus.closeBus(); + m_setupSuccess = false; + response = m_i2cBus.openBus(); + m_setupSuccess = !response.isError(); + return response; +} + +bool I2C_Interface::isSuccessfullSetup() +{ + return m_setupSuccess; +} + +uint64_t I2C_Interface::registerEvent(I2C_Transaction_Message message) +{ + ScopeLock scopeLock(m_eventMessageLock); + m_registeredEvents[message.getHandle()] = message; + return message.getHandle(); +} + +void I2C_Interface::unregisterEvent(uint64_t messageHandle) +{ + ScopeLock scopeLock(m_eventMessageLock); + m_registeredEvents.erase(messageHandle); +} + +void I2C_Interface::process(Message *obj) +{ + if (!m_setupSuccess) + { + return; + } + processEvents(); + MONOCURRTIME(m_lastProcessedEventTs); + if (!obj) + { + return; + } + I2C_Transaction_Message *txMessage = (I2C_Transaction_Message*) obj; + processMessage(txMessage); + enqueResponse(txMessage); + if (txMessage->m_transactionDelayUsec > 0) + { + MONOCURRTIME(timeNow); + uint64_t timeDelay = txMessage->m_transactionDelayUsec; + if ((timeNow - m_lastProcessedEventTs) > m_frequSec) + { + processEvents(); + MONOTIMEUS(m_lastProcessedEventTs); + timeDelay = getNormalizedDelay(m_lastProcessedEventTs, timeNow, + txMessage->m_transactionDelayUsec); + } + if (timeDelay) + { + usleep(timeDelay); + } + } + std::queue requests; + { + ScopeLock lock(m_requestLock); + while (!m_requestQueue.empty()) + { + Message *item = m_requestQueue.front(); + m_requestQueue.pop(); + if (item) + { + requests.push((I2C_Transaction_Message*) item); + } + } + } + while (!requests.empty()) + { + I2C_Transaction_Message *item = requests.front(); + requests.pop(); + if (item) + { + processMessage(item); + } + } + +} + +void I2C_Interface::processEvents() +{ + MONOCURRTIME(timeNow); + if ((timeNow - m_lastProcessedEventTs) < m_frequSec) + { + return; + } + map eventMessages; + { + ScopeLock lock(m_eventMessageLock); + eventMessages = m_registeredEvents; + } + for (map::iterator eventItr = + eventMessages.begin(); eventItr != eventMessages.end(); eventItr++) + { + if (std::find(m_processedEvents.begin(), m_processedEvents.end(), + eventItr->first) != m_processedEvents.end()) + { + continue; + } + I2C_Transaction_Message i2cTxMessage = eventItr->second; + processI2CTransaction(&i2cTxMessage); + i2cTxMessage.publishTransaction(); + } + m_processedEvents.clear(); +} + +void I2C_Interface::processSingleEvent() +{ + MONOCURRTIME(timeNow); + if ((timeNow - m_lastProcessedEventTs) < m_frequSec) + { + return; + } + map eventMessages; + { + ScopeLock lock(m_eventMessageLock); + eventMessages = m_registeredEvents; + } + for (map::iterator eventItr = + eventMessages.begin(); eventItr != eventMessages.end(); eventItr++) + { + if (std::find(m_processedEvents.begin(), m_processedEvents.end(), + eventItr->first) != m_processedEvents.end()) + { + continue; + } + I2C_Transaction_Message i2cTxMessage = eventItr->second; + processI2CTransaction(&i2cTxMessage); + i2cTxMessage.publishTransaction(); + m_processedEvents.push_back(eventItr->first); + break; + } + if (m_processedEvents.size() >= m_registeredEvents.size()) + { + m_processedEvents.clear(); + MONOTIMEUS(m_lastProcessedEventTs); + } +} + +void I2C_Interface::processMessage(I2C_Transaction_Message *txMessage) +{ + processI2CTransaction(txMessage); + enqueResponse(txMessage); + if (txMessage->m_transactionDelayUsec > 0) + { + MONOCURRTIME(timeNow); + uint64_t timeDelay = txMessage->m_transactionDelayUsec; + if ((timeNow - m_lastProcessedEventTs) > m_frequSec) + { + processEvents(); + MONOTIMEUS(m_lastProcessedEventTs); + timeDelay = getNormalizedDelay(m_lastProcessedEventTs, timeNow, + txMessage->m_transactionDelayUsec); + } + if (timeDelay) + { + usleep(timeDelay); + } + } +} + +I2CError I2C_Interface::performRead(uint8_t chipNumber, I2C_Message &message) +{ + I2CError response; + uint64_t retryCount = message.m_retryCount; + do + { + if (retryCount != message.m_retryCount) + { + if (message.m_allowOtherProcessOnIdle) + { + performTransactionDelay(message.m_retryDelayInUsec); + } + else if (message.m_retryDelayInUsec) + { + usleep(message.m_retryDelayInUsec); + } + } + response = m_i2cBus.genericRead(chipNumber, message.m_registerNumber, + message.m_data); + if (!response.isError()) + { + break; + } + } while (retryCount-- > 0); + message.m_error = response; + return response; +} + +I2CError I2C_Interface::performCompareRead(uint8_t chipNumber, + I2C_Message &message, bool compareEquals) +{ + I2CError response; + uint64_t retryCount = message.m_retryCount; + do + { + if (retryCount != message.m_retryCount) + { + if (message.m_allowOtherProcessOnIdle) + { + performTransactionDelay(message.m_retryDelayInUsec); + } + else if (message.m_retryDelayInUsec) + { + usleep(message.m_retryDelayInUsec); + } + } + response = m_i2cBus.genericRead(chipNumber, message.m_registerNumber, + message.m_data); + if (!response.isError()) + { + if (compareEquals + && (message.m_data.size() == message.m_compareData.size()) + && (message.m_data == message.m_compareData)) + { + break; + } + else if (!compareEquals + && ((message.m_data.size() != message.m_compareData.size()) + || (message.m_data == message.m_compareData))) + { + break; + } + } + } while (retryCount-- > 0); + message.m_error = response; + return response; +} +I2CError I2C_Interface::performWrite(uint8_t chipNumber, I2C_Message &message) +{ + I2CError response; + uint64_t retryCount = message.m_retryCount; + do + { + if (retryCount != message.m_retryCount) + { + if (message.m_allowOtherProcessOnIdle) + { + performTransactionDelay(message.m_retryDelayInUsec); + } + else if (message.m_retryDelayInUsec) + { + usleep(message.m_retryDelayInUsec); + } + } + response = m_i2cBus.genericWrite(chipNumber, message.m_registerNumber, + message.m_data); + if (!response.isError()) + { + break; + } + } while (retryCount-- > 0); + message.m_error = response; + return response; +} + +void I2C_Interface::processI2CTransaction(I2C_Transaction_Message *txMessage) +{ + I2CError transactionError; + vector i2cMessages = txMessage->getAllMessages(); + for (size_t messageIndex = 0; messageIndex < i2cMessages.size(); + messageIndex++) + { + I2CError i2cError; + switch (i2cMessages[messageIndex].m_type) + { + case I2C_READ: + { + i2cError = performRead(txMessage->m_chipNumber, + i2cMessages[messageIndex]); + break; + } + case I2C_READ_COMPARE_EQUAL: + case I2C_READ_COMPARE_NOT_EQUAL: + { + i2cError = performCompareRead(txMessage->m_chipNumber, + i2cMessages[messageIndex], + i2cMessages[messageIndex].m_type == I2C_READ_COMPARE_EQUAL); + break; + } + case I2C_WRITE: + { + i2cError = performWrite(txMessage->m_chipNumber, + i2cMessages[messageIndex]); + break; + } + } + if (i2cError.isError()) + { + transactionError = i2cError; + if (txMessage->m_stopOnAnyTransactionFailure) + { + break; + } + } + if (i2cMessages[messageIndex].m_delayInUsec) + { + if (i2cMessages[messageIndex].m_allowOtherProcessOnIdle) + { + performTransactionDelay( + i2cMessages[messageIndex].m_delayInUsec); + } + else + { + usleep(i2cMessages[messageIndex].m_delayInUsec); + } + } + } + txMessage->m_error = transactionError; +} + +void I2C_Interface::performTransactionDelay(const uint64_t timeDelay) +{ + if (!timeDelay) + { + return; + } + MONOCURRTIME(startTime); + int64_t timeNow = startTime; + uint64_t pendingEvents = m_registeredEvents.size() + - m_processedEvents.size(); + + uint64_t delayInUsec = getNormalizedDelay(timeNow, startTime, timeDelay); + while ((delayInUsec > 0) && (pendingEvents-- > 0)) + { + processSingleEvent(); + MONOTIMEUS(timeNow); + delayInUsec = getNormalizedDelay(timeNow, startTime, timeDelay); + } + if (delayInUsec > 0) + { + usleep(delayInUsec); + } +} + +uint64_t I2C_Interface::getNormalizedDelay(int64_t largerTime, + int64_t smallerTime, uint64_t timeDelay) +{ + int64_t signedDiff = largerTime - smallerTime; + uint64_t timeDiff = signedDiff > -1 ? signedDiff : 0; + return (timeDiff < timeDelay) ? (timeDelay - timeDiff) : 0; +} + +} /* namespace apra */ + diff --git a/src/models/I2CMessage.cpp b/src/models/I2CMessage.cpp new file mode 100644 index 0000000..7b14500 --- /dev/null +++ b/src/models/I2CMessage.cpp @@ -0,0 +1,112 @@ +/* + * I2CMessage.cpp + * + * Created on: Aug 5, 2024 + * Author: developer + */ + +#include "models/I2CMessage.h" +#include "utils/Utils.h" + +namespace apra +{ + +I2C_Message::I2C_Message() : + m_error(), m_type(I2C_READ), m_registerNumber(), m_data(), m_compareData(), m_retryCount( + 0), m_delayInUsec(0), m_retryDelayInUsec( + I2C_RETRY_FAILURE_DELAY), m_allowOtherProcessOnIdle(false), m_registerSize( + 0), m_dataSize(0) +{ + // TODO Auto-generated constructor stub + +} + +I2C_Message::~I2C_Message() +{ + // TODO Auto-generated destructor stub +} + +void I2C_Message::configureWrite(vector registerNumber, + vector data) +{ + m_registerNumber = registerNumber; + m_registerSize = registerNumber.size(); + m_data = data; + m_dataSize = data.size(); + m_type = I2C_WRITE; +} +void I2C_Message::configureWrite(uint64_t registerNumber, uint64_t data, + uint64_t registerSize, uint64_t dataSize) +{ + m_registerNumber = Utils::extractBytes(registerNumber, registerSize); + m_registerSize = registerSize; + m_data = Utils::extractBytes(data, dataSize); + m_dataSize = dataSize; + m_type = I2C_WRITE; +} +void I2C_Message::configureRead(vector registerNumber, + uint64_t dataSize) +{ + m_registerNumber = registerNumber; + m_registerSize = registerNumber.size(); + m_dataSize = dataSize; + m_type = I2C_READ; +} +void I2C_Message::configureRead(uint64_t registerNumber, uint64_t registerSize, + uint64_t dataSize) +{ + m_registerNumber = Utils::extractBytes(registerNumber, registerSize); + m_registerSize = registerSize; + m_dataSize = dataSize; + m_type = I2C_READ; +} + +void I2C_Message::configureReadWithComparison(vector registerNumber, + uint64_t dataSize, const vector dataCompare, + bool compareEquals) +{ + m_registerNumber = registerNumber; + m_registerSize = registerNumber.size(); + m_dataSize = dataSize; + m_compareData = dataCompare; + m_type = + compareEquals ? I2C_READ_COMPARE_EQUAL : I2C_READ_COMPARE_NOT_EQUAL; +} +void I2C_Message::configureReadWithComparison(uint64_t registerNumber, + uint64_t registerSize, uint64_t dataSize, const uint64_t dataCompare, + bool compareEquals) +{ + m_registerNumber = Utils::extractBytes(registerNumber, registerSize); + m_registerSize = registerSize; + m_dataSize = dataSize; + m_compareData = Utils::extractBytes(dataCompare, dataSize); + m_type = + compareEquals ? I2C_READ_COMPARE_EQUAL : I2C_READ_COMPARE_NOT_EQUAL; + +} +void I2C_Message::addDelay(uint64_t delayInUsec) +{ + if (delayInUsec) + { + m_delayInUsec = delayInUsec; + } +} +void I2C_Message::setRetries(uint64_t retryCount) +{ + if (retryCount) + { + m_retryCount = retryCount; + } +} + +uint64_t I2C_Message::getCombinedData() +{ + return Utils::combineBytes(m_data); +} + +uint64_t I2C_Message::getCombinedRegister() +{ + return Utils::combineBytes(m_registerNumber); +} + +} /* namespace apra */ diff --git a/src/models/I2CTransactionMessage.cpp b/src/models/I2CTransactionMessage.cpp new file mode 100644 index 0000000..e5b6dc8 --- /dev/null +++ b/src/models/I2CTransactionMessage.cpp @@ -0,0 +1,78 @@ +/* + * I2CTransactionMessage.cpp + * + * Created on: Aug 5, 2024 + * Author: developer + */ + +#include + +namespace apra +{ + +I2C_Transaction_Message::I2C_Transaction_Message() : + Message(), m_error(), m_chipNumber(0), m_stopOnAnyTransactionFailure( + true), m_transactionDelayUsec(0), m_messages(), m_callbackContext( + NULL), m_callback(NULL) +{ + +} +I2C_Transaction_Message::I2C_Transaction_Message(uint8_t chipNumber, + vector messageQueue, uint64_t transactionDelayUsec) : + Message(), m_error(), m_chipNumber(chipNumber), m_stopOnAnyTransactionFailure( + true), m_transactionDelayUsec(transactionDelayUsec), m_messages( + messageQueue), m_callbackContext(NULL), m_callback(NULL) +{ + // TODO Auto-generated constructor stub + setType(REQUEST_RESPONSE); +} + +I2C_Transaction_Message::~I2C_Transaction_Message() +{ + // TODO Auto-generated destructor stub +} + +I2C_Transaction_Message& I2C_Transaction_Message::operator=( + const I2C_Transaction_Message &other) +{ + m_error = other.m_error; + m_chipNumber = other.m_chipNumber; + m_stopOnAnyTransactionFailure = other.m_stopOnAnyTransactionFailure; + m_transactionDelayUsec = other.m_transactionDelayUsec; + m_messages = other.m_messages; + m_callbackContext = other.m_callbackContext; + m_callback = other.m_callback; + return *this; +} + +I2CError I2C_Transaction_Message::getError() +{ + return m_error; +} + +void I2C_Transaction_Message::setError(I2CError error) +{ + m_error = error; +} + +vector& I2C_Transaction_Message::getAllMessages() +{ + return m_messages; +} + +void I2C_Transaction_Message::registerEventHandle(I2CEventCallback *callback, + void *context) +{ + m_callback = callback; + m_callbackContext = context; +} + +void I2C_Transaction_Message::publishTransaction() +{ + if (m_callback) + { + (*m_callback)(m_callbackContext, *this); + } +} + +} /* namespace apra */ From cabdf7e4427ca498a58e3c422fbfbffdbb2bbf7b Mon Sep 17 00:00:00 2001 From: Omkar Mujumdar Date: Fri, 9 Aug 2024 15:33:49 +0530 Subject: [PATCH 08/30] removed redundent code --- includes/controllers/I2CInterface.h | 1 - includes/models/I2CMessage.h | 8 ++--- src/controllers/I2CInterface.cpp | 52 ++++++++++++++-------------- src/models/I2CMessage.cpp | 18 +++++----- src/models/I2CTransactionMessage.cpp | 4 ++- 5 files changed, 42 insertions(+), 41 deletions(-) diff --git a/includes/controllers/I2CInterface.h b/includes/controllers/I2CInterface.h index 81f698b..382115c 100644 --- a/includes/controllers/I2CInterface.h +++ b/includes/controllers/I2CInterface.h @@ -32,7 +32,6 @@ class I2C_Interface: public ProcessThread protected: virtual void processEvents(); virtual void processSingleEvent(); - void processEvent(); void processMessage(I2C_Transaction_Message *txMessage); void processI2CTransaction(I2C_Transaction_Message *txMessage); diff --git a/includes/models/I2CMessage.h b/includes/models/I2CMessage.h index 0e389c4..72c2c41 100644 --- a/includes/models/I2CMessage.h +++ b/includes/models/I2CMessage.h @@ -26,14 +26,14 @@ class I2C_Message void configureWrite(vector registerNumber, vector data); void configureWrite(uint64_t registerNumber, uint64_t data, uint64_t registerSize, uint64_t dataSize); - void configureRead(vector registerNumber, uint64_t dataSize); + void configureRead(vector registerNumber, uint64_t expectedDataSize); void configureRead(uint64_t registerNumber, uint64_t registerSize, - uint64_t dataSize); + uint64_t expectedDataSize); void configureReadWithComparison(vector registerNumber, - uint64_t dataSize, const vector dataCompare, + uint64_t expectedDataSize, const vector dataCompare, bool compareEquals); void configureReadWithComparison(uint64_t registerNumber, - uint64_t registerSize, uint64_t dataSize, + uint64_t registerSize, uint64_t expectedDataSize, const uint64_t dataCompare, bool compareEquals); void addDelay(uint64_t delayInUsec); void setRetries(uint64_t retryCount); diff --git a/src/controllers/I2CInterface.cpp b/src/controllers/I2CInterface.cpp index 1274a59..01a151f 100644 --- a/src/controllers/I2CInterface.cpp +++ b/src/controllers/I2CInterface.cpp @@ -41,6 +41,7 @@ I2C_Interface::~I2C_Interface() I2CError I2C_Interface::reSetupI2CBus() { + ScopeLock lock(m_processLock); I2CError response; m_i2cBus.closeBus(); m_setupSuccess = false; @@ -74,30 +75,12 @@ void I2C_Interface::process(Message *obj) return; } processEvents(); - MONOCURRTIME(m_lastProcessedEventTs); if (!obj) { return; } I2C_Transaction_Message *txMessage = (I2C_Transaction_Message*) obj; processMessage(txMessage); - enqueResponse(txMessage); - if (txMessage->m_transactionDelayUsec > 0) - { - MONOCURRTIME(timeNow); - uint64_t timeDelay = txMessage->m_transactionDelayUsec; - if ((timeNow - m_lastProcessedEventTs) > m_frequSec) - { - processEvents(); - MONOTIMEUS(m_lastProcessedEventTs); - timeDelay = getNormalizedDelay(m_lastProcessedEventTs, timeNow, - txMessage->m_transactionDelayUsec); - } - if (timeDelay) - { - usleep(timeDelay); - } - } std::queue requests; { ScopeLock lock(m_requestLock); @@ -120,7 +103,6 @@ void I2C_Interface::process(Message *obj) processMessage(item); } } - } void I2C_Interface::processEvents() @@ -135,6 +117,7 @@ void I2C_Interface::processEvents() ScopeLock lock(m_eventMessageLock); eventMessages = m_registeredEvents; } + bool isAnyEventProcessed = false; for (map::iterator eventItr = eventMessages.begin(); eventItr != eventMessages.end(); eventItr++) { @@ -143,11 +126,16 @@ void I2C_Interface::processEvents() { continue; } + isAnyEventProcessed = true; I2C_Transaction_Message i2cTxMessage = eventItr->second; processI2CTransaction(&i2cTxMessage); i2cTxMessage.publishTransaction(); } m_processedEvents.clear(); + if (isAnyEventProcessed) + { + MONOTIMEUS(m_lastProcessedEventTs); + } } void I2C_Interface::processSingleEvent() @@ -194,7 +182,6 @@ void I2C_Interface::processMessage(I2C_Transaction_Message *txMessage) if ((timeNow - m_lastProcessedEventTs) > m_frequSec) { processEvents(); - MONOTIMEUS(m_lastProcessedEventTs); timeDelay = getNormalizedDelay(m_lastProcessedEventTs, timeNow, txMessage->m_transactionDelayUsec); } @@ -203,6 +190,10 @@ void I2C_Interface::processMessage(I2C_Transaction_Message *txMessage) usleep(timeDelay); } } + else + { + processEvents(); + } } I2CError I2C_Interface::performRead(uint8_t chipNumber, I2C_Message &message) @@ -222,8 +213,11 @@ I2CError I2C_Interface::performRead(uint8_t chipNumber, I2C_Message &message) usleep(message.m_retryDelayInUsec); } } - response = m_i2cBus.genericRead(chipNumber, message.m_registerNumber, - message.m_data); + { + ScopeLock lock(m_processLock); + response = m_i2cBus.genericRead(chipNumber, + message.m_registerNumber, message.m_data); + } if (!response.isError()) { break; @@ -251,8 +245,11 @@ I2CError I2C_Interface::performCompareRead(uint8_t chipNumber, usleep(message.m_retryDelayInUsec); } } - response = m_i2cBus.genericRead(chipNumber, message.m_registerNumber, - message.m_data); + { + ScopeLock lock(m_processLock); + response = m_i2cBus.genericRead(chipNumber, + message.m_registerNumber, message.m_data); + } if (!response.isError()) { if (compareEquals @@ -289,8 +286,11 @@ I2CError I2C_Interface::performWrite(uint8_t chipNumber, I2C_Message &message) usleep(message.m_retryDelayInUsec); } } - response = m_i2cBus.genericWrite(chipNumber, message.m_registerNumber, - message.m_data); + { + ScopeLock lock(m_processLock); + response = m_i2cBus.genericWrite(chipNumber, + message.m_registerNumber, message.m_data); + } if (!response.isError()) { break; diff --git a/src/models/I2CMessage.cpp b/src/models/I2CMessage.cpp index 7b14500..936902b 100644 --- a/src/models/I2CMessage.cpp +++ b/src/models/I2CMessage.cpp @@ -45,41 +45,41 @@ void I2C_Message::configureWrite(uint64_t registerNumber, uint64_t data, m_type = I2C_WRITE; } void I2C_Message::configureRead(vector registerNumber, - uint64_t dataSize) + uint64_t expectedDataSize) { m_registerNumber = registerNumber; m_registerSize = registerNumber.size(); - m_dataSize = dataSize; + m_dataSize = expectedDataSize; m_type = I2C_READ; } void I2C_Message::configureRead(uint64_t registerNumber, uint64_t registerSize, - uint64_t dataSize) + uint64_t expectedDataSize) { m_registerNumber = Utils::extractBytes(registerNumber, registerSize); m_registerSize = registerSize; - m_dataSize = dataSize; + m_dataSize = expectedDataSize; m_type = I2C_READ; } void I2C_Message::configureReadWithComparison(vector registerNumber, - uint64_t dataSize, const vector dataCompare, + uint64_t expectedDataSize, const vector dataCompare, bool compareEquals) { m_registerNumber = registerNumber; m_registerSize = registerNumber.size(); - m_dataSize = dataSize; + m_dataSize = expectedDataSize; m_compareData = dataCompare; m_type = compareEquals ? I2C_READ_COMPARE_EQUAL : I2C_READ_COMPARE_NOT_EQUAL; } void I2C_Message::configureReadWithComparison(uint64_t registerNumber, - uint64_t registerSize, uint64_t dataSize, const uint64_t dataCompare, + uint64_t registerSize, uint64_t expectedDataSize, const uint64_t dataCompare, bool compareEquals) { m_registerNumber = Utils::extractBytes(registerNumber, registerSize); m_registerSize = registerSize; - m_dataSize = dataSize; - m_compareData = Utils::extractBytes(dataCompare, dataSize); + m_dataSize = expectedDataSize; + m_compareData = Utils::extractBytes(dataCompare, expectedDataSize); m_type = compareEquals ? I2C_READ_COMPARE_EQUAL : I2C_READ_COMPARE_NOT_EQUAL; diff --git a/src/models/I2CTransactionMessage.cpp b/src/models/I2CTransactionMessage.cpp index e5b6dc8..867a8a3 100644 --- a/src/models/I2CTransactionMessage.cpp +++ b/src/models/I2CTransactionMessage.cpp @@ -15,7 +15,7 @@ I2C_Transaction_Message::I2C_Transaction_Message() : true), m_transactionDelayUsec(0), m_messages(), m_callbackContext( NULL), m_callback(NULL) { - + setType(REQUEST_RESPONSE); } I2C_Transaction_Message::I2C_Transaction_Message(uint8_t chipNumber, vector messageQueue, uint64_t transactionDelayUsec) : @@ -42,6 +42,8 @@ I2C_Transaction_Message& I2C_Transaction_Message::operator=( m_messages = other.m_messages; m_callbackContext = other.m_callbackContext; m_callback = other.m_callback; + m_handle = other.m_handle; + m_type = other.m_type; return *this; } From d90e4455deddec49a71904bd3bb670239856f333 Mon Sep 17 00:00:00 2001 From: Omkar Mujumdar Date: Mon, 12 Aug 2024 11:12:30 +0530 Subject: [PATCH 09/30] Updated parameter names in the constructor --- includes/controllers/I2CInterface.h | 2 +- src/controllers/I2CInterface.cpp | 40 ++++++++++++++--------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/includes/controllers/I2CInterface.h b/includes/controllers/I2CInterface.h index 382115c..250cd7d 100644 --- a/includes/controllers/I2CInterface.h +++ b/includes/controllers/I2CInterface.h @@ -21,7 +21,7 @@ namespace apra class I2C_Interface: public ProcessThread { public: - I2C_Interface(string i2cPath, string name, uint64_t fpsHz, + I2C_Interface(string i2cPath, string processName, uint64_t processFpsHz, bool shouldPrint); virtual ~I2C_Interface(); virtual void process(Message *obj); diff --git a/src/controllers/I2CInterface.cpp b/src/controllers/I2CInterface.cpp index 01a151f..ce06e1f 100644 --- a/src/controllers/I2CInterface.cpp +++ b/src/controllers/I2CInterface.cpp @@ -310,26 +310,26 @@ void I2C_Interface::processI2CTransaction(I2C_Transaction_Message *txMessage) I2CError i2cError; switch (i2cMessages[messageIndex].m_type) { - case I2C_READ: - { - i2cError = performRead(txMessage->m_chipNumber, - i2cMessages[messageIndex]); - break; - } - case I2C_READ_COMPARE_EQUAL: - case I2C_READ_COMPARE_NOT_EQUAL: - { - i2cError = performCompareRead(txMessage->m_chipNumber, - i2cMessages[messageIndex], - i2cMessages[messageIndex].m_type == I2C_READ_COMPARE_EQUAL); - break; - } - case I2C_WRITE: - { - i2cError = performWrite(txMessage->m_chipNumber, - i2cMessages[messageIndex]); - break; - } + case I2C_READ: + { + i2cError = performRead(txMessage->m_chipNumber, + i2cMessages[messageIndex]); + break; + } + case I2C_READ_COMPARE_EQUAL: + case I2C_READ_COMPARE_NOT_EQUAL: + { + i2cError = performCompareRead(txMessage->m_chipNumber, + i2cMessages[messageIndex], + i2cMessages[messageIndex].m_type == I2C_READ_COMPARE_EQUAL); + break; + } + case I2C_WRITE: + { + i2cError = performWrite(txMessage->m_chipNumber, + i2cMessages[messageIndex]); + break; + } } if (i2cError.isError()) { From c88bd03c6953c62d4808478bf82ad083ce15f292 Mon Sep 17 00:00:00 2001 From: Omkar Mujumdar Date: Tue, 13 Aug 2024 16:32:44 +0530 Subject: [PATCH 10/30] 1. included all the interfaces in aprautils header 2. add missing message implementation 3. removed warnings --- includes/ApraUtils.h | 19 ++++++++++++------- src/models/Message.cpp | 4 ++++ src/utils/StorageUSB.cpp | 19 ++++++++++--------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/includes/ApraUtils.h b/includes/ApraUtils.h index eb2bdf0..36ad613 100644 --- a/includes/ApraUtils.h +++ b/includes/ApraUtils.h @@ -7,26 +7,31 @@ #ifndef INCLUDES_APRAUTILS_H_ #define INCLUDES_APRAUTILS_H_ +#include "constants/EventCallbacks.h" +#include "constants/I2CMessageType.h" +#include "constants/MessageType.h" #include "constants/StorageState.h" #include "constants/StorageType.h" -#include "constants/MessageType.h" #include "constants/ThreadType.h" +#include "controllers/I2CInterface.h" #include "models/GenericError.h" #include "models/I2CError.h" +#include "models/I2CMessage.h" +#include "models/I2CTransactionMessage.h" +#include "models/Message.h" #include "models/Range.h" #include "models/StorageMinimalInfo.h" -#include "models/Message.h" #include "utils/FileIO.h" #include "utils/GPIO.h" #include "utils/I2CBus.h" -#include "utils/RealHexParser.h" -#include "utils/Utils.h" -#include "utils/ScopeFunction.h" #include "utils/Macro.h" -#include "utils/StorageUSB.h" -#include "utils/PWM.h" #include "utils/Mutex.h" #include "utils/ProcessThread.h" +#include "utils/PWM.h" +#include "utils/RealHexParser.h" +#include "utils/ScopeFunction.h" #include "utils/ScopeLock.h" +#include "utils/StorageUSB.h" +#include "utils/Utils.h" #endif /* INCLUDES_APRAUTILS_H_ */ diff --git a/src/models/Message.cpp b/src/models/Message.cpp index 509b83f..cea27a0 100644 --- a/src/models/Message.cpp +++ b/src/models/Message.cpp @@ -30,4 +30,8 @@ MESSAGE_TYPE Message::getType() return m_type; } +uint64_t Message::getHandle() +{ + return m_handle; +} } diff --git a/src/utils/StorageUSB.cpp b/src/utils/StorageUSB.cpp index 0e21d87..bc6ddbc 100644 --- a/src/utils/StorageUSB.cpp +++ b/src/utils/StorageUSB.cpp @@ -594,43 +594,44 @@ bool StorageUSB::getStorageInfo(uint64_t &freeSpaceInMB, } if (m_shouldPrint) { - printf("stat.f_bsize=%lu\n stat.f_frsize=%lu\n stat.f_bfree=%lu\n " - "stat.f_blocks=%lu\n", stat.f_bsize, stat.f_frsize, + printf("stat.f_bsize=%" PRIu64 "\n stat.f_frsize=%" PRIu64 "\n stat.f_bfree=%" PRIu64 "\n " + "stat.f_blocks=%" PRIu64 "\n", stat.f_bsize, stat.f_frsize, stat.f_bfree, stat.f_blocks); } uint64_t sz = stat.f_bsize; if (m_shouldPrint) { - printf("int sz = stat.f_bsize; === %lu = %lu\n", sz, stat.f_bsize); - printf("sz *= stat.f_bfree === %lu *= %lu\n", sz, stat.f_bfree); + printf("int sz = stat.f_bsize; === %" PRIu64 " = %" PRIu64 "\n", sz, stat.f_bsize); + printf("sz *= stat.f_bfree === %" PRIu64 " *= %" PRIu64 "\n", sz, stat.f_bfree); } sz *= stat.f_bfree; freeSpaceInMB = sz >> 20; if (m_shouldPrint) { - printf("int freeSpaceInMB = sz >> 20 === int %lu = %lu >> 20\n", + printf("int freeSpaceInMB = sz >> 20 === int %" PRId64 " = %" PRId64 " >> 20\n", freeSpaceInMB, sz); } sz = stat.f_frsize; if (m_shouldPrint) { - printf("sz = stat.f_bsize; === %lu = %lu;\n", sz, stat.f_bsize); + printf("sz = stat.f_bsize; === %" PRId64 " = %" PRId64 ";\n", sz, stat.f_bsize); } sz *= stat.f_blocks; if (m_shouldPrint) { - printf("sz *= stat.f_blocks; === %lu *= %lu;\n", sz, stat.f_blocks); + printf("sz *= stat.f_blocks; === %" PRIu64 " *= %" PRIu64 ";\n", sz, + stat.f_blocks); } totalCapacityInMB = sz >> 20; if (m_shouldPrint) { - printf("int totalSpaceInMB = sz >> 20; === int %lu = " - "%lu >> 20;\n", totalCapacityInMB, sz); + printf("int totalSpaceInMB = sz >> 20; === int %" PRIu64 " = " + "%" PRIu64 " >> 20;\n", totalCapacityInMB, sz); } return true; } From 9a047e63b3048791a84958644a786447277ac5e6 Mon Sep 17 00:00:00 2001 From: Omkar Mujumdar Date: Tue, 13 Aug 2024 19:56:19 +0530 Subject: [PATCH 11/30] Updated Macros for header file --- includes/constants/EventCallbacks.h | 4 ++-- includes/constants/I2CMessageType.h | 6 +++--- includes/constants/MessageType.h | 6 +++--- includes/constants/StorageState.h | 4 ++-- includes/constants/StorageType.h | 6 +++--- includes/constants/ThreadType.h | 6 +++--- includes/controllers/I2CInterface.h | 6 +++--- includes/models/GenericError.h | 6 +++--- includes/models/I2CError.h | 6 +++--- includes/models/I2CMessage.h | 6 +++--- includes/models/I2CTransactionMessage.h | 6 +++--- includes/models/Message.h | 6 +++--- includes/models/Range.h | 6 +++--- includes/models/StorageMinimalInfo.h | 6 +++--- includes/utils/FileIO.h | 6 +++--- includes/utils/GPIO.h | 6 +++--- includes/utils/I2CBus.h | 6 +++--- includes/utils/Macro.h | 6 +++--- includes/utils/Mutex.h | 6 +++--- includes/utils/PWM.h | 6 +++--- includes/utils/ProcessThread.h | 6 +++--- includes/utils/RealHexParser.h | 6 +++--- includes/utils/ScopeFunction.h | 6 +++--- includes/utils/ScopeLock.h | 6 +++--- includes/utils/StorageUSB.h | 6 +++--- includes/utils/Utils.h | 6 +++--- 26 files changed, 76 insertions(+), 76 deletions(-) diff --git a/includes/constants/EventCallbacks.h b/includes/constants/EventCallbacks.h index e3a6486..3a7c27c 100644 --- a/includes/constants/EventCallbacks.h +++ b/includes/constants/EventCallbacks.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef INCLUDES_CALLBACK_EVENTCALLBACKS_H_ -#define INCLUDES_CALLBACK_EVENTCALLBACKS_H_ +#ifndef INCLUDES_APRA_CALLBACK_EVENTCALLBACKS_H_ +#define INCLUDES_APRA_CALLBACK_EVENTCALLBACKS_H_ namespace apra { diff --git a/includes/constants/I2CMessageType.h b/includes/constants/I2CMessageType.h index 18911ef..60c0cb5 100644 --- a/includes/constants/I2CMessageType.h +++ b/includes/constants/I2CMessageType.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef INCLUDES_CONSTANTS_I2CMESSAGETYPE_H_ -#define INCLUDES_CONSTANTS_I2CMESSAGETYPE_H_ +#ifndef INCLUDES_APRA_CONSTANTS_I2CMESSAGETYPE_H_ +#define INCLUDES_APRA_CONSTANTS_I2CMESSAGETYPE_H_ namespace apra { @@ -18,4 +18,4 @@ enum I2C_MESSAGE_TYPE } /* namespace apra */ -#endif /* INCLUDES_CONSTANTS_I2CMESSAGETYPE_H_ */ +#endif /* INCLUDES_APRA_CONSTANTS_I2CMESSAGETYPE_H_ */ diff --git a/includes/constants/MessageType.h b/includes/constants/MessageType.h index 0fa8922..aa4ac41 100644 --- a/includes/constants/MessageType.h +++ b/includes/constants/MessageType.h @@ -5,12 +5,12 @@ * Author: developer */ -#ifndef INCLUDES_CONSTANTS_MESSAGETYPE_H_ -#define INCLUDES_CONSTANTS_MESSAGETYPE_H_ +#ifndef INCLUDES_APRA_CONSTANTS_MESSAGETYPE_H_ +#define INCLUDES_APRA_CONSTANTS_MESSAGETYPE_H_ enum MESSAGE_TYPE { NO_TYPE, REQUEST_ONLY, REQUEST_RESPONSE }; -#endif /* INCLUDES_CONSTANTS_MESSAGETYPE_H_ */ +#endif /* INCLUDES_APRA_CONSTANTS_MESSAGETYPE_H_ */ diff --git a/includes/constants/StorageState.h b/includes/constants/StorageState.h index b2621af..7e7ca06 100644 --- a/includes/constants/StorageState.h +++ b/includes/constants/StorageState.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef INCLUDES_MODELS_STORAGESTATES_H_ -#define INCLUDES_MODELS_STORAGESTATES_H_ +#ifndef INCLUDES_APRA_MODELS_STORAGESTATES_H_ +#define INCLUDES_APRA_MODELS_STORAGESTATES_H_ namespace apra { diff --git a/includes/constants/StorageType.h b/includes/constants/StorageType.h index b1b1028..03fee5a 100644 --- a/includes/constants/StorageType.h +++ b/includes/constants/StorageType.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef INCLUDES_CONSTANTS_STORAGETYPE_H_ -#define INCLUDES_CONSTANTS_STORAGETYPE_H_ +#ifndef INCLUDES_APRA_CONSTANTS_STORAGETYPE_H_ +#define INCLUDES_APRA_CONSTANTS_STORAGETYPE_H_ #include namespace apra @@ -25,4 +25,4 @@ class STORAGE_TYPE_STRING } /* namespace apra */ -#endif /* INCLUDES_CONSTANTS_STORAGETYPE_H_ */ +#endif /* INCLUDES_APRA_CONSTANTS_STORAGETYPE_H_ */ diff --git a/includes/constants/ThreadType.h b/includes/constants/ThreadType.h index d2d925d..c3306a9 100644 --- a/includes/constants/ThreadType.h +++ b/includes/constants/ThreadType.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef INCLUDES_CONSTANTS_THREADTYPE_H_ -#define INCLUDES_CONSTANTS_THREADTYPE_H_ +#ifndef INCLUDES_APRA_CONSTANTS_THREADTYPE_H_ +#define INCLUDES_APRA_CONSTANTS_THREADTYPE_H_ namespace apra { @@ -16,4 +16,4 @@ enum THREAD_TYPE }; } -#endif /* INCLUDES_CONSTANTS_THREADTYPE_H_ */ +#endif /* INCLUDES_APRA_CONSTANTS_THREADTYPE_H_ */ diff --git a/includes/controllers/I2CInterface.h b/includes/controllers/I2CInterface.h index 250cd7d..7075566 100644 --- a/includes/controllers/I2CInterface.h +++ b/includes/controllers/I2CInterface.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef SRC_CONTROLLERS_I2CINTERFACE_H_ -#define SRC_CONTROLLERS_I2CINTERFACE_H_ +#ifndef SRC_APRA_CONTROLLERS_I2CINTERFACE_H_ +#define SRC_APRA_CONTROLLERS_I2CINTERFACE_H_ #include #include @@ -54,4 +54,4 @@ class I2C_Interface: public ProcessThread } /* namespace apra */ -#endif /* SRC_CONTROLLERS_I2CINTERFACE_H_ */ +#endif /* SRC_APRA_CONTROLLERS_I2CINTERFACE_H_ */ diff --git a/includes/models/GenericError.h b/includes/models/GenericError.h index d1068ec..1aced03 100644 --- a/includes/models/GenericError.h +++ b/includes/models/GenericError.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef INCLUDES_GENERICERROR_H_ -#define INCLUDES_GENERICERROR_H_ +#ifndef INCLUDES_APRA_GENERICERROR_H_ +#define INCLUDES_APRA_GENERICERROR_H_ #include #include @@ -31,4 +31,4 @@ class GenericError } // namespace apra -#endif /* INCLUDES_GENERICERROR_H_ */ +#endif /* INCLUDES_APRA_GENERICERROR_H_ */ diff --git a/includes/models/I2CError.h b/includes/models/I2CError.h index 9788fc5..fac647a 100644 --- a/includes/models/I2CError.h +++ b/includes/models/I2CError.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef INCLUDES_MODELS_I2CERROR_H_ -#define INCLUDES_MODELS_I2CERROR_H_ +#ifndef INCLUDES_APRA_MODELS_I2CERROR_H_ +#define INCLUDES_APRA_MODELS_I2CERROR_H_ #include @@ -38,4 +38,4 @@ class I2CError: public GenericError } /* namespace apra */ -#endif /* INCLUDES_MODELS_I2CERROR_H_ */ +#endif /* INCLUDES_APRA_MODELS_I2CERROR_H_ */ diff --git a/includes/models/I2CMessage.h b/includes/models/I2CMessage.h index 72c2c41..1de19bf 100644 --- a/includes/models/I2CMessage.h +++ b/includes/models/I2CMessage.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef SRC_MODELS_I2CMESSAGE_H_ -#define SRC_MODELS_I2CMESSAGE_H_ +#ifndef SRC_APRA_MODELS_I2CMESSAGE_H_ +#define SRC_APRA_MODELS_I2CMESSAGE_H_ #include #include @@ -57,4 +57,4 @@ class I2C_Message } /* namespace apra */ -#endif /* SRC_MODELS_I2CMESSAGE_H_ */ +#endif /* SRC_APRA_MODELS_I2CMESSAGE_H_ */ diff --git a/includes/models/I2CTransactionMessage.h b/includes/models/I2CTransactionMessage.h index 8df3aed..4e7874a 100644 --- a/includes/models/I2CTransactionMessage.h +++ b/includes/models/I2CTransactionMessage.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef INCLUDES_MODELS_I2CTRANSACTIONMESSAGE_H_ -#define INCLUDES_MODELS_I2CTRANSACTIONMESSAGE_H_ +#ifndef INCLUDES_APRA_MODELS_I2CTRANSACTIONMESSAGE_H_ +#define INCLUDES_APRA_MODELS_I2CTRANSACTIONMESSAGE_H_ #include #include @@ -41,4 +41,4 @@ class I2C_Transaction_Message: public Message } /* namespace apra */ -#endif /* INCLUDES_MODELS_I2CTRANSACTIONMESSAGE_H_ */ +#endif /* INCLUDES_APRA_MODELS_I2CTRANSACTIONMESSAGE_H_ */ diff --git a/includes/models/Message.h b/includes/models/Message.h index 2b5890d..d6729b2 100644 --- a/includes/models/Message.h +++ b/includes/models/Message.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef MESSAGE_H_ -#define MESSAGE_H_ +#ifndef INCLUDES_APRA_MESSAGE_H_ +#define INCLUDES_APRA_MESSAGE_H_ #include #include @@ -34,5 +34,5 @@ class Message }; } -#endif /* MESSAGE_H_ */ +#endif /* INCLUDES_APRA_MESSAGE_H_ */ diff --git a/includes/models/Range.h b/includes/models/Range.h index 89f919f..4ad75ce 100644 --- a/includes/models/Range.h +++ b/includes/models/Range.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef INCLUDES_MODELS_RANGE_H_ -#define INCLUDES_MODELS_RANGE_H_ +#ifndef INCLUDES_APRA_MODELS_RANGE_H_ +#define INCLUDES_APRA_MODELS_RANGE_H_ #include namespace apra @@ -25,4 +25,4 @@ class Range } // namespace apra -#endif /* INCLUDES_MODELS_RANGE_H_ */ +#endif /* INCLUDES_APRA_MODELS_RANGE_H_ */ diff --git a/includes/models/StorageMinimalInfo.h b/includes/models/StorageMinimalInfo.h index 378ed0b..d7d1300 100644 --- a/includes/models/StorageMinimalInfo.h +++ b/includes/models/StorageMinimalInfo.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef INCLUDES_MODELS_STORAGEMINIMALINFO_H_ -#define INCLUDES_MODELS_STORAGEMINIMALINFO_H_ +#ifndef INCLUDES_APRA_MODELS_STORAGEMINIMALINFO_H_ +#define INCLUDES_APRA_MODELS_STORAGEMINIMALINFO_H_ #include namespace apra @@ -27,4 +27,4 @@ class StorageMinimalInfo } /* namespace apra */ -#endif /* INCLUDES_MODELS_STORAGEMINIMALINFO_H_ */ +#endif /* INCLUDES_APRA_MODELS_STORAGEMINIMALINFO_H_ */ diff --git a/includes/utils/FileIO.h b/includes/utils/FileIO.h index d3d3f1f..6a9cde8 100644 --- a/includes/utils/FileIO.h +++ b/includes/utils/FileIO.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef SRC_UTILS_FILEIO_H_ -#define SRC_UTILS_FILEIO_H_ +#ifndef SRC_APRA_UTILS_FILEIO_H_ +#define SRC_APRA_UTILS_FILEIO_H_ #include using namespace std; @@ -24,4 +24,4 @@ class FileIO }; } -#endif /* SRC_UTILS_FILEIO_H_ */ +#endif /* SRC_APRA_UTILS_FILEIO_H_ */ diff --git a/includes/utils/GPIO.h b/includes/utils/GPIO.h index 400696f..faebdb8 100644 --- a/includes/utils/GPIO.h +++ b/includes/utils/GPIO.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef GPIO_H_ -#define GPIO_H_ +#ifndef INCLUDES_APRA_GPIO_H_ +#define INCLUDES_APRA_GPIO_H_ #include #include @@ -49,4 +49,4 @@ class GPIO }; } -#endif /* GPIO_H_ */ +#endif /* INCLUDES_APRA_GPIO_H_ */ diff --git a/includes/utils/I2CBus.h b/includes/utils/I2CBus.h index 443ab3f..c1ecb91 100644 --- a/includes/utils/I2CBus.h +++ b/includes/utils/I2CBus.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef SRC_UTILS_I2CBUS_H_ -#define SRC_UTILS_I2CBUS_H_ +#ifndef SRC_APRA_UTILS_I2CBUS_H_ +#define SRC_APRA_UTILS_I2CBUS_H_ #include #include @@ -47,4 +47,4 @@ class I2C_Bus }; } -#endif /* SRC_UTILS_I2CBUS_H_ */ +#endif /* SRC_APRA_UTILS_I2CBUS_H_ */ diff --git a/includes/utils/Macro.h b/includes/utils/Macro.h index 159b43d..cfab9d0 100644 --- a/includes/utils/Macro.h +++ b/includes/utils/Macro.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef INCLUDES_MACRO_H_ -#define INCLUDES_MACRO_H_ +#ifndef INCLUDES_APRA_MACRO_H_ +#define INCLUDES_APRA_MACRO_H_ #include "ScopeFunction.h" #include @@ -78,4 +78,4 @@ MONOTIMEUS(ret); \ } -#endif /* INCLUDES_MACRO_H_ */ +#endif /* INCLUDES_APRA_MACRO_H_ */ diff --git a/includes/utils/Mutex.h b/includes/utils/Mutex.h index a2a931b..286afab 100644 --- a/includes/utils/Mutex.h +++ b/includes/utils/Mutex.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef SRC_UTILS_MUTEX_H_ -#define SRC_UTILS_MUTEX_H_ +#ifndef SRC_APRA_UTILS_MUTEX_H_ +#define SRC_APRA_UTILS_MUTEX_H_ #include namespace apra @@ -25,4 +25,4 @@ class Mutex }; } /* namespace apra */ -#endif /* SRC_UTILS_MUTEX_H_ */ +#endif /* SRC_APRA_UTILS_MUTEX_H_ */ diff --git a/includes/utils/PWM.h b/includes/utils/PWM.h index d515457..e82226c 100644 --- a/includes/utils/PWM.h +++ b/includes/utils/PWM.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef INCLUDES_UTILS_PWM_H_ -#define INCLUDES_UTILS_PWM_H_ +#ifndef INCLUDES_APRA_UTILS_PWM_H_ +#define INCLUDES_APRA_UTILS_PWM_H_ #include #include @@ -48,4 +48,4 @@ class PWM } /* namespace apra */ -#endif /* INCLUDES_UTILS_PWM_H_ */ +#endif /* INCLUDES_APRA_UTILS_PWM_H_ */ diff --git a/includes/utils/ProcessThread.h b/includes/utils/ProcessThread.h index 26b00d7..a1cbb65 100644 --- a/includes/utils/ProcessThread.h +++ b/includes/utils/ProcessThread.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef PROCESSTHREAD_H_ -#define PROCESSTHREAD_H_ +#ifndef INCLUDES_APRA_PROCESSTHREAD_H_ +#define INCLUDES_APRA_PROCESSTHREAD_H_ #include #include @@ -61,4 +61,4 @@ class ProcessThread }; } -#endif /* PROCESSTHREAD_H_ */ +#endif /* INCLUDES_APRA_PROCESSTHREAD_H_ */ diff --git a/includes/utils/RealHexParser.h b/includes/utils/RealHexParser.h index 9fbc5db..707d53c 100644 --- a/includes/utils/RealHexParser.h +++ b/includes/utils/RealHexParser.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef REALHEXPARSER_H_ -#define REALHEXPARSER_H_ +#ifndef INCLUDES_APRA_REALHEXPARSER_H_ +#define INCLUDES_APRA_REALHEXPARSER_H_ #include namespace apra { @@ -23,4 +23,4 @@ class RealHexParser }; } -#endif /* REALHEXPARSER_H_ */ +#endif /* INCLUDES_APRA_REALHEXPARSER_H_ */ diff --git a/includes/utils/ScopeFunction.h b/includes/utils/ScopeFunction.h index d33a093..240ffa8 100644 --- a/includes/utils/ScopeFunction.h +++ b/includes/utils/ScopeFunction.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef INCLUDES_SCOPEFUNCTION_H_ -#define INCLUDES_SCOPEFUNCTION_H_ +#ifndef INCLUDES_APRA_SCOPEFUNCTION_H_ +#define INCLUDES_APRA_SCOPEFUNCTION_H_ #include namespace apra @@ -21,4 +21,4 @@ class ScopeFunction }; } -#endif /* INCLUDES_SCOPEFUNCTION_H_ */ +#endif /* INCLUDES_APRA_SCOPEFUNCTION_H_ */ diff --git a/includes/utils/ScopeLock.h b/includes/utils/ScopeLock.h index 3ff64a0..8f0b45a 100644 --- a/includes/utils/ScopeLock.h +++ b/includes/utils/ScopeLock.h @@ -1,5 +1,5 @@ -#ifndef SYNCHRONIZATION_H_ -#define SYNCHRONIZATION_H_ +#ifndef INCLUDES_APRA_SYNCHRONIZATION_H_ +#define INCLUDES_APRA_SYNCHRONIZATION_H_ #include #include @@ -19,4 +19,4 @@ class ScopeLock }; } -#endif /* SYNCHRONIZATION_H_ */ +#endif /* INCLUDES_APRA_SYNCHRONIZATION_H_ */ diff --git a/includes/utils/StorageUSB.h b/includes/utils/StorageUSB.h index b3d3fa9..5ffcb18 100644 --- a/includes/utils/StorageUSB.h +++ b/includes/utils/StorageUSB.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef INCLUDES_UTILS_STORAGEUSB_H_ -#define INCLUDES_UTILS_STORAGEUSB_H_ +#ifndef INCLUDES_APRA_UTILS_STORAGEUSB_H_ +#define INCLUDES_APRA_UTILS_STORAGEUSB_H_ #include #include #include @@ -61,4 +61,4 @@ class StorageUSB } /* namespace apra */ -#endif /* INCLUDES_UTILS_STORAGEUSB_H_ */ +#endif /* INCLUDES_APRA_UTILS_STORAGEUSB_H_ */ diff --git a/includes/utils/Utils.h b/includes/utils/Utils.h index 0d890c6..1231ca8 100644 --- a/includes/utils/Utils.h +++ b/includes/utils/Utils.h @@ -5,8 +5,8 @@ * Author: developer */ -#ifndef SRC_UTILS_H_ -#define SRC_UTILS_H_ +#ifndef SRC_APRA_UTILS_H_ +#define SRC_APRA_UTILS_H_ #include #include @@ -48,4 +48,4 @@ class Utils }; } -#endif /* SRC_UTILS_H_ */ +#endif /* SRC_APRA_UTILS_H_ */ From 75dd2bd7880abb6a4c1d72f868704aeb17d3b645 Mon Sep 17 00:00:00 2001 From: Omkar Mujumdar Date: Tue, 13 Aug 2024 19:58:53 +0530 Subject: [PATCH 12/30] Removed NO_TYPE as it was redundent --- includes/constants/MessageType.h | 2 +- src/models/Message.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/constants/MessageType.h b/includes/constants/MessageType.h index aa4ac41..2e351a9 100644 --- a/includes/constants/MessageType.h +++ b/includes/constants/MessageType.h @@ -10,7 +10,7 @@ enum MESSAGE_TYPE { - NO_TYPE, REQUEST_ONLY, REQUEST_RESPONSE + REQUEST_ONLY, REQUEST_RESPONSE }; #endif /* INCLUDES_APRA_CONSTANTS_MESSAGETYPE_H_ */ diff --git a/src/models/Message.cpp b/src/models/Message.cpp index cea27a0..6bc2655 100644 --- a/src/models/Message.cpp +++ b/src/models/Message.cpp @@ -10,7 +10,7 @@ namespace apra { Message::Message() : - m_type(NO_TYPE) + m_type(REQUEST_ONLY) { GTMONOTIMENS(m_handle) } From 687a7e81d87a47a83ead90b9fac3d63a274a9bb9 Mon Sep 17 00:00:00 2001 From: Srishti Karanth Date: Wed, 21 Aug 2024 00:08:24 -0700 Subject: [PATCH 13/30] made changes in eventcallback and added setSize --- includes/constants/EventCallbacks.h | 3 +- includes/models/I2CMessage.h | 1 + includes/models/I2CTransactionMessage.h | 6 +-- src/controllers/I2CInterface.cpp | 62 ++++++++++++++----------- src/models/I2CMessage.cpp | 9 +++- src/models/I2CTransactionMessage.cpp | 12 +++-- 6 files changed, 55 insertions(+), 38 deletions(-) diff --git a/includes/constants/EventCallbacks.h b/includes/constants/EventCallbacks.h index 3a7c27c..1322d8c 100644 --- a/includes/constants/EventCallbacks.h +++ b/includes/constants/EventCallbacks.h @@ -15,6 +15,7 @@ class I2C_Transaction_Message; } // namespace apra -typedef void* I2CEventCallback(void *context, apra::I2C_Transaction_Message message); +typedef void* I2CEventCallback(void *context, + apra::I2C_Transaction_Message message); #endif /* INCLUDES_CALLBACK_EVENTCALLBACKS_H_ */ diff --git a/includes/models/I2CMessage.h b/includes/models/I2CMessage.h index 1de19bf..30bbfa4 100644 --- a/includes/models/I2CMessage.h +++ b/includes/models/I2CMessage.h @@ -39,6 +39,7 @@ class I2C_Message void setRetries(uint64_t retryCount); uint64_t getCombinedData(); uint64_t getCombinedRegister(); + uint64_t getDataSize(); I2CError m_error; I2C_MESSAGE_TYPE m_type; diff --git a/includes/models/I2CTransactionMessage.h b/includes/models/I2CTransactionMessage.h index 4e7874a..2da0869 100644 --- a/includes/models/I2CTransactionMessage.h +++ b/includes/models/I2CTransactionMessage.h @@ -19,7 +19,7 @@ class I2C_Transaction_Message: public Message { public: I2C_Transaction_Message(); - I2C_Transaction_Message(uint8_t chipNumber, + I2C_Transaction_Message(uint16_t chipNumber, vector messageQueue, uint64_t transactionDelayUsec = 0); virtual ~I2C_Transaction_Message(); @@ -27,10 +27,10 @@ class I2C_Transaction_Message: public Message I2CError getError(); void setError(I2CError error); vector& getAllMessages(); - void registerEventHandle(I2CEventCallback *callback, void *context); + void registerEventHandle(void *callback, void *context); void publishTransaction(); I2CError m_error; - uint8_t m_chipNumber; + uint16_t m_chipNumber; bool m_stopOnAnyTransactionFailure; uint64_t m_transactionDelayUsec; vector m_messages; diff --git a/src/controllers/I2CInterface.cpp b/src/controllers/I2CInterface.cpp index ce06e1f..67ebb26 100644 --- a/src/controllers/I2CInterface.cpp +++ b/src/controllers/I2CInterface.cpp @@ -131,6 +131,7 @@ void I2C_Interface::processEvents() processI2CTransaction(&i2cTxMessage); i2cTxMessage.publishTransaction(); } + m_processedEvents.clear(); if (isAnyEventProcessed) { @@ -215,6 +216,8 @@ I2CError I2C_Interface::performRead(uint8_t chipNumber, I2C_Message &message) } { ScopeLock lock(m_processLock); + m_i2cBus.setSize(message.m_registerNumber.size(), + message.getDataSize()); response = m_i2cBus.genericRead(chipNumber, message.m_registerNumber, message.m_data); } @@ -247,6 +250,8 @@ I2CError I2C_Interface::performCompareRead(uint8_t chipNumber, } { ScopeLock lock(m_processLock); + m_i2cBus.setSize(message.m_registerNumber.size(), + message.getDataSize()); response = m_i2cBus.genericRead(chipNumber, message.m_registerNumber, message.m_data); } @@ -269,6 +274,7 @@ I2CError I2C_Interface::performCompareRead(uint8_t chipNumber, message.m_error = response; return response; } + I2CError I2C_Interface::performWrite(uint8_t chipNumber, I2C_Message &message) { I2CError response; @@ -288,6 +294,8 @@ I2CError I2C_Interface::performWrite(uint8_t chipNumber, I2C_Message &message) } { ScopeLock lock(m_processLock); + m_i2cBus.setSize(message.m_registerNumber.size(), + message.m_data.size()); response = m_i2cBus.genericWrite(chipNumber, message.m_registerNumber, message.m_data); } @@ -303,33 +311,33 @@ I2CError I2C_Interface::performWrite(uint8_t chipNumber, I2C_Message &message) void I2C_Interface::processI2CTransaction(I2C_Transaction_Message *txMessage) { I2CError transactionError; - vector i2cMessages = txMessage->getAllMessages(); - for (size_t messageIndex = 0; messageIndex < i2cMessages.size(); + for (size_t messageIndex = 0; messageIndex < txMessage->m_messages.size(); messageIndex++) { I2CError i2cError; - switch (i2cMessages[messageIndex].m_type) + switch (txMessage->m_messages[messageIndex].m_type) { - case I2C_READ: - { - i2cError = performRead(txMessage->m_chipNumber, - i2cMessages[messageIndex]); - break; - } - case I2C_READ_COMPARE_EQUAL: - case I2C_READ_COMPARE_NOT_EQUAL: - { - i2cError = performCompareRead(txMessage->m_chipNumber, - i2cMessages[messageIndex], - i2cMessages[messageIndex].m_type == I2C_READ_COMPARE_EQUAL); - break; - } - case I2C_WRITE: - { - i2cError = performWrite(txMessage->m_chipNumber, - i2cMessages[messageIndex]); - break; - } + case I2C_READ: + { + i2cError = performRead(txMessage->m_chipNumber, + txMessage->m_messages[messageIndex]); + break; + } + case I2C_READ_COMPARE_EQUAL: + case I2C_READ_COMPARE_NOT_EQUAL: + { + i2cError = performCompareRead(txMessage->m_chipNumber, + txMessage->m_messages[messageIndex], + txMessage->m_messages[messageIndex].m_type + == I2C_READ_COMPARE_EQUAL); + break; + } + case I2C_WRITE: + { + i2cError = performWrite(txMessage->m_chipNumber, + txMessage->m_messages[messageIndex]); + break; + } } if (i2cError.isError()) { @@ -339,16 +347,16 @@ void I2C_Interface::processI2CTransaction(I2C_Transaction_Message *txMessage) break; } } - if (i2cMessages[messageIndex].m_delayInUsec) + if (txMessage->m_messages[messageIndex].m_delayInUsec) { - if (i2cMessages[messageIndex].m_allowOtherProcessOnIdle) + if (txMessage->m_messages[messageIndex].m_allowOtherProcessOnIdle) { performTransactionDelay( - i2cMessages[messageIndex].m_delayInUsec); + txMessage->m_messages[messageIndex].m_delayInUsec); } else { - usleep(i2cMessages[messageIndex].m_delayInUsec); + usleep(txMessage->m_messages[messageIndex].m_delayInUsec); } } } diff --git a/src/models/I2CMessage.cpp b/src/models/I2CMessage.cpp index 936902b..5a1bed7 100644 --- a/src/models/I2CMessage.cpp +++ b/src/models/I2CMessage.cpp @@ -73,8 +73,8 @@ void I2C_Message::configureReadWithComparison(vector registerNumber, compareEquals ? I2C_READ_COMPARE_EQUAL : I2C_READ_COMPARE_NOT_EQUAL; } void I2C_Message::configureReadWithComparison(uint64_t registerNumber, - uint64_t registerSize, uint64_t expectedDataSize, const uint64_t dataCompare, - bool compareEquals) + uint64_t registerSize, uint64_t expectedDataSize, + const uint64_t dataCompare, bool compareEquals) { m_registerNumber = Utils::extractBytes(registerNumber, registerSize); m_registerSize = registerSize; @@ -109,4 +109,9 @@ uint64_t I2C_Message::getCombinedRegister() return Utils::combineBytes(m_registerNumber); } +uint64_t I2C_Message::getDataSize() +{ + return m_dataSize; +} + } /* namespace apra */ diff --git a/src/models/I2CTransactionMessage.cpp b/src/models/I2CTransactionMessage.cpp index 867a8a3..be808f1 100644 --- a/src/models/I2CTransactionMessage.cpp +++ b/src/models/I2CTransactionMessage.cpp @@ -6,6 +6,10 @@ */ #include +#include "utils/Macro.h" +#include +#include +#include namespace apra { @@ -17,13 +21,12 @@ I2C_Transaction_Message::I2C_Transaction_Message() : { setType(REQUEST_RESPONSE); } -I2C_Transaction_Message::I2C_Transaction_Message(uint8_t chipNumber, +I2C_Transaction_Message::I2C_Transaction_Message(uint16_t chipNumber, vector messageQueue, uint64_t transactionDelayUsec) : Message(), m_error(), m_chipNumber(chipNumber), m_stopOnAnyTransactionFailure( true), m_transactionDelayUsec(transactionDelayUsec), m_messages( messageQueue), m_callbackContext(NULL), m_callback(NULL) { - // TODO Auto-generated constructor stub setType(REQUEST_RESPONSE); } @@ -62,10 +65,9 @@ vector& I2C_Transaction_Message::getAllMessages() return m_messages; } -void I2C_Transaction_Message::registerEventHandle(I2CEventCallback *callback, - void *context) +void I2C_Transaction_Message::registerEventHandle(void *callback, void *context) { - m_callback = callback; + m_callback = (I2CEventCallback *) (callback); m_callbackContext = context; } From 47ae3ff00da90998ef1ab982433a79abd47c8ec9 Mon Sep 17 00:00:00 2001 From: Srishti Karanth Date: Thu, 6 Nov 2025 23:09:14 -0800 Subject: [PATCH 14/30] added functions for extract and merging of Bytes added operator for range --- includes/ApraUtils.h | 1 - includes/models/Range.h | 1 + includes/utils/StorageUSB.h | 4 ++-- includes/utils/Utils.h | 2 ++ src/models/Range.cpp | 6 ++++++ src/utils/I2CBus.cpp | 21 ++++++++++++++------- src/utils/Utils.cpp | 27 ++++++++++++++++++++++++++- 7 files changed, 51 insertions(+), 11 deletions(-) diff --git a/includes/ApraUtils.h b/includes/ApraUtils.h index 36ad613..34a007b 100644 --- a/includes/ApraUtils.h +++ b/includes/ApraUtils.h @@ -31,7 +31,6 @@ #include "utils/RealHexParser.h" #include "utils/ScopeFunction.h" #include "utils/ScopeLock.h" -#include "utils/StorageUSB.h" #include "utils/Utils.h" #endif /* INCLUDES_APRAUTILS_H_ */ diff --git a/includes/models/Range.h b/includes/models/Range.h index 4ad75ce..35d79dc 100644 --- a/includes/models/Range.h +++ b/includes/models/Range.h @@ -18,6 +18,7 @@ class Range Range(); Range(int64_t min, int64_t max, bool isReversed = false); virtual ~Range(); + Range operator=(const Range &t); int64_t m_min; int64_t m_max; bool m_isReversed; diff --git a/includes/utils/StorageUSB.h b/includes/utils/StorageUSB.h index 5ffcb18..67a8299 100644 --- a/includes/utils/StorageUSB.h +++ b/includes/utils/StorageUSB.h @@ -29,11 +29,11 @@ class StorageUSB bool getStorageInfo(uint64_t &freeSpaceInMB, uint64_t &totalCapacityInMB); STORAGE_STATE getStatus(); std::string getMountPath(); + struct udev_device* getChildDevice(struct udev *udev, + struct udev_device *parent, const char *subsystem); protected: string findMountDeviceBylsblk(string devicePartitionNode); string findMountedDevice(string devicePartitionNode); - struct udev_device* getChildDevice(struct udev *udev, - struct udev_device *parent, const char *subsystem); std::string enumerateDevices(struct udev *udev); std::vector getPartitions(std::string devpath); bool mountDeviceNode(string deviceNode); diff --git a/includes/utils/Utils.h b/includes/utils/Utils.h index 1231ca8..0531178 100644 --- a/includes/utils/Utils.h +++ b/includes/utils/Utils.h @@ -42,6 +42,8 @@ class Utils static double convertFrom10p6(uint16_t value); static uint16_t convertToUFormat(double value, uint8_t format); static double convertFromUFormat(uint16_t value, uint8_t format); + static uint64_t mergefrom8Bytes(uint8_t *bytes); + static void extractTo8Bytes(uint64_t timeInSec, uint8_t *bytes); private: static void getFilesInDirectoryRecursive(const std::string &directoryPath, std::vector &fileList); diff --git a/src/models/Range.cpp b/src/models/Range.cpp index 996cd68..60eca48 100644 --- a/src/models/Range.cpp +++ b/src/models/Range.cpp @@ -25,4 +25,10 @@ Range::~Range() { // TODO Auto-generated destructor stub } +Range Range::operator=(const Range &t) +{ + m_min = t.m_min; + m_max = t.m_max; + return *this; +} diff --git a/src/utils/I2CBus.cpp b/src/utils/I2CBus.cpp index a270efd..40a16db 100644 --- a/src/utils/I2CBus.cpp +++ b/src/utils/I2CBus.cpp @@ -96,14 +96,16 @@ I2CError I2C_Bus::genericWrite(uint8_t chipAddress, debugString += " , 0x"; for (uint32_t count = 0; count < registerAddress.size(); count++) { - char regCh[5] = { 0 }; + char regCh[5] = + { 0}; sprintf(regCh, "%02x", registerAddress[count]); debugString += string(regCh); } debugString += " <--> 0x"; for (uint32_t count = 0; count < data.size(); count++) { - char dataCh[5] = { 0 }; + char dataCh[5] = + { 0}; sprintf(dataCh, "%02x", data[count]); debugString += string(dataCh); } @@ -112,11 +114,13 @@ I2CError I2C_Bus::genericWrite(uint8_t chipAddress, { printf("%s", debugString.c_str()); } - if (ioctl(m_i2cFileDescriptor, I2C_RDWR, &msgset) < 0 && m_shouldPrint) + if (ioctl(m_i2cFileDescriptor, I2C_RDWR, &msgset) < 0) { error = I2CError("ioctl(I2C_RDWR) in i2c_write", debugString, WRITE_ERROR); - perror(error.getMessage().c_str()); + if(m_shouldPrint) + { + perror(error.getMessage().c_str());} } else { @@ -164,16 +168,19 @@ I2CError I2C_Bus::genericRead(uint8_t chipAddress, debugString += " , 0x"; for (uint32_t count = 0; count < registerAddress.size(); count++) { - char regCh[5] = { 0 }; + char regCh[5] = + { 0}; sprintf(regCh, "%02x", registerAddress[count]); debugString += string(regCh); } - if (ioctl(m_i2cFileDescriptor, I2C_RDWR, &msgset) < 0 && m_shouldPrint) + if (ioctl(m_i2cFileDescriptor, I2C_RDWR, &msgset) < 0 ) { debugString += "\n"; error = I2CError("ioctl(I2C_RDWR) in i2c_read", debugString, READ_ERROR); - perror(error.getMessage().c_str()); + if(m_shouldPrint) + { + perror(error.getMessage().c_str());} } else { diff --git a/src/utils/Utils.cpp b/src/utils/Utils.cpp index b9cf883..593a130 100644 --- a/src/utils/Utils.cpp +++ b/src/utils/Utils.cpp @@ -359,7 +359,7 @@ uint16_t Utils::convertToUFormat(double value, uint8_t format) } double Utils::convertFromUFormat(uint16_t value, uint8_t format) { - double returnValue; + double returnValue; double decVal = 0; uint16_t fractionValue = 0; decVal = value >> format; @@ -374,3 +374,28 @@ double Utils::convertFromUFormat(uint16_t value, uint8_t format) returnValue = (decVal + temp); return returnValue; } +uint64_t Utils::mergefrom8Bytes(uint8_t * bytes) +{ + uint64_t response = 0; + if (bytes) + { + for (uint8_t cnt = 0; cnt < 8; cnt++) + { + uint64_t pushValue = bytes[cnt]; + response |= pushValue << (8 * cnt); + } + } + return response; +} + +void Utils::extractTo8Bytes(uint64_t timeInSec, uint8_t *bytes) +{ + if (bytes) + { + for (uint8_t cnt = 0; cnt < 8; cnt++) + { + uint64_t extractedBytes = (timeInSec >> (8 * cnt)); + bytes[cnt] = extractedBytes & 0xFF; + } + } +} From 3d54d110bc1acb68c4292eeaf93e0c440566ec04 Mon Sep 17 00:00:00 2001 From: Omkar Mujumdar Date: Fri, 7 Nov 2025 19:32:13 +0530 Subject: [PATCH 15/30] Update I2CTransactionMessage.h --- includes/models/I2CTransactionMessage.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/models/I2CTransactionMessage.h b/includes/models/I2CTransactionMessage.h index 2da0869..3967c60 100644 --- a/includes/models/I2CTransactionMessage.h +++ b/includes/models/I2CTransactionMessage.h @@ -29,7 +29,6 @@ class I2C_Transaction_Message: public Message vector& getAllMessages(); void registerEventHandle(void *callback, void *context); void publishTransaction(); - I2CError m_error; uint16_t m_chipNumber; bool m_stopOnAnyTransactionFailure; uint64_t m_transactionDelayUsec; @@ -37,6 +36,7 @@ class I2C_Transaction_Message: public Message protected: void *m_callbackContext; I2CEventCallback *m_callback; + I2CError m_error; }; } /* namespace apra */ From 18183820d0a272acb7149fdfb613c1f7c36b381e Mon Sep 17 00:00:00 2001 From: Omkar Mujumdar Date: Fri, 7 Nov 2025 21:07:46 +0530 Subject: [PATCH 16/30] Added Linux platform check and fixed protected member access in I2CInterface - Added platform detection in CMakeLists to restrict builds to Linux only - Fixed I2CInterface.cpp to use setError() method instead of direct protected member access - Resolves compilation error when accessing m_error member --- CMakeLists.txt | 18 ++++++++++++++++++ src/controllers/I2CInterface.cpp | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bb3ab7..48b3113 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,24 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}" ${CMAKE_MODULE_PATH}) project(ApraUtils) +# Platform check - this library is Linux-only +if(NOT UNIX OR APPLE) + message(FATAL_ERROR + "\n" + "========================================================================\n" + " ApraUtils is designed for embedded Linux systems only.\n" + " \n" + " This library requires:\n" + " - Linux kernel headers (I2C, GPIO, PWM)\n" + " - POSIX threads (pthread)\n" + " - Linux-specific system interfaces\n" + " \n" + " Supported platforms: Linux only\n" + " Current platform: ${CMAKE_SYSTEM_NAME}\n" + "========================================================================\n" + ) +endif() + find_package(PkgConfig REQUIRED) include_directories(AFTER SYSTEM include) diff --git a/src/controllers/I2CInterface.cpp b/src/controllers/I2CInterface.cpp index 67ebb26..46201c9 100644 --- a/src/controllers/I2CInterface.cpp +++ b/src/controllers/I2CInterface.cpp @@ -360,7 +360,7 @@ void I2C_Interface::processI2CTransaction(I2C_Transaction_Message *txMessage) } } } - txMessage->m_error = transactionError; + txMessage->setError(transactionError); } void I2C_Interface::performTransactionDelay(const uint64_t timeDelay) From dab50761720e969b2c27a6294d084087bc754426 Mon Sep 17 00:00:00 2001 From: Omkar Mujumdar Date: Fri, 7 Nov 2025 21:19:08 +0530 Subject: [PATCH 17/30] Fixed missing stdexcept include in I2CInterface.cpp - Added missing #include header - Resolves std::invalid_argument compilation error in GitHub Actions --- src/controllers/I2CInterface.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/controllers/I2CInterface.cpp b/src/controllers/I2CInterface.cpp index 46201c9..7876233 100644 --- a/src/controllers/I2CInterface.cpp +++ b/src/controllers/I2CInterface.cpp @@ -6,6 +6,7 @@ */ #include +#include #include "utils/Macro.h" #include "utils/ScopeLock.h" #include "controllers/I2CInterface.h" From 21cfd6acb97f7d4512c7507c34a333fb6f06c1de Mon Sep 17 00:00:00 2001 From: Omkar Mujumdar Date: Fri, 7 Nov 2025 21:22:22 +0530 Subject: [PATCH 18/30] Fixed missing cstdint include in StorageMinimalInfo.h - Added missing #include header for uint64_t type - Resolves uint64_t not declared compilation error in GitHub Actions --- includes/models/StorageMinimalInfo.h | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/models/StorageMinimalInfo.h b/includes/models/StorageMinimalInfo.h index d7d1300..b43d604 100644 --- a/includes/models/StorageMinimalInfo.h +++ b/includes/models/StorageMinimalInfo.h @@ -7,6 +7,7 @@ #ifndef INCLUDES_APRA_MODELS_STORAGEMINIMALINFO_H_ #define INCLUDES_APRA_MODELS_STORAGEMINIMALINFO_H_ +#include #include namespace apra From f811ccbf810f2bd32ffcafdfcbf5dcf2b8031a6c Mon Sep 17 00:00:00 2001 From: Omkar Mujumdar Date: Mon, 10 Nov 2025 11:50:36 +0530 Subject: [PATCH 19/30] Fixed missing time.h include in Macro.h - Added missing #include header for clock_gettime and CLOCK_MONOTONIC - Resolves compilation error in GitHub Actions build pipeline --- includes/utils/Macro.h | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/utils/Macro.h b/includes/utils/Macro.h index cfab9d0..1fff154 100644 --- a/includes/utils/Macro.h +++ b/includes/utils/Macro.h @@ -9,6 +9,7 @@ #define INCLUDES_APRA_MACRO_H_ #include "ScopeFunction.h" +#include #include /* * Timestamp Functions From 85d88e20175957c1a805361d56973b6b1f516d21 Mon Sep 17 00:00:00 2001 From: Omkar Mujumdar Date: Mon, 10 Nov 2025 14:03:08 +0530 Subject: [PATCH 20/30] Complete preparation of ApraUtils for public open-source release under MIT License. - Update all 48 source files with Apra Labs copyright headers - Remove auto-generated TODO comments from codebase - Add comprehensive README.md with badges and documentation - Add CONTRIBUTING.md with development guidelines - Add CODE_OF_CONDUCT.md (Contributor Covenant v2.1) - Add SECURITY.md with vulnerability reporting process - Create 5 comprehensive examples (GPIO, I2C, PWM, USB, Threading) - Add examples documentation and usage guides - Configure Doxygen for API documentation generation - Add GitHub issue templates (bug report, feature request) - Add pull request template with comprehensive checklist - Create CHANGELOG.md following Keep a Changelog format - Add GitHub Pages workflow for automated documentation - Enhance CI/CD with code coverage reporting (lcov) - Create comprehensive packaging guide (deb, rpm, Conan, vcpkg) --- .github/ISSUE_TEMPLATE/bug_report.yml | 136 + .github/ISSUE_TEMPLATE/feature_request.yml | 159 ++ .github/pull_request_template.md | 121 + .github/workflows/c-cpp.yml | 17 +- .github/workflows/documentation.yml | 50 + CHANGELOG.md | 162 ++ CODE_OF_CONDUCT.md | 132 + CONTRIBUTING.md | 453 +++ Doxyfile | 2970 ++++++++++++++++++++ PACKAGING.md | 714 +++++ README.md | 278 ++ examples/README.md | 262 ++ examples/gpio_example.cpp | 267 ++ examples/i2c_example.cpp | 272 ++ examples/pwm_example.cpp | 340 +++ examples/threading_example.cpp | 519 ++++ examples/usb_storage_example.cpp | 406 +++ includes/ApraUtils.h | 8 +- includes/constants/EventCallbacks.h | 8 +- includes/constants/I2CMessageType.h | 8 +- includes/constants/MessageType.h | 8 +- includes/constants/StorageState.h | 8 +- includes/constants/StorageType.h | 8 +- includes/constants/ThreadType.h | 8 +- includes/controllers/I2CInterface.h | 8 +- includes/models/GenericError.h | 8 +- includes/models/I2CError.h | 8 +- includes/models/I2CMessage.h | 8 +- includes/models/I2CTransactionMessage.h | 8 +- includes/models/Message.h | 8 +- includes/models/Range.h | 8 +- includes/models/StorageMinimalInfo.h | 8 +- includes/utils/FileIO.h | 8 +- includes/utils/GPIO.h | 8 +- includes/utils/I2CBus.h | 8 +- includes/utils/Macro.h | 8 +- includes/utils/Mutex.h | 8 +- includes/utils/PWM.h | 8 +- includes/utils/ProcessThread.h | 8 +- includes/utils/RealHexParser.h | 8 +- includes/utils/ScopeFunction.h | 8 +- includes/utils/ScopeLock.h | 11 + includes/utils/StorageUSB.h | 8 +- includes/utils/Utils.h | 8 +- src/constants/StorageType.cpp | 8 +- src/controllers/I2CInterface.cpp | 10 +- src/models/GenericError.cpp | 11 +- src/models/I2CError.cpp | 10 +- src/models/I2CMessage.cpp | 11 +- src/models/I2CTransactionMessage.cpp | 9 +- src/models/Message.cpp | 8 +- src/models/Range.cpp | 11 +- src/models/StorageMinimalInfo.cpp | 11 +- src/utils/FileIO.cpp | 12 +- src/utils/GPIO.cpp | 10 +- src/utils/I2CBus.cpp | 10 +- src/utils/Mutex.cpp | 8 +- src/utils/PWM.cpp | 10 +- src/utils/ProcessThread.cpp | 8 +- src/utils/RealHexParser.cpp | 10 +- src/utils/ScopeFunction.cpp | 10 +- src/utils/ScopeLock.cpp | 8 +- src/utils/StorageUSB.cpp | 10 +- src/utils/Utils.cpp | 10 +- 64 files changed, 7543 insertions(+), 129 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/pull_request_template.md create mode 100644 .github/workflows/documentation.yml create mode 100644 CHANGELOG.md create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 Doxyfile create mode 100644 PACKAGING.md create mode 100644 README.md create mode 100644 examples/README.md create mode 100644 examples/gpio_example.cpp create mode 100644 examples/i2c_example.cpp create mode 100644 examples/pwm_example.cpp create mode 100644 examples/threading_example.cpp create mode 100644 examples/usb_storage_example.cpp diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..d90d5e4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,136 @@ +name: Bug Report +description: File a bug report to help us improve +title: "[Bug]: " +labels: ["bug", "triage"] +assignees: [] + +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! Please provide as much detail as possible. + + - type: textarea + id: description + attributes: + label: Bug Description + description: A clear and concise description of what the bug is. + placeholder: Describe the bug... + validations: + required: true + + - type: textarea + id: steps + attributes: + label: Steps to Reproduce + description: Steps to reproduce the behavior + placeholder: | + 1. Initialize GPIO pin '...' + 2. Call method '...' + 3. See error + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected Behavior + description: What you expected to happen + placeholder: Describe what should happen... + validations: + required: true + + - type: textarea + id: actual + attributes: + label: Actual Behavior + description: What actually happened + placeholder: Describe what actually happened... + validations: + required: true + + - type: input + id: version + attributes: + label: ApraUtils Version + description: What version of ApraUtils are you using? + placeholder: "e.g., 1.0.0 or commit SHA" + validations: + required: true + + - type: dropdown + id: os + attributes: + label: Operating System + description: What OS are you running? + options: + - Ubuntu 22.04 + - Ubuntu 20.04 + - Debian Bullseye + - Raspberry Pi OS + - Other Linux (specify in additional context) + validations: + required: true + + - type: input + id: compiler + attributes: + label: Compiler Version + description: Which C++ compiler and version? + placeholder: "e.g., GCC 11.2, Clang 14.0" + validations: + required: false + + - type: input + id: hardware + attributes: + label: Hardware Platform + description: What hardware are you using? + placeholder: "e.g., Raspberry Pi 4, BeagleBone Black, x86_64" + validations: + required: false + + - type: textarea + id: code + attributes: + label: Code Sample + description: Minimal code to reproduce the issue + placeholder: | + ```cpp + // Your code here + ``` + render: cpp + validations: + required: false + + - type: textarea + id: logs + attributes: + label: Error Messages / Logs + description: Any relevant error messages or logs + placeholder: Paste error output here... + render: shell + validations: + required: false + + - type: textarea + id: context + attributes: + label: Additional Context + description: Any other context about the problem + placeholder: Add any other context, screenshots, or information... + validations: + required: false + + - type: checkboxes + id: terms + attributes: + label: Checklist + description: Please confirm the following + options: + - label: I have searched existing issues to avoid duplicates + required: true + - label: I have provided all required information + required: true + - label: I am using a supported platform (Linux) + required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..e6bd33f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,159 @@ +name: Feature Request +description: Suggest an idea or enhancement for ApraUtils +title: "[Feature]: " +labels: ["enhancement"] +assignees: [] + +body: + - type: markdown + attributes: + value: | + Thanks for suggesting a new feature! Your ideas help make ApraUtils better for everyone. + + - type: textarea + id: problem + attributes: + label: Problem Statement + description: Is your feature request related to a problem? Please describe. + placeholder: "I'm frustrated when..." + validations: + required: true + + - type: textarea + id: solution + attributes: + label: Proposed Solution + description: Describe the solution you'd like + placeholder: "I would like ApraUtils to..." + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives Considered + description: Describe any alternative solutions or features you've considered + placeholder: "Alternative approaches could be..." + validations: + required: false + + - type: dropdown + id: category + attributes: + label: Feature Category + description: Which area does this feature relate to? + options: + - GPIO + - I2C + - PWM + - USB Storage + - Threading + - Error Handling + - Documentation + - Build System + - New Hardware Interface + - Other + validations: + required: true + + - type: dropdown + id: priority + attributes: + label: Priority + description: How important is this feature to you? + options: + - Critical - Blocking my project + - High - Very important + - Medium - Would be nice to have + - Low - Minor enhancement + validations: + required: true + + - type: textarea + id: use-case + attributes: + label: Use Case + description: Describe how you would use this feature + placeholder: | + In my project, I need to... + This feature would allow me to... + validations: + required: true + + - type: textarea + id: example + attributes: + label: Example API / Usage + description: If applicable, show how you envision using this feature + placeholder: | + ```cpp + // Example usage + apra::NewFeature feature; + feature.doSomething(); + ``` + render: cpp + validations: + required: false + + - type: textarea + id: implementation + attributes: + label: Implementation Ideas + description: Do you have ideas about how this could be implemented? + placeholder: "This could be implemented by..." + validations: + required: false + + - type: dropdown + id: breaking + attributes: + label: Breaking Change + description: Would this be a breaking change to existing APIs? + options: + - "No - Backward compatible" + - "Yes - Breaking change required" + - "Not sure" + validations: + required: true + + - type: textarea + id: similar + attributes: + label: Similar Features in Other Libraries + description: Have you seen similar features in other libraries? + placeholder: "Library X has a similar feature that..." + validations: + required: false + + - type: textarea + id: context + attributes: + label: Additional Context + description: Add any other context, diagrams, or screenshots + placeholder: "Additional information..." + validations: + required: false + + - type: checkboxes + id: contribution + attributes: + label: Contribution + description: Are you willing to contribute to this feature? + options: + - label: I am willing to submit a pull request for this feature + required: false + - label: I can help with testing this feature + required: false + - label: I can help with documentation for this feature + required: false + + - type: checkboxes + id: terms + attributes: + label: Checklist + description: Please confirm the following + options: + - label: I have searched existing issues/PRs to avoid duplicates + required: true + - label: This feature aligns with the project's goals (embedded Linux utilities) + required: true diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..5743e06 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,121 @@ +# Pull Request + +## Description + + + +## Type of Change + + + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] Documentation update +- [ ] Code refactoring (no functional changes) +- [ ] Performance improvement +- [ ] Test addition/improvement +- [ ] Build/CI improvement + +## Related Issues + + + +Fixes # +Related to # + +## Changes Made + + + +- +- +- + +## Testing + +### Test Environment + +- **OS**: +- **Hardware**: +- **Compiler**: + +### Testing Performed + + + +- [ ] Unit tests (all passing) +- [ ] Integration tests +- [ ] Manual testing on hardware +- [ ] Tested on multiple platforms +- [ ] Performance testing + +### Test Results + + + +``` +Paste test output here +``` + +## Code Quality + +- [ ] Code follows the project's coding standards +- [ ] Self-review of code performed +- [ ] Comments added for complex or unclear code +- [ ] No new compiler warnings introduced +- [ ] Code is properly formatted + +## Documentation + +- [ ] Updated README.md (if user-facing changes) +- [ ] Updated API documentation / Doxygen comments +- [ ] Updated CONTRIBUTING.md (if development workflow changed) +- [ ] Added/updated examples (if new feature) +- [ ] Updated CHANGELOG.md + +## Breaking Changes + + + +### Impact + + + +### Migration Guide + + + +## Additional Notes + + + +## Checklist + +- [ ] I have read the [CONTRIBUTING.md](../CONTRIBUTING.md) guidelines +- [ ] My code follows the project's coding standards +- [ ] All existing and new tests pass +- [ ] I have added tests for my changes +- [ ] Documentation has been updated +- [ ] No sensitive information (passwords, API keys, etc.) is included +- [ ] Commit messages follow conventional commit format +- [ ] Changes are focused and atomic (one feature/fix per PR) +- [ ] I have rebased on the latest main branch +- [ ] I have resolved any merge conflicts + +## Screenshots (if applicable) + + + +## Performance Impact + + + +- [ ] No performance impact +- [ ] Performance improved +- [ ] Performance may be affected (please explain) + + diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index ba94cb6..1f54ad2 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -15,18 +15,29 @@ jobs: - name: Install dependencies run: | sudo apt-get update - sudo apt-get install -y cmake libudev-dev + sudo apt-get install -y cmake libudev-dev lcov - name: Create build directory run: mkdir -p build - name: Configure run: | cd build - cmake .. + cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="--coverage -fprofile-arcs -ftest-coverage" -DCMAKE_C_FLAGS="--coverage -fprofile-arcs -ftest-coverage" -DCMAKE_EXE_LINKER_FLAGS="--coverage" .. - name: Build run: | cd build make - - name: Publish artifact + - name: Generate coverage report + run: | + cd build + lcov --capture --directory . --output-file coverage.info + lcov --remove coverage.info '/usr/*' '*/test/*' --output-file coverage.info + lcov --list coverage.info + - name: Upload coverage artifact + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: build/coverage.info + - name: Publish library artifact uses: actions/upload-artifact@v4 with: name: libApraUtils diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 0000000..f21d0e4 --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,50 @@ +name: Documentation + +on: + push: + branches: [ "main" ] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Doxygen + run: | + sudo apt-get update + sudo apt-get install -y doxygen graphviz + + - name: Generate documentation + run: | + doxygen Doxyfile + + - name: Setup Pages + uses: actions/configure-pages@v4 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: 'docs/html' + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..efff7dc --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,162 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Planned +- Unit test coverage +- Additional hardware interface support (SPI, UART) +- Package distribution (apt, Conan, vcpkg) +- Performance benchmarking suite +- Comprehensive Doxygen documentation +- Code coverage reporting + +## [1.0.0] - Initial Open Source Release + +### Added +- **Core Hardware Interfaces** + - GPIO control with interrupt support (RISING, FALLING, BOTH edges) + - I2C asynchronous transaction management with error handling + - PWM control with nanosecond precision + - USB storage device detection and management + +- **Utilities** + - ProcessThread for multi-threaded applications with message passing + - Mutex and ScopeLock for thread synchronization + - FileIO utilities for embedded systems + - RealHexParser for numeric conversions + - Utils class with common utility functions + - ScopeFunction for function tracing + - Macro definitions for timing and utilities + +- **Data Models** + - Message and I2CMessage for inter-thread communication + - I2CTransactionMessage for complex I2C operations + - GenericError and I2CError for comprehensive error reporting + - Range for numeric range management + - StorageMinimalInfo for USB storage information + +- **Constants and Enums** + - I2CMessageType (READ, WRITE, READ_COMPARE) + - MessageType (REQUEST_ONLY, REQUEST_RESPONSE) + - ThreadType (FREERUNNING, MESSAGE_AND_FREERUNNING, ONLY_MESSAGE) + - StorageType (FAT32, NTFS, EXT4) + - StorageState (INSERTED, MOUNTED, SAFE_EJECT, UNSAFE_EJECT) + - EventCallbacks for I2C transaction callbacks + +- **Build System** + - CMake build configuration (CMakeLists.txt) + - C++14 standard support + - Static library output (libApraUtils.a) + - GitHub Actions CI/CD pipeline + +- **Documentation** + - Comprehensive README.md with badges and examples + - CONTRIBUTING.md with development guidelines + - CODE_OF_CONDUCT.md (Contributor Covenant v2.1) + - SECURITY.md with vulnerability reporting process + - MIT License + +- **Examples** + - GPIO control examples (gpio_example.cpp) + - I2C communication examples (i2c_example.cpp) + - PWM control examples (pwm_example.cpp) + - USB storage management examples (usb_storage_example.cpp) + - Multi-threading examples (threading_example.cpp) + - Examples README with usage instructions + +- **GitHub Templates** + - Bug report issue template + - Feature request issue template + - Pull request template + +- **API Documentation Setup** + - Doxygen configuration (Doxyfile) + - Source code documentation structure + +### Changed +- Updated all source file headers with Apra Labs copyright +- Standardized author attribution to "Apra Labs" +- Cleaned up auto-generated TODO comments +- Improved code organization and structure + +### Fixed +- Fixed missing platform check in I2CInterface +- Added missing header includes (cstdint, stdexcept, time.h) +- Corrected protected member access in I2CInterface +- Improved error handling in I2C bus operations + +### Platform Support +- **Operating Systems**: Linux (embedded systems focus) +- **Architectures**: ARM, x86, x86_64 +- **Tested On**: Ubuntu 22.04, Raspberry Pi OS +- **Compiler Support**: GCC 5.0+, Clang 3.8+ + +### Dependencies +- pthread (POSIX threads) +- libudev-dev (USB device enumeration) +- Linux kernel headers (I2C, GPIO, PWM interfaces) +- CMake 3.10+ + +### Breaking Changes +- None (initial release) + +### Security +- No known vulnerabilities +- Proper input validation in all public APIs +- Thread-safe operations using provided synchronization primitives + +### Performance +- Asynchronous I2C transactions for non-blocking operations +- Efficient GPIO interrupt handling +- Optimized memory usage with RAII patterns + +### Known Issues +- None currently reported + +### Contributors +- Apra Labs development team + +--- + +## Version History Format + +### [Version] - YYYY-MM-DD + +#### Added +- New features and capabilities + +#### Changed +- Changes to existing functionality + +#### Deprecated +- Soon-to-be removed features + +#### Removed +- Removed features + +#### Fixed +- Bug fixes + +#### Security +- Security fixes and improvements + +--- + +## Links + +- [Repository](https://github.com/Apra-Labs/ApraUtils) +- [Issues](https://github.com/Apra-Labs/ApraUtils/issues) +- [Pull Requests](https://github.com/Apra-Labs/ApraUtils/pulls) +- [Releases](https://github.com/Apra-Labs/ApraUtils/releases) + +--- + +**Note**: This project follows [Semantic Versioning](https://semver.org/): +- MAJOR version for incompatible API changes +- MINOR version for backwards-compatible new functionality +- PATCH version for backwards-compatible bug fixes diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..4197db8 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[contact@apralabs.com](mailto:contact@apralabs.com). +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..9199949 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,453 @@ +# Contributing to ApraUtils + +Thank you for considering contributing to ApraUtils! We welcome contributions from the community and are grateful for your support. + +## Table of Contents + +- [Code of Conduct](#code-of-conduct) +- [How Can I Contribute?](#how-can-i-contribute) + - [Reporting Bugs](#reporting-bugs) + - [Suggesting Enhancements](#suggesting-enhancements) + - [Code Contributions](#code-contributions) +- [Development Setup](#development-setup) +- [Coding Standards](#coding-standards) +- [Commit Message Guidelines](#commit-message-guidelines) +- [Pull Request Process](#pull-request-process) +- [Testing](#testing) +- [Documentation](#documentation) + +## Code of Conduct + +This project and everyone participating in it is governed by our [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to the project maintainers. + +## How Can I Contribute? + +### Reporting Bugs + +Before creating bug reports, please check the [existing issues](https://github.com/Apra-Labs/ApraUtils/issues) to avoid duplicates. + +When creating a bug report, please include: + +- **Clear title and description**: Describe what you expected to happen and what actually happened +- **Steps to reproduce**: Provide specific examples to reproduce the issue +- **Environment details**: + - OS version and distribution (e.g., Ubuntu 22.04, Raspbian Bullseye) + - Compiler version (e.g., GCC 11.2) + - CMake version + - Hardware platform if relevant +- **Code sample**: Minimal reproducible example if possible +- **Error messages**: Complete error output or logs +- **Screenshots**: If applicable + +**Template:** +```markdown +**Description:** +Brief description of the issue + +**Steps to Reproduce:** +1. Step 1 +2. Step 2 +3. ... + +**Expected Behavior:** +What should happen + +**Actual Behavior:** +What actually happens + +**Environment:** +- OS: Ubuntu 22.04 +- Compiler: GCC 11.2 +- CMake: 3.22.1 +- Hardware: Raspberry Pi 4 + +**Additional Context:** +Any other relevant information +``` + +### Suggesting Enhancements + +Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion: + +- **Use a clear and descriptive title** +- **Provide a detailed description** of the proposed functionality +- **Explain why this enhancement would be useful** to most ApraUtils users +- **List any similar features** in other libraries +- **Include code examples** if applicable + +### Code Contributions + +We actively welcome your pull requests! Here's how to contribute code: + +1. Fork the repository +2. Create your feature branch +3. Make your changes +4. Test your changes +5. Commit your changes +6. Push to your fork +7. Submit a pull request + +## Development Setup + +### Prerequisites + +```bash +# Ubuntu/Debian +sudo apt-get update +sudo apt-get install -y build-essential cmake git libudev-dev + +# Additional tools for development +sudo apt-get install -y clang-format clang-tidy doxygen graphviz +``` + +### Setting Up Your Development Environment + +```bash +# 1. Fork and clone the repository +git clone https://github.com/YOUR_USERNAME/ApraUtils.git +cd ApraUtils + +# 2. Add upstream remote +git remote add upstream https://github.com/Apra-Labs/ApraUtils.git + +# 3. Create a development branch +git checkout -b feature/your-feature-name + +# 4. Build the project +mkdir build && cd build +cmake .. +make + +# 5. Make your changes and test +# Edit files... +make +# Run tests... + +# 6. Commit and push +git add . +git commit -m "Add feature: description" +git push origin feature/your-feature-name +``` + +### Keeping Your Fork Updated + +```bash +git fetch upstream +git checkout main +git merge upstream/main +git push origin main +``` + +## Coding Standards + +### C++ Standards + +- **Language Standard**: C++14 +- **Compiler Compatibility**: GCC 5.0+, Clang 3.8+ +- **Platform**: Linux only + +### Code Style + +We follow a consistent coding style to maintain readability: + +#### Naming Conventions + +```cpp +// Namespaces: lowercase +namespace apra { + +// Classes: PascalCase +class ProcessThread { + +// Public member variables: m_ prefix with camelCase +public: + uint64_t m_handle; + +// Private member variables: m_ prefix with camelCase +private: + std::string m_functionName; + +// Methods: camelCase + void processMessage(); + +// Constants: UPPER_CASE +enum THREAD_TYPE { + FREERUNNING, + ONLY_MESSAGE +}; + +// Function parameters: camelCase +void setType(MESSAGE_TYPE messageType); + +} // namespace apra +``` + +#### Formatting + +- **Indentation**: Tabs (as per existing codebase) +- **Braces**: Opening brace on same line for functions, new line for classes +- **Line Length**: Prefer 80-100 characters, max 120 +- **Spaces**: Space after keywords, around operators + +Example: +```cpp +void MyClass::myFunction(int param1, bool param2) +{ + if (param2) + { + doSomething(param1); + } + else + { + doSomethingElse(); + } +} +``` + +#### Header Files + +```cpp +/* + * FileName.h + * + * Copyright (c) 2024 Apra Labs + * + * This file is part of ApraUtils. + * + * Licensed under the MIT License. + * See LICENSE file in the project root for full license information. + */ + +#ifndef INCLUDES_APRA_FILENAME_H_ +#define INCLUDES_APRA_FILENAME_H_ + +// System includes first +#include +#include + +// Local includes second +#include "models/Message.h" + +namespace apra +{ + +class ClassName +{ +public: + ClassName(); + virtual ~ClassName(); + +private: + int m_memberVariable; +}; + +} // namespace apra + +#endif /* INCLUDES_APRA_FILENAME_H_ */ +``` + +### Best Practices + +1. **RAII (Resource Acquisition Is Initialization)**: Use RAII for resource management +2. **Const Correctness**: Use `const` wherever appropriate +3. **Error Handling**: Use the GenericError/I2CError classes for error reporting +4. **Thread Safety**: Use Mutex and ScopeLock for thread-safe operations +5. **Memory Management**: Avoid raw pointers; prefer smart pointers when needed +6. **Comments**: Document complex logic; avoid obvious comments + +```cpp +// Good +// Calculate the average delay between I2C transactions to prevent bus saturation +uint64_t averageDelay = totalDelay / transactionCount; + +// Bad +// Set x to 5 +int x = 5; +``` + +## Commit Message Guidelines + +We follow conventional commit message format: + +### Format + +``` +(): + + + +