2017-11-13 03:19:05 -04:00
|
|
|
#pragma once
|
|
|
|
|
2024-03-07 03:52:58 -04:00
|
|
|
#include "AP_Scheduler_config.h"
|
|
|
|
|
|
|
|
#if AP_SCHEDULER_ENABLED
|
|
|
|
|
2017-11-12 21:47:22 -04:00
|
|
|
#include <stdint.h>
|
2022-04-01 16:57:03 -03:00
|
|
|
#include <AP_Common/ExpandingString.h>
|
2017-11-12 21:47:22 -04:00
|
|
|
|
|
|
|
namespace AP {
|
|
|
|
|
|
|
|
class PerfInfo {
|
|
|
|
public:
|
2017-12-12 21:06:14 -04:00
|
|
|
PerfInfo() {}
|
2017-11-12 21:47:22 -04:00
|
|
|
|
2020-09-04 15:55:45 -03:00
|
|
|
// per-task timing information
|
|
|
|
struct TaskInfo {
|
|
|
|
uint16_t min_time_us;
|
|
|
|
uint16_t max_time_us;
|
|
|
|
uint32_t elapsed_time_us;
|
|
|
|
uint32_t tick_count;
|
|
|
|
uint16_t slip_count;
|
|
|
|
uint16_t overrun_count;
|
2022-04-01 16:57:03 -03:00
|
|
|
|
|
|
|
void update(uint16_t task_time_us, bool overrun);
|
|
|
|
void print(const char* task_name, uint32_t total_time, ExpandingString& str) const;
|
2020-09-04 15:55:45 -03:00
|
|
|
};
|
|
|
|
|
2017-11-12 21:47:22 -04:00
|
|
|
/* Do not allow copies */
|
2022-09-30 06:50:43 -03:00
|
|
|
CLASS_NO_COPY(PerfInfo);
|
2017-11-12 21:47:22 -04:00
|
|
|
|
2017-11-15 23:20:04 -04:00
|
|
|
void reset();
|
2017-11-12 21:47:22 -04:00
|
|
|
void ignore_this_loop();
|
|
|
|
void check_loop_time(uint32_t time_in_micros);
|
|
|
|
uint16_t get_num_loops() const;
|
|
|
|
uint32_t get_max_time() const;
|
|
|
|
uint32_t get_min_time() const;
|
|
|
|
uint16_t get_num_long_running() const;
|
|
|
|
uint32_t get_avg_time() const;
|
|
|
|
uint32_t get_stddev_time() const;
|
2018-02-09 20:48:20 -04:00
|
|
|
float get_filtered_time() const;
|
2022-11-29 23:27:06 -04:00
|
|
|
float get_filtered_loop_rate_hz() const;
|
2018-02-09 20:48:20 -04:00
|
|
|
void set_loop_rate(uint16_t rate_hz);
|
2017-11-12 23:14:50 -04:00
|
|
|
|
2021-02-01 12:26:34 -04:00
|
|
|
void update_logging() const;
|
2017-11-13 04:25:54 -04:00
|
|
|
|
2020-09-04 15:55:45 -03:00
|
|
|
// allocate the array of task statistics for use by @SYS/tasks.txt
|
|
|
|
void allocate_task_info(uint8_t num_tasks);
|
|
|
|
void free_task_info();
|
|
|
|
// whether or not we have task info allocated
|
|
|
|
bool has_task_info() { return _task_info != nullptr; }
|
|
|
|
// return a task info
|
|
|
|
const TaskInfo* get_task_info(uint8_t task_index) const {
|
2022-04-01 16:57:03 -03:00
|
|
|
return (_task_info && task_index < _num_tasks) ? &_task_info[task_index] : nullptr;
|
2020-09-04 15:55:45 -03:00
|
|
|
}
|
|
|
|
// called after each run of a task to update its statistics based on measurements taken by the scheduler
|
|
|
|
void update_task_info(uint8_t task_index, uint16_t task_time_us, bool overrun);
|
|
|
|
// record that a task slipped
|
|
|
|
void task_slipped(uint8_t task_index) {
|
2022-04-01 16:57:03 -03:00
|
|
|
if (_task_info && task_index < _num_tasks) {
|
2020-09-04 15:55:45 -03:00
|
|
|
_task_info[task_index].overrun_count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-12 21:47:22 -04:00
|
|
|
private:
|
2018-02-09 20:48:20 -04:00
|
|
|
uint16_t loop_rate_hz;
|
2017-11-12 23:14:50 -04:00
|
|
|
uint16_t overtime_threshold_micros;
|
2017-11-12 21:47:22 -04:00
|
|
|
uint16_t loop_count;
|
|
|
|
uint32_t max_time; // in microseconds
|
|
|
|
uint32_t min_time; // in microseconds
|
|
|
|
uint64_t sigma_time;
|
|
|
|
uint64_t sigmasquared_time;
|
|
|
|
uint16_t long_running;
|
2018-02-09 21:20:45 -04:00
|
|
|
uint32_t last_check_us;
|
2018-02-09 20:48:20 -04:00
|
|
|
float filtered_loop_time;
|
2017-11-12 21:47:22 -04:00
|
|
|
bool ignore_loop;
|
2020-09-04 15:55:45 -03:00
|
|
|
// performance monitoring
|
|
|
|
uint8_t _num_tasks;
|
|
|
|
TaskInfo* _task_info;
|
2017-11-12 21:47:22 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
};
|
2024-03-07 03:52:58 -04:00
|
|
|
|
|
|
|
#endif // AP_SCHEDULER_ENABLED
|