diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 2912129..2ed70dc 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -116,6 +116,11 @@
#include "usb_core.h"
#endif
+#ifdef ROCKBOX_HAS_LOGF
+#include "logf.h"
+#include "asyncfile.h"
+#endif
+
/*---------------------------------------------------*/
/* SPECIAL DEBUG STUFF */
/*---------------------------------------------------*/
@@ -2583,6 +2588,32 @@ static bool dbg_scrollwheel(void)
}
#endif
+#ifdef ROCKBOX_HAS_LOGF
+static bool logf_file_output(void)
+{
+ bool old = global_settings.logf_file_output;
+ bool result;
+
+ result = set_bool( "logf file auto output", &global_settings.logf_file_output);
+
+ if(old != global_settings.logf_file_output)
+ {
+ if(!global_settings.logf_file_output)
+ {
+ logf("logf file auto output disabled.");
+ logf_file_close();
+ }
+ logf_file_output_enabled(global_settings.logf_file_output);
+ if(global_settings.logf_file_output)
+ {
+ logf_file_open(LOGF_FILENAME);
+ logf("logf file auto output enabled.");
+ }
+ }
+ return result;
+}
+#endif
+
#if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) && defined(USB_SERIAL)
static bool logf_usb_serial(void)
{
@@ -2727,6 +2758,7 @@ static const struct the_menu_item menuitems[] = {
#ifdef ROCKBOX_HAS_LOGF
{"logf", logfdisplay },
{"logfdump", logfdump },
+ {"logf auto file output", logf_file_output},
#endif
#if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) && defined(USB_SERIAL)
{"logf over usb",logf_usb_serial },
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 6827257..2d5edb0 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -12418,3 +12418,17 @@
speaker: "Enable Speaker"
+
+ id: LANG_LOGF_FILE_OUTPUT
+ desc: logf() is output to the file.
+ user:
+
+ *: "logf auto file output"
+
+
+ *: "logf auto file output"
+
+
+ *: "logf auto file output"
+
+
diff --git a/apps/main.c b/apps/main.c
index 20cec9b..95be6e8 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -116,6 +116,11 @@
#include "system-sdl.h"
#endif
+#ifdef ROCKBOX_HAS_LOGF
+#include "asyncfile.h"
+#include "logf.h"
+#endif
+
/*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
const char appsversion[]=APPSVERSION;
@@ -387,6 +392,10 @@ static void init(void)
show_logo();
lang_init();
+#ifdef ROCKBOX_HAS_LOGF
+ asyncfile_init();
+ logf_file_open(LOGF_FILENAME);
+#endif
#ifdef DEBUG
debug_init();
#else
@@ -522,6 +531,14 @@ static void init(void)
#endif
settings_load(SETTINGS_ALL);
+#ifdef ROCKBOX_HAS_LOGF
+ if(!global_settings.logf_file_output){
+ logf_file_output_enabled(false);
+ clear_logf_buffer();
+ logf_file_close();
+ }
+#endif
+
if (init_dircache(true) < 0)
{
#ifdef HAVE_TAGCACHE
diff --git a/apps/misc.c b/apps/misc.c
index d7a64b3..c9ab767 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -90,6 +90,11 @@
#endif
#endif
+#ifdef ROCKBOX_HAS_LOGF
+#include "asyncfile.h"
+#include "logf.h"
+#endif
+
/* Format a large-range value for output, using the appropriate unit so that
* the displayed value is in the range 1 <= display < 1000 (1024 for "binary"
* units) if possible, and 3 significant digits are shown. If a buffer is
@@ -394,6 +399,11 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter)
dircache_disable();
#endif
+#ifdef ROCKBOX_HAS_LOGF
+ logf_file_close();
+ asyncfile_finalize();
+#endif
+
shutdown_hw();
}
#endif
diff --git a/apps/settings.h b/apps/settings.h
index c376a46..6c4ce30 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -80,6 +80,8 @@ struct opt_items {
#define CONFIGFILE ROCKBOX_DIR "/config.cfg"
#define FIXEDSETTINGSFILE ROCKBOX_DIR "/fixed.cfg"
+#define LOGF_FILENAME ROCKBOX_DIR "/logf.log"
+
#define MAX_FILENAME 32
@@ -226,6 +228,9 @@ enum {
#if CONFIG_CODEC == SWCODEC
SETTINGS_SAVE_EQPRESET,
#endif
+#ifdef ROCKBOX_HAS_LOGF
+ bool logf_file_output;
+#endif
};
bool settings_save_config(int options);
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 2d9be08..9b9d00a 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -1462,6 +1462,10 @@ const struct settings_list settings[] = {
OFFON_SETTING(0, speaker_enabled, LANG_ENABLE_SPEAKER, false, "speaker",
audiohw_enable_speaker),
#endif
+#ifdef ROCKBOX_HAS_LOGF
+ OFFON_SETTING(0, logf_file_output, LANG_LOGF_FILE_OUTPUT,
+ false, "logf file auto output", NULL),
+#endif
};
const int nb_settings = sizeof(settings)/sizeof(*settings);
diff --git a/firmware/SOURCES b/firmware/SOURCES
index d7d2b69..f078775 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -7,6 +7,7 @@ powermgmt.c
system.c
usb.c
#ifdef ROCKBOX_HAS_LOGF
+asyncfile.c
logf.c
#endif /* ROCKBOX_HAS_LOGF */
kernel.c
diff --git a/firmware/export/logf.h b/firmware/export/logf.h
old mode 100644
new mode 100755
index 4926fe5..9dcca27
--- a/firmware/export/logf.h
+++ b/firmware/export/logf.h
@@ -39,6 +39,13 @@
extern unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY+1];
extern int logfindex;
extern bool logfwrap;
+
+int logf_file_open(const char* fname);
+void logf_file_close(void);
+void logf_flush(int wait);
+void clear_logf_buffer(void);
+void logf_file_output_enabled(bool flg);
+
#endif /* __PCTOOL__ */
#define logf _logf
diff --git a/firmware/logf.c b/firmware/logf.c
old mode 100644
new mode 100755
index 75aaf31..ac0aeca
--- a/firmware/logf.c
+++ b/firmware/logf.c
@@ -44,8 +44,10 @@
#include
#include "config.h"
#include "lcd-remote.h"
+#define LOGF_ENABLE
#include "logf.h"
#include "serial.h"
+#include "asyncfile.h"
#ifdef HAVE_USBSTACK
#include "usb_core.h"
@@ -55,6 +57,9 @@
/* Only provide all this if asked to */
#ifdef ROCKBOX_HAS_LOGF
+static int logf_id = -1;
+static bool enabled_logf_file_output = false;
+
#ifndef __PCTOOL__
unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY+1];
int logfindex;
@@ -139,6 +144,8 @@ void _logf(const char *format, ...)
usb_serial_send(buf, len);
usb_serial_send("\r\n", 2);
#endif
+ if(enabled_logf_file_output)
+ async_puts(logf_id, buf);
tlen = 0;
check_logfindex();
@@ -165,6 +172,59 @@ void _logf(const char *format, ...)
displayremote();
}
+
+int logf_file_open(const char *fname)
+{
+ if(logf_id >= 0)
+ {
+ return -1;
+ }
+
+ enabled_logf_file_output = false;
+
+ logf_id = async_open(fname, O_WRONLY | O_CREAT | O_APPEND);
+
+ if(logf_id >= 0)
+ {
+ enabled_logf_file_output = true;
+ logf("logf file %s open.", fname);
+ }
+ return 0;
+}
+
+void logf_file_close(void)
+{
+ if(logf_id >= 0)
+ {
+ logf("logf file close.");
+ enabled_logf_file_output = false;
+ async_close(logf_id);
+ logf_id = -1;
+ }
+}
+
+void logf_flush(int wait)
+{
+ if(logf_id >= 0)
+ {
+ async_flush(logf_id, wait);
+ }
+}
+
+void logf_finalize(void)
+{
+ logf_file_close();
+}
+
+void clear_logf_buffer(void)
+{
+ clear_async_buffer(logf_id);
+}
+
+void logf_file_output_enabled(bool flg)
+{
+ enabled_logf_file_output = flg;
+}
#endif
#endif