From 1f1ecd07b00989d5eb9b11d85a545ded8158789b Mon Sep 17 00:00:00 2001
From: Matteo Pignataro <matteo.pignataro@skywarder.eu>
Date: Wed, 13 Mar 2024 18:13:51 +0000
Subject: [PATCH] [Sensor] Added mutex for synchronization purposes

---
 src/shared/sensors/Sensor.h                   | 23 +++++++++++++++++--
 .../analog/test-analog-pressure-sensors.cpp   |  4 ++--
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/src/shared/sensors/Sensor.h b/src/shared/sensors/Sensor.h
index 5cba9b216..1b5e83bd0 100644
--- a/src/shared/sensors/Sensor.h
+++ b/src/shared/sensors/Sensor.h
@@ -22,6 +22,8 @@
 
 #pragma once
 
+#include <miosix.h>
+
 #include <array>
 #include <type_traits>
 
@@ -97,15 +99,32 @@ protected:
      */
     virtual Data sampleImpl() = 0;
 
+    // Thread safe mutex to synchronize writes and reads
+    miosix::FastMutex mutex;
+
 public:
     virtual ~Sensor() {}
 
-    void sample() override { lastSample = sampleImpl(); }
+    void sample() override
+    {
+        // Sampling outside of the protected zone ensures that the sampling
+        // action cannot cause locks or delays
+        Data d = sampleImpl();
+
+        {
+            miosix::Lock<miosix::FastMutex> l(mutex);
+            lastSample = d;
+        }
+    }
 
     /**
      * @return last available sample from this sensor
      */
-    virtual const Data& getLastSample() { return lastSample; }
+    virtual const Data& getLastSample()
+    {
+        miosix::Lock<miosix::FastMutex> l(mutex);
+        return lastSample;
+    }
 };
 
 /**
diff --git a/src/tests/sensors/analog/test-analog-pressure-sensors.cpp b/src/tests/sensors/analog/test-analog-pressure-sensors.cpp
index 98cc37b3a..d64e113db 100644
--- a/src/tests/sensors/analog/test-analog-pressure-sensors.cpp
+++ b/src/tests/sensors/analog/test-analog-pressure-sensors.cpp
@@ -73,14 +73,14 @@ int main()
     ADS1118 ads1118(spiSlave);
 
     std::function<ADCData()> getVoltageFunction =
-        std::bind(&ADS1118::getVoltage, ads1118, channel1);
+        std::bind(&ADS1118::getVoltage, std::ref(ads1118), channel1);
     HSCMAND015PA analogSensor(getVoltageFunction);
 
     analogSensor.init();
     analogSensor.selfTest();
 
     std::function<ADCData()> getVoltageFunction2 =
-        std::bind(&ADS1118::getVoltage, ads1118, channel2);
+        std::bind(&ADS1118::getVoltage, std::ref(ads1118), channel2);
     HSCMRNN030PA analogSensor2(getVoltageFunction2);
 
     analogSensor2.init();
-- 
GitLab