/** * Called periodically to update the system stats */ static void updateStats() { static portTickType lastTickCount = 0; SystemStatsData stats; // Get stats and update SystemStatsGet(&stats); stats.FlightTime = xTaskGetTickCount() * portTICK_RATE_MS; #if defined(ARCH_POSIX) || defined(ARCH_WIN32) // POSIX port of FreeRTOS doesn't have xPortGetFreeHeapSize() stats.HeapRemaining = 10240; #else stats.HeapRemaining = xPortGetFreeHeapSize(); #endif // Get Irq stack status stats.IRQStackRemaining = GetFreeIrqStackSize(); // When idleCounterClear was not reset by the idle-task, it means the idle-task did not run if (idleCounterClear) { idleCounter = 0; } portTickType now = xTaskGetTickCount(); if (now > lastTickCount) { uint32_t dT = (xTaskGetTickCount() - lastTickCount) * portTICK_RATE_MS; // in ms stats.CPULoad = 100 - (uint8_t) roundf(100.0f * ((float)idleCounter / ((float)dT / 1000.0f)) / (float)IDLE_COUNTS_PER_SEC_AT_NO_LOAD); } //else: TickCount has wrapped, do not calc now lastTickCount = now; idleCounterClear = 1; #if defined(PIOS_INCLUDE_ADC) && defined(PIOS_ADC_USE_TEMP_SENSOR) #if defined(STM32F2XX) || defined(STM32F4XX) // STM32F2XX and STM32F4XX sensor values float temp_voltage = 3.3f * PIOS_ADC_PinGet(5) / ((1 << 12) - 1); const float STM32_TEMP_V25 = 0.76f; /* V */ const float STM32_TEMP_AVG_SLOPE = 2.5f; /* mV/C */ stats.CPUTemp = (temp_voltage-STM32_TEMP_V25) * 1000.0f / STM32_TEMP_AVG_SLOPE + 25.0f; #else float temp_voltage = 3.3f * PIOS_ADC_PinGet(0) / ((1 << 12) - 1); const float STM32_TEMP_V25 = 1.43f; /* V */ const float STM32_TEMP_AVG_SLOPE = 4.3f; /* mV/C */ stats.CPUTemp = (temp_voltage-STM32_TEMP_V25) * 1000.0f / STM32_TEMP_AVG_SLOPE + 25.0f; #endif #endif SystemStatsSet(&stats); }
/** * Called periodically to update the system stats */ static void updateStats() { static uint32_t lastTickCount = 0; SystemStatsData stats; // Get stats and update SystemStatsGet(&stats); stats.FlightTime = PIOS_Thread_Systime(); #if defined(ARCH_POSIX) || defined(ARCH_WIN32) // POSIX port of FreeRTOS doesn't have xPortGetFreeHeapSize() stats.HeapRemaining = 10240; #else stats.HeapRemaining = PIOS_heap_get_free_size(); #endif // Get Irq stack status stats.IRQStackRemaining = GetFreeIrqStackSize(); // When idleCounterClear was not reset by the idle-task, it means the idle-task did not run if (idleCounterClear) { idleCounter = 0; } uint32_t now = PIOS_Thread_Systime(); if (now > lastTickCount) { float dT = (PIOS_Thread_Systime() - lastTickCount) / 1000.0f; // In the case of a slightly miscalibrated max idle count, make sure CPULoad does // not go negative and set an alarm inappropriately. float idleFraction = ((float)idleCounter / dT) / (float)IDLE_COUNTS_PER_SEC_AT_NO_LOAD; if (idleFraction > 1) stats.CPULoad = 0; else stats.CPULoad = 100 - roundf(100.0f * idleFraction); } //else: TickCount has wrapped, do not calc now lastTickCount = now; idleCounterClear = 1; #if defined(PIOS_INCLUDE_ADC) && defined(PIOS_ADC_USE_TEMP_SENSOR) float temp_voltage = 3.3 * PIOS_ADC_DevicePinGet(PIOS_INTERNAL_ADC, 0) / ((1 << 12) - 1); const float STM32_TEMP_V25 = 1.43; /* V */ const float STM32_TEMP_AVG_SLOPE = 4.3; /* mV/C */ stats.CPUTemp = (temp_voltage-STM32_TEMP_V25) * 1000 / STM32_TEMP_AVG_SLOPE + 25; #endif SystemStatsSet(&stats); }
/** * Update system alarms */ static void updateSystemAlarms() { SystemStatsData stats; UAVObjStats objStats; EventStats evStats; SystemStatsGet(&stats); // Check heap, IRQ stack and malloc failures if (PIOS_heap_malloc_failed_p() || (stats.HeapRemaining < HEAP_LIMIT_CRITICAL) #if !defined(ARCH_POSIX) && !defined(ARCH_WIN32) && defined(CHECK_IRQ_STACK) || (stats.IRQStackRemaining < IRQSTACK_LIMIT_CRITICAL) #endif ) { AlarmsSet(SYSTEMALARMS_ALARM_OUTOFMEMORY, SYSTEMALARMS_ALARM_CRITICAL); } else if ( (stats.HeapRemaining < HEAP_LIMIT_WARNING) #if !defined(ARCH_POSIX) && !defined(ARCH_WIN32) && defined(CHECK_IRQ_STACK) || (stats.IRQStackRemaining < IRQSTACK_LIMIT_WARNING) #endif ) { AlarmsSet(SYSTEMALARMS_ALARM_OUTOFMEMORY, SYSTEMALARMS_ALARM_WARNING); } else { AlarmsClear(SYSTEMALARMS_ALARM_OUTOFMEMORY); } // Check CPU load if (stats.CPULoad > CPULOAD_LIMIT_CRITICAL) { AlarmsSet(SYSTEMALARMS_ALARM_CPUOVERLOAD, SYSTEMALARMS_ALARM_CRITICAL); } else if (stats.CPULoad > CPULOAD_LIMIT_WARNING) { AlarmsSet(SYSTEMALARMS_ALARM_CPUOVERLOAD, SYSTEMALARMS_ALARM_WARNING); } else { AlarmsClear(SYSTEMALARMS_ALARM_CPUOVERLOAD); } // Check for stack overflow if (stackOverflow) { AlarmsSet(SYSTEMALARMS_ALARM_STACKOVERFLOW, SYSTEMALARMS_ALARM_CRITICAL); } else { AlarmsClear(SYSTEMALARMS_ALARM_STACKOVERFLOW); } // Check for event errors UAVObjGetStats(&objStats); EventGetStats(&evStats); UAVObjClearStats(); EventClearStats(); if (objStats.eventCallbackErrors > 0 || objStats.eventQueueErrors > 0 || evStats.eventErrors > 0) { AlarmsSet(SYSTEMALARMS_ALARM_EVENTSYSTEM, SYSTEMALARMS_ALARM_WARNING); } else { AlarmsClear(SYSTEMALARMS_ALARM_EVENTSYSTEM); } if (objStats.lastCallbackErrorID || objStats.lastQueueErrorID || evStats.lastErrorID) { SystemStatsData sysStats; SystemStatsGet(&sysStats); sysStats.EventSystemWarningID = evStats.lastErrorID; sysStats.ObjectManagerCallbackID = objStats.lastCallbackErrorID; sysStats.ObjectManagerQueueID = objStats.lastQueueErrorID; SystemStatsSet(&sysStats); } }