From 7135168ba549d8d73d9e31aff1e41b04c4ae0b33 Mon Sep 17 00:00:00 2001 From: Federico Terraneo <fede.tft@miosix.org> Date: Sun, 14 May 2017 16:17:43 +0200 Subject: [PATCH] Added CPU meter --- sbs.conf | 1 + src/entrypoints/anakin-test-dma.cpp | 4 +- src/shared/diagnostic/CpuMeter.cpp | 80 +++++++++++++++++++++++++++++ src/shared/diagnostic/CpuMeter.h | 54 +++++++++++++++++++ 4 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 src/shared/diagnostic/CpuMeter.cpp create mode 100644 src/shared/diagnostic/CpuMeter.h diff --git a/sbs.conf b/sbs.conf index 41484140a..f78b8b937 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 e5f4f09d5..47535649e 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 000000000..437499baa --- /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 000000000..24f260bdc --- /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 -- GitLab