logger: convert to use ModuleBase

This commit is contained in:
Beat Küng
2017-07-14 11:57:11 +02:00
parent 5bdbfa9b5c
commit 7361244359
2 changed files with 111 additions and 147 deletions
+90 -136
View File
@@ -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
View File
@@ -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;