mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-16 00:53:34 +08:00
logger: convert to use ModuleBase
This commit is contained in:
+90
-136
@@ -89,9 +89,6 @@
|
||||
|
||||
using namespace px4::logger;
|
||||
|
||||
static Logger *logger_ptr = nullptr;
|
||||
static int logger_task = -1;
|
||||
|
||||
/* This is used to schedule work for the logger (periodic scan for updated topics) */
|
||||
static void timer_callback(void *arg)
|
||||
{
|
||||
@@ -110,75 +107,7 @@ int logger_main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc < 2) {
|
||||
PX4_INFO("usage: logger {start|stop|status}");
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Check if thread exited, but the object has not been destroyed yet (happens in case of an error)
|
||||
if (logger_task == -1 && logger_ptr) {
|
||||
delete logger_ptr;
|
||||
logger_ptr = nullptr;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "start")) {
|
||||
|
||||
if (logger_ptr != nullptr) {
|
||||
PX4_INFO("already running");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (OK != Logger::start((char *const *)argv)) {
|
||||
PX4_WARN("start failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "on")) {
|
||||
if (logger_ptr != nullptr) {
|
||||
logger_ptr->set_arm_override(true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "off")) {
|
||||
if (logger_ptr != nullptr) {
|
||||
logger_ptr->set_arm_override(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "stop")) {
|
||||
if (logger_ptr == nullptr) {
|
||||
PX4_INFO("not running");
|
||||
return 1;
|
||||
}
|
||||
|
||||
logger_ptr->print_statistics();
|
||||
delete logger_ptr;
|
||||
logger_ptr = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "status")) {
|
||||
if (logger_ptr) {
|
||||
logger_ptr->status();
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
PX4_INFO("not running");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
Logger::usage("unrecognized command");
|
||||
return 1;
|
||||
return Logger::main(argc, argv);
|
||||
}
|
||||
|
||||
namespace px4
|
||||
@@ -186,46 +115,92 @@ namespace px4
|
||||
namespace logger
|
||||
{
|
||||
|
||||
void Logger::usage(const char *reason)
|
||||
int Logger::custom_command(int argc, char *argv[])
|
||||
{
|
||||
if (!is_running()) {
|
||||
print_usage("logger not running");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0], "on")) {
|
||||
get_instance()->set_arm_override(true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0], "off")) {
|
||||
get_instance()->set_arm_override(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return print_usage("unknown command");
|
||||
}
|
||||
|
||||
int Logger::print_usage(const char *reason)
|
||||
{
|
||||
if (reason) {
|
||||
PX4_WARN("%s\n", reason);
|
||||
}
|
||||
|
||||
PX4_INFO("usage: logger {start|stop|on|off|status} [-r <log rate>] [-b <buffer size>]\n"
|
||||
" [-p <topic>] -e -a -t -x -m <mode> -q <size>\n"
|
||||
"\t-r\tLog rate in Hz, 0 means unlimited rate\n"
|
||||
"\t-p\tPoll on a topic instead of running with fixed rate (Log rate and topic interval are ignored if this is set)\n"
|
||||
"\t-b\tLog buffer size in KiB, default is 12\n"
|
||||
"\t-e\tEnable logging right after start until disarm (otherwise only when armed)\n"
|
||||
"\t-f\tLog until shutdown (implies -e)\n"
|
||||
"\t-t\tUse date/time for naming log directories and files\n"
|
||||
"\t-m\tMode: one of 'file', 'mavlink', 'all' (default=all)\n"
|
||||
"\t-q\tuORB queue size for mavlink mode");
|
||||
PRINT_MODULE_DESCRIPTION(
|
||||
R"DESCR_STR(
|
||||
System logger which logs a (configurable) set of uORB topics and system printf messages
|
||||
(warnings and errors) to ULog files. These can be used for system and flight performance evaluation,
|
||||
tuning, replay and crash analysis.
|
||||
|
||||
It supports 2 backends:
|
||||
- Files: write ULog files to the file system (SD card)
|
||||
- MAVLink: stream ULog data via MAVLink to a client (the client must support this)
|
||||
Both backends can be enabled and used at the same time.
|
||||
|
||||
The implementation uses two threads:
|
||||
- The main thread, running at a fixed rate (or polling on a topic if started with -p) and checking for
|
||||
data updates
|
||||
- The writer thread, writing data to the file
|
||||
In between there is a write buffer with configurable size. It should be large to avoid dropouts.
|
||||
|
||||
Typical usage to start logging immediately:
|
||||
$ logger start -e -t
|
||||
|
||||
Or if already running:
|
||||
$ logger on
|
||||
)DESCR_STR");
|
||||
|
||||
PRINT_MODULE_USAGE_NAME("logger", "system");
|
||||
PRINT_MODULE_USAGE_COMMAND("start");
|
||||
PRINT_MODULE_USAGE_PARAM_STRING('m', "all", "file|mavlink|all", "Backend mode", true);
|
||||
PRINT_MODULE_USAGE_PARAM_FLAG('e', "Enable logging right after start until disarm (otherwise only when armed)", true);
|
||||
PRINT_MODULE_USAGE_PARAM_FLAG('f', "Log until shutdown (implies -e)", true);
|
||||
PRINT_MODULE_USAGE_PARAM_FLAG('t', "Use date/time for naming log directories and files", true);
|
||||
PRINT_MODULE_USAGE_PARAM_INT('r', 280, 0, 8000, "Log rate in Hz, 0 means unlimited rate", true);
|
||||
PRINT_MODULE_USAGE_PARAM_INT('b', 12, 4, 10000, "Log buffer size in KiB", true);
|
||||
PRINT_MODULE_USAGE_PARAM_INT('q', 14, 1, 100, "uORB queue size for mavlink mode", true);
|
||||
PRINT_MODULE_USAGE_PARAM_STRING('p', nullptr, "<topic_name>",
|
||||
"Poll on a topic instead of running with fixed rate (Log rate and topic intervals are ignored if this is set)", true);
|
||||
PRINT_MODULE_USAGE_COMMAND_DESCR("on", "start logging now, override arming (logger must be running)");
|
||||
PRINT_MODULE_USAGE_COMMAND_DESCR("off", "stop logging now, override arming (logger must be running)");
|
||||
PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Logger::start(char *const *argv)
|
||||
int Logger::task_spawn(int argc, char *argv[])
|
||||
{
|
||||
ASSERT(logger_task == -1);
|
||||
_task_id = px4_task_spawn_cmd("logger",
|
||||
SCHED_DEFAULT,
|
||||
SCHED_PRIORITY_MAX - 10,
|
||||
3600,
|
||||
(px4_main_t)&run_trampoline,
|
||||
(char *const *)argv);
|
||||
|
||||
/* start the task */
|
||||
logger_task = px4_task_spawn_cmd("logger",
|
||||
SCHED_DEFAULT,
|
||||
SCHED_PRIORITY_MAX - 10,
|
||||
3600,
|
||||
(px4_main_t)&Logger::run_trampoline,
|
||||
(char *const *)argv);
|
||||
|
||||
if (logger_task < 0) {
|
||||
logger_task = -1;
|
||||
PX4_WARN("task start failed");
|
||||
if (_task_id < 0) {
|
||||
_task_id = -1;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Logger::status()
|
||||
int Logger::print_status()
|
||||
{
|
||||
PX4_INFO("Running in mode: %s", configured_backend_mode());
|
||||
|
||||
@@ -237,6 +212,8 @@ void Logger::status()
|
||||
if (_writer.is_started(LogWriter::BackendMavlink)) {
|
||||
PX4_INFO("Mavlink Logging Running");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Logger::print_statistics()
|
||||
@@ -259,7 +236,7 @@ void Logger::print_statistics()
|
||||
_max_dropout_duration = 0.f;
|
||||
}
|
||||
|
||||
void Logger::run_trampoline(int argc, char *argv[])
|
||||
Logger *Logger::instanciate(int argc, char *argv[])
|
||||
{
|
||||
uint32_t log_interval = 3500;
|
||||
int log_buffer_size = 12 * 1024;
|
||||
@@ -355,12 +332,11 @@ void Logger::run_trampoline(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (error_flag) {
|
||||
logger_task = -1;
|
||||
return;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
logger_ptr = new Logger(backend, log_buffer_size, log_interval, poll_topic, log_on_start,
|
||||
log_until_shutdown, log_name_timestamp, queue_size);
|
||||
Logger *logger = new Logger(backend, log_buffer_size, log_interval, poll_topic, log_on_start,
|
||||
log_until_shutdown, log_name_timestamp, queue_size);
|
||||
|
||||
#if defined(DBGPRINT) && defined(__PX4_NUTTX)
|
||||
struct mallinfo alloc_info = mallinfo();
|
||||
@@ -368,7 +344,7 @@ void Logger::run_trampoline(int argc, char *argv[])
|
||||
PX4_INFO("remaining free heap: %d bytes", alloc_info.fordblks);
|
||||
#endif /* DBGPRINT */
|
||||
|
||||
if (logger_ptr == nullptr) {
|
||||
if (logger == nullptr) {
|
||||
PX4_ERR("alloc failed");
|
||||
|
||||
} else {
|
||||
@@ -377,15 +353,14 @@ void Logger::run_trampoline(int argc, char *argv[])
|
||||
const char *logfile = getenv(px4::replay::ENV_FILENAME);
|
||||
|
||||
if (logfile) {
|
||||
logger_ptr->setReplayFile(logfile);
|
||||
logger->setReplayFile(logfile);
|
||||
}
|
||||
|
||||
#endif /* __PX4_NUTTX */
|
||||
|
||||
logger_ptr->run();
|
||||
}
|
||||
|
||||
logger_task = -1;
|
||||
return logger;
|
||||
}
|
||||
|
||||
|
||||
@@ -420,26 +395,6 @@ Logger::Logger(LogWriter::Backend backend, size_t buffer_size, uint32_t log_inte
|
||||
|
||||
Logger::~Logger()
|
||||
{
|
||||
if (logger_task != -1) {
|
||||
/* task wakes up every 100ms or so at the longest */
|
||||
_task_should_exit = true;
|
||||
|
||||
/* wait for a second for the task to quit at our request */
|
||||
unsigned int i = 0;
|
||||
|
||||
do {
|
||||
/* wait 20ms */
|
||||
usleep(20000);
|
||||
|
||||
/* if we have given up, kill it */
|
||||
if (++i > 200) {
|
||||
px4_task_delete(logger_task);
|
||||
logger_task = -1;
|
||||
break;
|
||||
}
|
||||
} while (logger_task != -1);
|
||||
}
|
||||
|
||||
if (_replay_file_name) {
|
||||
free(_replay_file_name);
|
||||
}
|
||||
@@ -449,13 +404,14 @@ Logger::~Logger()
|
||||
}
|
||||
}
|
||||
|
||||
bool Logger::request_stop()
|
||||
bool Logger::request_stop_static()
|
||||
{
|
||||
if (logger_ptr) {
|
||||
logger_ptr->_task_should_exit = true;
|
||||
if (is_running()) {
|
||||
get_instance()->request_stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
return logger_task == -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
int Logger::add_topic(const orb_metadata *topic)
|
||||
@@ -819,14 +775,12 @@ void Logger::run()
|
||||
return;
|
||||
}
|
||||
|
||||
_task_should_exit = false;
|
||||
|
||||
#ifdef DBGPRINT
|
||||
hrt_abstime timer_start = 0;
|
||||
uint32_t total_bytes = 0;
|
||||
#endif /* DBGPRINT */
|
||||
|
||||
px4_register_shutdown_hook(&Logger::request_stop);
|
||||
px4_register_shutdown_hook(&Logger::request_stop_static);
|
||||
|
||||
// we start logging immediately
|
||||
// the case where we wait with logging until vehicle is armed is handled below
|
||||
@@ -859,7 +813,7 @@ void Logger::run()
|
||||
hrt_abstime next_subscribe_check = 0;
|
||||
int next_subscribe_topic_index = -1; // this is used to distribute the checks over time
|
||||
|
||||
while (!_task_should_exit) {
|
||||
while (!should_exit()) {
|
||||
|
||||
// Start/stop logging when system arm/disarm
|
||||
bool vehicle_status_updated;
|
||||
@@ -1134,7 +1088,7 @@ void Logger::run()
|
||||
orb_unsubscribe(vehicle_command_sub);
|
||||
}
|
||||
|
||||
px4_unregister_shutdown_hook(&Logger::request_stop);
|
||||
px4_unregister_shutdown_hook(&Logger::request_stop_static);
|
||||
}
|
||||
|
||||
bool Logger::write_message(void *ptr, size_t size)
|
||||
|
||||
+21
-11
@@ -41,6 +41,7 @@
|
||||
#include <version/version.h>
|
||||
#include <systemlib/param/param.h>
|
||||
#include <systemlib/printload.h>
|
||||
#include <px4_module.h>
|
||||
|
||||
extern "C" __EXPORT int logger_main(int argc, char *argv[]);
|
||||
|
||||
@@ -87,7 +88,7 @@ struct LoggerSubscription {
|
||||
}
|
||||
};
|
||||
|
||||
class Logger
|
||||
class Logger : public ModuleBase<Logger>
|
||||
{
|
||||
public:
|
||||
Logger(LogWriter::Backend backend, size_t buffer_size, uint32_t log_interval, const char *poll_topic_name,
|
||||
@@ -95,6 +96,24 @@ public:
|
||||
|
||||
~Logger();
|
||||
|
||||
/** @see ModuleBase */
|
||||
static int task_spawn(int argc, char *argv[]);
|
||||
|
||||
/** @see ModuleBase */
|
||||
static Logger *instanciate(int argc, char *argv[]);
|
||||
|
||||
/** @see ModuleBase */
|
||||
static int custom_command(int argc, char *argv[]);
|
||||
|
||||
/** @see ModuleBase */
|
||||
static int print_usage(const char *reason = nullptr);
|
||||
|
||||
/** @see ModuleBase::run() */
|
||||
void run() override;
|
||||
|
||||
/** @see ModuleBase::print_status() */
|
||||
int print_status() override;
|
||||
|
||||
/**
|
||||
* Tell the logger that we're in replay mode. This must be called
|
||||
* before starting the logger.
|
||||
@@ -116,25 +135,17 @@ public:
|
||||
*/
|
||||
int add_topic(const orb_metadata *topic);
|
||||
|
||||
static int start(char *const *argv);
|
||||
|
||||
/**
|
||||
* request the logger thread to stop (this method does not block).
|
||||
* @return true if the logger is stopped, false if (still) running
|
||||
*/
|
||||
static bool request_stop();
|
||||
static bool request_stop_static();
|
||||
|
||||
static void usage(const char *reason);
|
||||
|
||||
void status();
|
||||
void print_statistics();
|
||||
|
||||
void set_arm_override(bool override) { _arm_override = override; }
|
||||
|
||||
private:
|
||||
static void run_trampoline(int argc, char *argv[]);
|
||||
|
||||
void run();
|
||||
|
||||
/**
|
||||
* Write an ADD_LOGGED_MSG to the log for a all current subscriptions and instances
|
||||
@@ -284,7 +295,6 @@ private:
|
||||
char _log_dir[LOG_DIR_LEN];
|
||||
int _sess_dir_index = 1; ///< search starting index for 'sess<i>' directory name
|
||||
char _log_file_name[32];
|
||||
bool _task_should_exit = true;
|
||||
bool _has_log_dir = false;
|
||||
bool _was_armed = false;
|
||||
bool _arm_override;
|
||||
|
||||
Reference in New Issue
Block a user