1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-20 10:54:14 +01:00

LP-96 - Implement CPU idle counters and calibration functions

This commit is contained in:
Alessio Morale 2015-08-17 16:29:44 +02:00 committed by a*morale
parent d207f848ee
commit 3eaf1ef3c3
4 changed files with 79 additions and 32 deletions

View File

@ -59,6 +59,7 @@
#include <hwsettings.h>
#include <pios_flashfs.h>
#include <pios_notify.h>
#include <pios_task_monitor.h>
#ifdef PIOS_INCLUDE_INSTRUMENTATION
#include <instrumentation.h>
@ -528,7 +529,6 @@ static uint16_t GetFreeIrqStackSize(void)
static void updateStats()
{
SystemStatsData stats;
// Get stats and update
SystemStatsGet(&stats);
stats.FlightTime = xTaskGetTickCount() * portTICK_RATE_MS;
@ -558,7 +558,9 @@ static void updateStats()
stats.UsrSlotsActive = fsStats.num_active_slots;
}
#endif
stats.CPULoad = 100 - PIOS_TASK_MONITOR_GetIdlePercentage();
stats.CPUIdleTicks = PIOS_TASK_MONITOR_GetIdleTicksCount();
stats.CPUZeroLoadTicks = PIOS_TASK_MONITOR_GetZeroLoadTicksCount();
stats.CPULoad = 100 - (uint8_t)((100 * stats.CPUIdleTicks) / stats.CPUZeroLoadTicks);
#if defined(PIOS_INCLUDE_ADC) && defined(PIOS_ADC_USE_TEMP_SENSOR)
float temp_voltage = PIOS_ADC_PinGetVolt(PIOS_ADC_TEMPERATURE_PIN);
@ -642,6 +644,7 @@ static void updateSystemAlarms()
*/
void vApplicationIdleHook(void)
{
PIOS_TASK_MONITOR_IdleHook();
NotificationOnboardLedsRun();
#ifdef PIOS_INCLUDE_WS2811
LedNotificationExtLedsRun();

View File

@ -1,11 +1,12 @@
/**
******************************************************************************
* @addtogroup OpenPilotSystem OpenPilot System
* @addtogroup LibrePilotSystem LibrePilot System
* @{
* @addtogroup OpenPilotLibraries OpenPilot System Libraries
* @addtogroup LibrePilotLibraries LibrePilot System Libraries
* @{
* @file pios_task_monitor.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file pios_task_monitor.c
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2015.
* @brief Task monitoring functions
* @see The GNU Public License (GPL) Version 3
*
@ -36,6 +37,9 @@ static uint32_t mLastMonitorTime;
static uint32_t mLastIdleMonitorTime;
static uint16_t mMaxTasks;
volatile uint32_t idleCounter;
uint32_t zeroLoadIdleCounterPerSec = UINT32_MAX;
volatile bool idleCounterClear;
/**
* Initialize the Task Monitor
*/
@ -149,31 +153,44 @@ void PIOS_TASK_MONITOR_ForEachTask(TaskMonitorTaskInfoCallback callback, void *c
xSemaphoreGiveRecursive(mLock);
}
uint8_t PIOS_TASK_MONITOR_GetIdlePercentage()
{
#if defined(ARCH_POSIX) || defined(ARCH_WIN32)
return 50;
uint32_t ticks = PIOS_TASK_MONITOR_GetIdleTicksCount();
#elif (configGENERATE_RUN_TIME_STATS == 1)
xSemaphoreTakeRecursive(mLock, portMAX_DELAY);
uint32_t currentTime = portGET_RUN_TIME_COUNTER_VALUE();
/* avoid divide-by-zero if the interval is too small */
uint32_t deltaTime = ((currentTime - mLastIdleMonitorTime) / 100) ? : 1;
mLastIdleMonitorTime = currentTime;
uint8_t running_time_percentage = 0;
/* Generate idle time percentage stats */
running_time_percentage = uxTaskGetRunTime(xTaskGetIdleTaskHandle()) / deltaTime;
xSemaphoreGiveRecursive(mLock);
return running_time_percentage;
#else
return 0;
#endif
return (uint8_t)((100 * ticks) / zeroLoadIdleCounterPerSec);
}
uint32_t PIOS_TASK_MONITOR_GetIdleTicksCount()
{
static portTickType lastTickCount = 0;
uint32_t ticks = 0;
portTickType now = xTaskGetTickCount();
if (idleCounterClear) {
idleCounter = 0;
}
if (now > lastTickCount) {
uint32_t dT = (xTaskGetTickCount() - lastTickCount) * portTICK_RATE_MS; // in ms
ticks = (1000 * idleCounter) / dT;
} // else: TickCount has wrapped, do not calc now
lastTickCount = now;
idleCounterClear = true;
return ticks;
}
void PIOS_TASK_MONITOR_CalibrateIdleCounter()
{
idleCounterClear = true;
PIOS_TASK_MONITOR_GetIdleTicksCount();
vTaskDelay(20);
zeroLoadIdleCounterPerSec = PIOS_TASK_MONITOR_GetIdleTicksCount();
}
uint32_t PIOS_TASK_MONITOR_GetZeroLoadTicksCount()
{
return zeroLoadIdleCounterPerSec;
}
#endif // PIOS_INCLUDE_TASK_MONITOR

View File

@ -1,15 +1,17 @@
/**
******************************************************************************
* @addtogroup OpenPilotSystem OpenPilot System
* @addtogroup LibrePilotSystem LibrePilot System
* @{
* @addtogroup OpenPilotLibraries OpenPilot System Libraries
* @addtogroup LibrePilotLibraries LibrePilot System Libraries
* @{
* @file task_monitor.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
* @file pios_task_monitor.h
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2015.
* @brief Task monitoring functions
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -29,7 +31,8 @@
#define PIOS_TASK_MONITOR_H
#include <stdbool.h>
extern volatile uint32_t idleCounter;
extern volatile bool idleCounterClear;
/**
* Initializes the Task Monitor.
*
@ -109,4 +112,26 @@ extern void PIOS_TASK_MONITOR_ForEachTask(TaskMonitorTaskInfoCallback callback,
*/
extern uint8_t PIOS_TASK_MONITOR_GetIdlePercentage();
static inline void PIOS_TASK_MONITOR_IdleHook()
{
if (!idleCounterClear) {
++idleCounter;
} else {
idleCounter = 0;
idleCounterClear = false;
}
}
/**
* Calibrate the idle counter. it should be run with a single task (caller) created
*/
extern void PIOS_TASK_MONITOR_CalibrateIdleCounter();
/**
* return the number of idle hook execution per second
* @return number of idle hook execution per second
*/
extern uint32_t PIOS_TASK_MONITOR_GetIdleTicksCount();
extern uint32_t PIOS_TASK_MONITOR_GetZeroLoadTicksCount();
#endif // PIOS_TASK_MONITOR_H

View File

@ -6,6 +6,8 @@
<field name="IRQStackRemaining" units="bytes" type="uint16" elements="1"/>
<field name="SystemModStackRemaining" units="bytes" type="uint16" elements="1"/>
<field name="CPULoad" units="%" type="uint8" elements="1"/>
<field name="CPUIdleTicks" units="unit" type="uint32" elements="1"/>
<field name="CPUZeroLoadTicks" units="unit" type="uint32" elements="1"/>
<field name="CPUTemp" units="C" type="int8" elements="1"/>
<field name="EventSystemWarningID" units="uavoid" type="uint32" elements="1"/>
<field name="ObjectManagerCallbackID" units="uavoid" type="uint32" elements="1"/>