~aleteoryx/muditaos

9c9e921ab488e73ec57ece6ff93a07624b252162 — Maciej Gibowicz 5 years ago d57f44f
[EGD-4693] PowerManagement: CPU load measurement (#1156)

Add FreeRTOS idle tasks Run Time Statistics

This will allow to measure the CPU load
M changelog.md => changelog.md +1 -0
@@ 12,6 12,7 @@
* `[cellular]` USSD session handling.
* `[settings]` Nightshift window - GUI.
* `[bluetooth][settings]` Add Bluetooth settings to database.
* `[PowerManagement]` Added CPU load measurement.

### Changed


M module-os/FreeRTOS/include/FreeRTOSConfig.h => module-os/FreeRTOS/include/FreeRTOSConfig.h +1 -1
@@ 125,7 125,7 @@ extern uint32_t SystemCoreClock;
#define INCLUDE_xTaskGetCurrentTaskHandle       1
#define INCLUDE_uxTaskGetStackHighWaterMark     1
#define INCLUDE_uxTaskGetStackHighWaterMark2    1
#define INCLUDE_xTaskGetIdleTaskHandle          0
#define INCLUDE_xTaskGetIdleTaskHandle          1
#define INCLUDE_eTaskGetState                   0
#define INCLUDE_xTimerPendFunctionCall          1
#define INCLUDE_xTaskAbortDelay                 0

M module-sys/CMakeLists.txt => module-sys/CMakeLists.txt +1 -0
@@ 12,6 12,7 @@ set(SOURCES
        ${CMAKE_CURRENT_SOURCE_DIR}/Service/Timer.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/SystemManager/SystemManager.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/SystemManager/PowerManager.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/SystemManager/CpuStatistics.cpp

        )


A module-sys/SystemManager/CpuStatistics.cpp => module-sys/SystemManager/CpuStatistics.cpp +45 -0
@@ 0,0 1,45 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "CpuStatistics.hpp"
#include <log/log.hpp>
#include <FreeRTOS.h>
#include <task.h>
#include <limits>

namespace sys
{
    void CpuStatistics::Update()
    {
        uint32_t idleTickCount  = xTaskGetIdleRunTimeCounter();
        uint32_t totalTickCount = ulHighFrequencyTimerTicks();

        uint32_t idleTickIncrease  = ComputeIncrease(idleTickCount, lastIdleTickCount);
        uint32_t totalTickIncrease = ComputeIncrease(totalTickCount, lastTotalTickCount);

        if (totalTickIncrease) {
            cpuLoad = 100 - ((idleTickIncrease * 100) / totalTickIncrease);
        }
        else {
            cpuLoad = 0;
        }

        lastIdleTickCount  = idleTickCount;
        lastTotalTickCount = totalTickCount;
    }

    uint32_t CpuStatistics::GetPercentageCpuLoad() const noexcept
    {
        return cpuLoad;
    }

    uint32_t CpuStatistics::ComputeIncrease(uint32_t currentCount, uint32_t lastCount) const
    {
        if (currentCount >= lastCount) {
            return currentCount - lastCount;
        }
        else {
            return std::numeric_limits<uint32_t>::max() - lastCount + currentCount;
        }
    }
} // namespace sys

A module-sys/SystemManager/CpuStatistics.hpp => module-sys/SystemManager/CpuStatistics.hpp +26 -0
@@ 0,0 1,26 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <cstdint>

namespace sys
{

    class CpuStatistics
    {

      public:
        void Update();
        [[nodiscard]] uint32_t GetPercentageCpuLoad() const noexcept;

      private:
        uint32_t ComputeIncrease(uint32_t currentCount, uint32_t lastCount) const;

        uint32_t lastIdleTickCount{0};
        uint32_t lastTotalTickCount{0};
        uint32_t cpuLoad{0};
    };

} // namespace sys

M module-sys/SystemManager/SystemManager.cpp => module-sys/SystemManager/SystemManager.cpp +13 -1
@@ 11,6 11,7 @@
#include <service-evtmgr/KbdMessage.hpp>
#include <service-evtmgr/BatteryMessages.hpp>
#include <service-evtmgr/Constants.hpp>
#include <Service/Timer.hpp>

const inline size_t systemManagerStack = 4096 * 2;



@@ 94,8 95,9 @@ namespace sys

    void SystemManager::StartSystem(InitFunction init)
    {

        powerManager = std::make_unique<PowerManager>();
        cpuStatistics = std::make_unique<CpuStatistics>();

        // Switch system to full functionality(clocks and power domains configured to max values)
        powerManager->Switch(PowerManager::Mode::FullSpeed);
        userInit = init;


@@ 106,6 108,10 @@ namespace sys
        // M.P: Ping/pong mechanism is turned off. It doesn't bring any value to the system.
        // pingPongTimerID = CreateTimer(Ticks::MsToTicks(pingInterval), true);
        // ReloadTimer(pingPongTimerID);

        cpuStatisticsTimer = std::make_unique<sys::Timer>("cpuStatistics", this, 1000);
        cpuStatisticsTimer->connect([&](sys::Timer &) { CpuStatisticsTimerHandler(); });
        cpuStatisticsTimer->start();
    }

    bool SystemManager::CloseSystem(Service *s)


@@ 348,8 354,14 @@ namespace sys
        set(State::Reboot);
    }

    void SystemManager::CpuStatisticsTimerHandler()
    {
        cpuStatistics->Update();
    }

    std::vector<std::shared_ptr<Service>> SystemManager::servicesList;
    cpp_freertos::MutexStandard SystemManager::destroyMutex;
    std::unique_ptr<PowerManager> SystemManager::powerManager;
    std::unique_ptr<CpuStatistics> SystemManager::cpuStatistics;

} // namespace sys

M module-sys/SystemManager/SystemManager.hpp => module-sys/SystemManager/SystemManager.hpp +7 -0
@@ 21,6 21,7 @@
#include "Service/Message.hpp"
#include "PowerManager.hpp"
#include "Constants.hpp"
#include "CpuStatistics.hpp"

namespace sys
{


@@ 124,14 125,20 @@ namespace sys
        /// red key won't work to power it on. For more information follow up with schematics
        bool PreShutdownLoop();

        /// periodic update of cpu statistics
        void CpuStatisticsTimerHandler();

        TickType_t pingInterval;
        uint32_t pingPongTimerID;

        InitFunction userInit;

        std::unique_ptr<sys::Timer> cpuStatisticsTimer;

        static std::vector<std::shared_ptr<Service>> servicesList;
        static cpp_freertos::MutexStandard destroyMutex;
        static std::unique_ptr<PowerManager> powerManager;
        static std::unique_ptr<CpuStatistics> cpuStatistics;
    };

} // namespace sys