44 #include <px4_platform_common/px4_config.h> 45 #include <px4_platform_common/defines.h> 46 #include <px4_platform_common/module.h> 47 #include <px4_platform_common/module_params.h> 48 #include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp> 55 #if defined(__PX4_NUTTX) && !defined(CONFIG_SCHED_INSTRUMENTATION) 56 # error load_mon support requires CONFIG_SCHED_INSTRUMENTATION 59 #define STACK_LOW_WARNING_THRESHOLD 300 60 #define FDS_LOW_WARNING_THRESHOLD 3
70 class LoadMon :
public ModuleBase<LoadMon>,
public ModuleParams,
public px4::ScheduledWorkItem
85 static int print_usage(
const char *reason =
nullptr);
106 int _stack_task_index{0};
111 (ParamBool<px4::params::SYS_STCK_EN>) _param_sys_stck_en
123 ModuleParams(nullptr),
124 ScheduledWorkItem(MODULE_NAME,
px4::wq_configurations::lp_default),
141 PX4_ERR(
"alloc failed");
146 _task_id = task_id_is_work_queue;
157 ScheduleOnInterval(LOAD_MON_INTERVAL_US);
166 if (_param_sys_stck_en.get()) {
191 _last_idle_time = total_runtime;
195 cpuload.
load = 1.0f - (float)interval_idletime / (
float)interval;
207 #ifdef CONFIG_CAN_PASS_STRUCTS 210 (void)mallinfo(&mem);
218 return (
float)mem.uordblks / mem.arena;
226 void LoadMon::_stack_usage()
231 const int num_tasks_per_cycle = 2;
233 for (
int i = _stack_task_index; i < _stack_task_index + num_tasks_per_cycle; i++) {
235 unsigned stack_free = 0;
237 bool checked_task =
false;
246 stack_free = up_check_tcbstack_remain(
system_load.tasks[task_index].tcb);
248 static_assert(
sizeof(task_stack_info.
task_name) == CONFIG_TASK_NAME_SIZE,
249 "task_stack_info.task_name must match NuttX CONFIG_TASK_NAME_SIZE");
250 strncpy((
char *)task_stack_info.
task_name,
system_load.tasks[task_index].tcb->name, CONFIG_TASK_NAME_SIZE - 1);
251 task_stack_info.
task_name[CONFIG_TASK_NAME_SIZE - 1] =
'\0';
253 #if CONFIG_NFILE_DESCRIPTORS > 0 254 FAR
struct task_group_s *group =
system_load.tasks[task_index].tcb->group;
256 unsigned tcb_num_used_fds = 0;
259 for (
int fd_index = 0; fd_index < CONFIG_NFILE_DESCRIPTORS; ++fd_index) {
260 if (group->tg_filelist.fl_files[fd_index].f_inode) {
265 fds_free = CONFIG_NFILE_DESCRIPTORS - tcb_num_used_fds;
268 #endif // CONFIG_NFILE_DESCRIPTORS 281 _task_stack_info_pub.publish(task_stack_info);
287 PX4_WARN(
"%s low on stack! (%i bytes left)", task_stack_info.
task_name, stack_free);
295 PX4_WARN(
"%s low on FDs! (%i FDs left)", task_stack_info.
task_name, fds_free);
306 _stack_task_index = task_index + 1;
320 PX4_ERR(
"%s\n", reason);
323 PRINT_MODULE_DESCRIPTION(
326 Background process running periodically with 1 Hz on the LP work queue to calculate the CPU load and RAM 327 usage and publish the `cpuload` topic. 329 On NuttX it also checks the stack usage of each process and if it falls below 300 bytes, a warning is output, 330 which will also appear in the log file. 333 PRINT_MODULE_USAGE_NAME("load_mon",
"system");
334 PRINT_MODULE_USAGE_COMMAND_DESCR(
"start",
"Start the background task");
335 PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
Queued publication with queue length set as a message constant (ORB_QUEUE_LENGTH) ...
measure the time elapsed performing an event
int main(int argc, char **argv)
const unsigned LOAD_MON_INTERVAL_US
void Run() override
Do a compute and schedule the next cycle.
High-resolution timer with callouts and timekeeping.
int print_status() override
Base publication wrapper class.
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
static int custom_command(int argc, char *argv[])
DEFINE_PARAMETERS((ParamBool< px4::params::SYS_STCK_EN >) _param_sys_stck_en) uORB hrt_abstime _last_idle_time
void perf_free(perf_counter_t handle)
Free a counter.
hrt_abstime _last_idle_time_sample
static int task_spawn(int argc, char *argv[])
static hrt_abstime hrt_elapsed_time(const hrt_abstime *then)
Compute the delta between a timestamp taken in the past and now.
void perf_end(perf_counter_t handle)
End a performance event.
float _ram_used()
Calculate the memory usage.
__EXPORT int load_mon_main(int argc, char *argv[])
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units.
#define FDS_LOW_WARNING_THRESHOLD
if free file descriptors fall below this, print a warning
struct system_load_s system_load
perf_counter_t _stack_perf
void perf_print_counter(perf_counter_t handle)
Print one performance counter to stdout.
static struct cpuload_s cpuload
void _cpuload()
Do a calculation of the CPU load and publish it.
static int print_usage(const char *reason=nullptr)
#define STACK_LOW_WARNING_THRESHOLD
if free stack space falls below this, print a warning
void perf_begin(perf_counter_t handle)
Begin a performance event.
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
Performance measuring tools.