diff --git a/sbs.conf b/sbs.conf
index 41484140ab5ac591f63ea183b8ea7c535c939177..f78b8b937624b320c55d23c99d1429e8718fb83a 100644
--- a/sbs.conf
+++ b/sbs.conf
@@ -69,6 +69,7 @@ Files:      src/shared/canbus/CanManager.cpp
 Type:       srcfiles
 Files:      src/shared/events/Scheduler.cpp
             src/shared/DMA/DMA.cpp
+            src/shared/diagnostic/CpuMeter.cpp
 
 [i2c]
 Type:       srcfiles
diff --git a/src/entrypoints/anakin-test-dma.cpp b/src/entrypoints/anakin-test-dma.cpp
index e5f4f09d5b50a28b9a4451fadb45396d4da46151..47535649e198417bdb076ed5818c94410fd0b0d8 100644
--- a/src/entrypoints/anakin-test-dma.cpp
+++ b/src/entrypoints/anakin-test-dma.cpp
@@ -24,6 +24,7 @@
 #include <Leds.h>
 #include <boards/AnakinBoard.h>
 #include <diagnostic/Log.h>
+#include <diagnostic/CpuMeter.h>
 
 using namespace miosix;
 
@@ -51,6 +52,7 @@ void fifoQueueSz(void *arg)
                 sLog->logLimitedInt(17, 0, 255, tx1);
                 sLog->logLimitedInt(18, 0, 255, rx1);
                 sLog->logUInt32(19, spi.getFIFOFaultCtr());
+                sLog->logUInt32(20, averageCpuUtilization());
             }
         }
         Thread::sleep(1);
@@ -85,7 +87,7 @@ int main()
             }
         }
     
-        Thread::sleep(10);
+        Thread::sleep(100);
     }
 
     // NOT EXECUTED
diff --git a/src/shared/diagnostic/CpuMeter.cpp b/src/shared/diagnostic/CpuMeter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..437499baaf3874a43936472087395cd668e98f7e
--- /dev/null
+++ b/src/shared/diagnostic/CpuMeter.cpp
@@ -0,0 +1,80 @@
+/* Copyright (c) 2017 Skyward Experimental Rocketry
+ * Author: Federico Terraneo
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <Common.h>
+#include "CpuMeter.h"
+
+using namespace miosix;
+
+const int period=100;
+const int gap=100;
+const int watchdogPeriod=20*period;
+
+static volatile float utilization=0.f;
+static volatile unsigned int update=0;
+
+float averageCpuUtilization()
+{
+    return utilization;
+}
+
+#ifdef ENABLE_CPU_METER
+
+static void cpuMeterThread(void*)
+{
+    for(;;)
+    {
+        long long t1=getTick();
+        delayMs(period);
+        long long t2=getTick();
+        
+        update++;
+        float delta=t2-t1;
+        utilization=100.f*(1.f-static_cast<float>(period)/delta);
+        
+        Thread::sleep(gap);
+    }
+}
+
+static void watchdogThread(void*)
+{
+    for(unsigned int previous=update;;previous=update)
+    {
+        Thread::sleep(watchdogPeriod);
+        if(previous==update) utilization=100.f;
+    }
+}
+
+class CpuMeterLauncher
+{
+public:
+    CpuMeterLauncher()
+    {
+        //Create the cpu meter thread with minimum priority
+        Thread::create(cpuMeterThread,STACK_MIN,0,nullptr);
+        Thread::create(watchdogThread,STACK_MIN,MAIN_PRIORITY,nullptr);
+    }
+};
+
+static CpuMeterLauncher launcher;
+
+#endif //ENABLE_CPU_METER
diff --git a/src/shared/diagnostic/CpuMeter.h b/src/shared/diagnostic/CpuMeter.h
new file mode 100644
index 0000000000000000000000000000000000000000..24f260bdcbd912eb088b7c77bb8de3f313faa85c
--- /dev/null
+++ b/src/shared/diagnostic/CpuMeter.h
@@ -0,0 +1,54 @@
+/* Copyright (c) 2017 Skyward Experimental Rocketry
+ * Author: Federico Terraneo
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef CPU_METER_H
+#define CPU_METER_H
+
+/*
+ * This CPU meter works like this.
+ * It creates a thread with the minimum priority that is (almost) always active
+ * Since the Miosix priority scheduler always runs the thread with the highest
+ * priority, every time other threads (or interrupts) have work to do, they
+ * preempt this thread. By measuring the amount of actual time this thread
+ * takes to perform a busy wait delay it is possible to compute an average CPU
+ * utilization.
+ * 
+ * The advantage of this technique is that it can account for the CPU time
+ * of everything, including interrupts and task context switch overhead.
+ * The disadvantage is that by being (almost) always running it prevents the
+ * idle thread from running and thus it prevents the CPU from going into deep
+ * sleep.
+ * 
+ * NOTE: for this to work, no other thread with the lowest priority has to be
+ * created, otherwise its time will not be accounted.
+ */
+
+/// If defined, the CPU meter is active
+#define ENABLE_CPU_METER
+
+/**
+ * \return the average CPU utilization
+ */
+float averageCpuUtilization();
+
+
+#endif //CPU_METER_H