diff --git a/src/modules/systemlib/print_load_posix.c b/src/modules/systemlib/print_load_posix.c index 0f1ea4da67..5578407da1 100644 --- a/src/modules/systemlib/print_load_posix.c +++ b/src/modules/systemlib/print_load_posix.c @@ -180,3 +180,9 @@ void print_load(uint64_t t, int fd, struct print_load_s *print_state) #endif } +void print_load_buffer(uint64_t t, char *buffer, int buffer_length, print_load_callback_f cb, void *user, + struct print_load_s *print_state) +{ + +} + diff --git a/src/modules/systemlib/printload.c b/src/modules/systemlib/printload.c index 62a27dcf19..b9a672ee32 100644 --- a/src/modules/systemlib/printload.c +++ b/src/modules/systemlib/printload.c @@ -113,20 +113,14 @@ tstate_name(const tstate_t s) } } -void print_load(uint64_t t, int fd, struct print_load_s *print_state) +void print_load_buffer(uint64_t t, char *buffer, int buffer_length, print_load_callback_f cb, void *user, + struct print_load_s *print_state) { print_state->new_time = t; int i; uint64_t curr_time_us; uint64_t idle_time_us; - char *clear_line = ""; - - /* print system information */ - if (fd == 1) { - dprintf(fd, "\033[H"); /* move cursor home and clear screen */ - clear_line = CL; - } curr_time_us = t; idle_time_us = system_load.tasks[0].total_runtime; @@ -239,6 +233,10 @@ void print_load(uint64_t t, int fd, struct print_load_s *print_state) // print output +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat" // NuttX uses a different printf format +#pragma GCC diagnostic ignored "-Wformat-extra-args" + if (tcb_pid == 0) { float idle; float task_load; @@ -255,78 +253,120 @@ void print_load(uint64_t t, int fd, struct print_load_s *print_state) sched_load = 1.f - idle - task_load; - dprintf(fd, "%sProcesses: %d total, %d running, %d sleeping\n", - clear_line, - system_load.total_count, - print_state->running_count, - print_state->blocked_count); - dprintf(fd, "%sCPU usage: %.2f%% tasks, %.2f%% sched, %.2f%% idle\n", - clear_line, - (double)(task_load * 100.f), - (double)(sched_load * 100.f), - (double)(idle * 100.f)); + snprintf(buffer, buffer_length, "Processes: %d total, %d running, %d sleeping", + system_load.total_count, + print_state->running_count, + print_state->blocked_count); + cb(user); + snprintf(buffer, buffer_length, "CPU usage: %.2f%% tasks, %.2f%% sched, %.2f%% idle", + (double)(task_load * 100.f), + (double)(sched_load * 100.f), + (double)(idle * 100.f)); + cb(user); #if defined(BOARD_DMA_ALLOC_POOL_SIZE) uint16_t dma_total; uint16_t dma_used; uint16_t dma_peak_used; if (board_get_dma_usage(&dma_total, &dma_used, &dma_peak_used) >= 0) { - dprintf(fd, "%sDMA Memory: %d total, %d used %d peak\n", - clear_line, - dma_total, - dma_used, - dma_peak_used); + snprintf(buffer, buffer_length, "DMA Memory: %d total, %d used %d peak", + dma_total, + dma_used, + dma_peak_used); + cb(user); } #endif - dprintf(fd, "%sUptime: %.3fs total, %.3fs idle\n%s\n", - clear_line, - (double)curr_time_us / 1000000.d, - (double)idle_time_us / 1000000.d, - clear_line); + snprintf(buffer, buffer_length, "Uptime: %.3fs total, %.3fs idle", + (double)curr_time_us / 1000000.d, + (double)idle_time_us / 1000000.d); + cb(user); + /* header for task list */ - dprintf(fd, "%s%4s %*-s %8s %6s %11s %10s %-6s\n", - clear_line, - "PID", - CONFIG_TASK_NAME_SIZE, "COMMAND", - "CPU(ms)", - "CPU(%)", - "USED/STACK", - "PRIO(BASE)", + snprintf(buffer, buffer_length, "%4s %*-s %8s %6s %11s %10s %-6s", + "PID", + CONFIG_TASK_NAME_SIZE, "COMMAND", + "CPU(ms)", + "CPU(%)", + "USED/STACK", + "PRIO(BASE)", #if CONFIG_RR_INTERVAL > 0 - "TSLICE" + "TSLICE" #else - "STATE" + "STATE" #endif - ); + ); + cb(user); } - dprintf(fd, "%s%4d %*-s %8d %2d.%03d %5u/%5u %3u (%3u) ", - clear_line, - tcb_pid, - CONFIG_TASK_NAME_SIZE, tcb_name, - total_runtime[i], - (int)(current_load * 100.0f), - (int)((current_load * 100.0f - (int)(current_load * 100.0f)) * 1000), - stack_size - stack_free, - stack_size, - tcb_sched_priority, + int print_len = snprintf(buffer, buffer_length, "%4d %*-s %8d %2d.%03d %5u/%5u %3u (%3u) ", + tcb_pid, + CONFIG_TASK_NAME_SIZE, tcb_name, + total_runtime[i], + (int)(current_load * 100.0f), + (int)((current_load * 100.0f - (int)(current_load * 100.0f)) * 1000), + stack_size - stack_free, + stack_size, + tcb_sched_priority, #if CONFIG_ARCH_BOARD_SIM || !defined(CONFIG_PRIORITY_INHERITANCE) - 0); + 0); #else - tcb_base_priority); + tcb_base_priority); #endif - #if CONFIG_RR_INTERVAL > 0 /* print scheduling info with RR time slice */ - dprintf(fd, " %6d\n", tcb_timeslice); + snprintf(buffer + print_len, buffer_length - print_len, " %6d", tcb_timeslice); (void)tstate_name(TSTATE_TASK_INVALID); // Stop not used warning #else // print task state instead - dprintf(fd, " %-6s\n", tstate_name(tcb_task_state)); + snprintf(buffer + print_len, buffer_length - print_len, " %-6s", tstate_name(tcb_task_state)); #endif + cb(user); } print_state->interval_start_time = print_state->new_time; + +#pragma GCC diagnostic pop +} + + +struct print_load_callback_data_s { + int counter; + int fd; + char buffer[140]; +}; + +static void print_load_callback(void *user) +{ + char *clear_line = ""; + struct print_load_callback_data_s *data = (struct print_load_callback_data_s *)user; + + if (data->fd == 1) { + clear_line = CL; + } + + dprintf(data->fd, "%s%s\n", clear_line, data->buffer); + + if (data->counter == 3) { + dprintf(data->fd, "%s\n", clear_line); + } + + ++data->counter; +} + +void print_load(uint64_t t, int fd, struct print_load_s *print_state) +{ + /* print system information */ + if (fd == 1) { + dprintf(fd, "\033[H"); /* move cursor home and clear screen */ + } + + struct print_load_callback_data_s data; + + data.counter = 0; + + data.fd = fd; + + print_load_buffer(t, data.buffer, sizeof(data.buffer), print_load_callback, &data, print_state); } diff --git a/src/modules/systemlib/printload.h b/src/modules/systemlib/printload.h index ca19650509..7ab5cdc2cb 100644 --- a/src/modules/systemlib/printload.h +++ b/src/modules/systemlib/printload.h @@ -67,4 +67,13 @@ __EXPORT void init_print_load_s(uint64_t t, struct print_load_s *s); __EXPORT void print_load(uint64_t t, int fd, struct print_load_s *print_state); + +typedef void (*print_load_callback_f)(void *user); + +/** + * Print load to a buffer, and call cb after each written line (buffer will not include '\n') + */ +void print_load_buffer(uint64_t t, char *buffer, int buffer_length, print_load_callback_f cb, void *user, + struct print_load_s *print_state); + __END_DECLS