diff options
-rw-r--r-- | apps/logfdisp.c | 58 | ||||
-rw-r--r-- | firmware/export/logf.h | 10 | ||||
-rw-r--r-- | firmware/logf.c | 58 |
3 files changed, 105 insertions, 21 deletions
diff --git a/apps/logfdisp.c b/apps/logfdisp.c index bfe37bc3fb..d55b3ba773 100644 --- a/apps/logfdisp.c +++ b/apps/logfdisp.c | |||
@@ -62,8 +62,8 @@ bool logfdisplay(void) | |||
62 | #endif | 62 | #endif |
63 | :LCD_WIDTH)/w; | 63 | :LCD_WIDTH)/w; |
64 | 64 | ||
65 | if (columns > MAX_LOGF_ENTRY) | 65 | if (columns > MAX_LOGF_ENTRY+1) |
66 | columns = MAX_LOGF_ENTRY; | 66 | columns = MAX_LOGF_ENTRY+1; |
67 | 67 | ||
68 | if(!lines) | 68 | if(!lines) |
69 | return false; | 69 | return false; |
@@ -83,7 +83,12 @@ bool logfdisplay(void) | |||
83 | } | 83 | } |
84 | 84 | ||
85 | memcpy(buffer, logfbuffer[index], columns); | 85 | memcpy(buffer, logfbuffer[index], columns); |
86 | buffer[columns]=0; | 86 | if (logfbuffer[index][MAX_LOGF_ENTRY] == LOGF_TERMINATE_CONTINUE_LINE) |
87 | buffer[columns-1] = '>'; | ||
88 | else if (logfbuffer[index][MAX_LOGF_ENTRY] == LOGF_TERMINATE_MULTI_LINE) | ||
89 | buffer[columns-1] = '\0'; | ||
90 | buffer[columns] = '\0'; | ||
91 | |||
87 | lcd_puts(0, i, buffer); | 92 | lcd_puts(0, i, buffer); |
88 | } | 93 | } |
89 | lcd_update(); | 94 | lcd_update(); |
@@ -113,24 +118,61 @@ bool logfdump(void) | |||
113 | 118 | ||
114 | fd = open(ROCKBOX_DIR "/logf.txt", O_CREAT|O_WRONLY|O_TRUNC); | 119 | fd = open(ROCKBOX_DIR "/logf.txt", O_CREAT|O_WRONLY|O_TRUNC); |
115 | if(-1 != fd) { | 120 | if(-1 != fd) { |
116 | unsigned char buffer[MAX_LOGF_ENTRY +1]; | 121 | unsigned char buffer[MAX_LOGF_ONE_LINE_SIZE +1]; |
122 | unsigned char *ptr; | ||
117 | int index = logfindex-1; | 123 | int index = logfindex-1; |
118 | int stop = logfindex; | 124 | int stop = logfindex; |
125 | int tindex; | ||
126 | bool dumpwrap = false; | ||
127 | bool multiline; | ||
119 | 128 | ||
120 | 129 | while(!dumpwrap || (index >= stop)) { | |
121 | while(index != stop) { | ||
122 | if(index < 0) { | 130 | if(index < 0) { |
123 | if(logfwrap) | 131 | if(logfwrap) |
132 | { | ||
124 | index = MAX_LOGF_LINES-1; | 133 | index = MAX_LOGF_LINES-1; |
134 | dumpwrap = true; | ||
135 | } | ||
125 | else | 136 | else |
126 | break; /* done */ | 137 | break; /* done */ |
127 | } | 138 | } |
139 | |||
140 | multiline = false; | ||
141 | if (logfbuffer[index][MAX_LOGF_ENTRY] == LOGF_TERMINATE_MULTI_LINE) | ||
142 | { | ||
143 | multiline = true; | ||
144 | do { | ||
145 | index--; | ||
146 | if(index < 0) { | ||
147 | if(logfwrap) | ||
148 | { | ||
149 | index = MAX_LOGF_LINES-1; | ||
150 | dumpwrap = true; | ||
151 | } | ||
152 | else | ||
153 | goto end_loop; | ||
154 | } | ||
155 | } while(logfbuffer[index][MAX_LOGF_ENTRY] == LOGF_TERMINATE_CONTINUE_LINE); | ||
156 | index++; | ||
157 | if (index >= MAX_LOGF_LINES) | ||
158 | index = 0; | ||
159 | } | ||
160 | |||
161 | tindex = index-1; | ||
162 | ptr = buffer; | ||
163 | do { | ||
164 | tindex++; | ||
165 | memcpy(ptr, logfbuffer[tindex], MAX_LOGF_ENTRY); | ||
166 | ptr += MAX_LOGF_ENTRY; | ||
167 | if (tindex >= MAX_LOGF_LINES) | ||
168 | tindex = 0; | ||
169 | } while(logfbuffer[tindex][MAX_LOGF_ENTRY] == LOGF_TERMINATE_CONTINUE_LINE); | ||
170 | *ptr = '\0'; | ||
128 | 171 | ||
129 | memcpy(buffer, logfbuffer[index], MAX_LOGF_ENTRY); | ||
130 | buffer[MAX_LOGF_ENTRY]=0; | ||
131 | fdprintf(fd, "%s\n", buffer); | 172 | fdprintf(fd, "%s\n", buffer); |
132 | index--; | 173 | index--; |
133 | } | 174 | } |
175 | end_loop: | ||
134 | close(fd); | 176 | close(fd); |
135 | } | 177 | } |
136 | return false; | 178 | return false; |
diff --git a/firmware/export/logf.h b/firmware/export/logf.h index d3644b5985..4926fe5ef2 100644 --- a/firmware/export/logf.h +++ b/firmware/export/logf.h | |||
@@ -29,10 +29,14 @@ | |||
29 | 29 | ||
30 | #ifndef __PCTOOL__ | 30 | #ifndef __PCTOOL__ |
31 | #define MAX_LOGF_LINES 1000 | 31 | #define MAX_LOGF_LINES 1000 |
32 | #define MAX_LOGF_ENTRY 30 | 32 | #define MAX_LOGF_ENTRY 29 |
33 | #define MAX_LOGF_DATASIZE (MAX_LOGF_ENTRY*MAX_LOGF_LINES) | 33 | #define MAX_LOGF_ONE_LINE_SIZE 200 |
34 | 34 | ||
35 | extern unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY]; | 35 | #define LOGF_TERMINATE_ONE_LINE 0x00 |
36 | #define LOGF_TERMINATE_CONTINUE_LINE 0x01 | ||
37 | #define LOGF_TERMINATE_MULTI_LINE 0x02 | ||
38 | |||
39 | extern unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY+1]; | ||
36 | extern int logfindex; | 40 | extern int logfindex; |
37 | extern bool logfwrap; | 41 | extern bool logfwrap; |
38 | #endif /* __PCTOOL__ */ | 42 | #endif /* __PCTOOL__ */ |
diff --git a/firmware/logf.c b/firmware/logf.c index 9599547907..539c2af9da 100644 --- a/firmware/logf.c +++ b/firmware/logf.c | |||
@@ -20,10 +20,23 @@ | |||
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | /* | 22 | /* |
23 | * logf() logs MAX_LOGF_ENTRY (21) bytes per entry in a circular buffer. Each | 23 | * logf() logs MAX_LOGF_ENTRY (29) bytes per entry in a circular buffer. Each |
24 | * logged string is space- padded for easier and faster output on screen. Just | 24 | * logged string is space- padded for easier and faster output on screen. Just |
25 | * output MAX_LOGF_ENTRY characters on each line. MAX_LOGF_ENTRY bytes fit | 25 | * output MAX_LOGF_ENTRY characters on each line. MAX_LOGF_ENTRY bytes fit |
26 | * nicely on the iRiver remote LCD (128 pixels with an 8x6 pixels font). | 26 | * nicely on the iRiver remote LCD (128 pixels with an 8x6 pixels font). |
27 | * | ||
28 | * When the length of log exceeds MAX_LOGF_ENTRY bytes, dividing into the | ||
29 | * string of length is MAX_LOGF_ENTRY-1 bytes. | ||
30 | * | ||
31 | * logfbuffer[*]: | ||
32 | * | ||
33 | * |<- MAX_LOGF_ENTRY bytes ->|1| | ||
34 | * | log data area |T| | ||
35 | * | ||
36 | * T : log terminate flag | ||
37 | * == LOGF_TERMINATE_ONE_LINE(0x00) : log data end (one line) | ||
38 | * == LOGF_TERMINATE_CONTINUE_LINE(0x01) : log data continues | ||
39 | * == LOGF_TERMINATE_MULTI_LINE(0x02) : log data end (multi line) | ||
27 | */ | 40 | */ |
28 | 41 | ||
29 | #include <string.h> | 42 | #include <string.h> |
@@ -43,7 +56,7 @@ | |||
43 | #ifdef ROCKBOX_HAS_LOGF | 56 | #ifdef ROCKBOX_HAS_LOGF |
44 | 57 | ||
45 | #ifndef __PCTOOL__ | 58 | #ifndef __PCTOOL__ |
46 | unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY]; | 59 | unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY+1]; |
47 | int logfindex; | 60 | int logfindex; |
48 | bool logfwrap; | 61 | bool logfwrap; |
49 | #endif | 62 | #endif |
@@ -84,6 +97,15 @@ static void displayremote(void) | |||
84 | #define displayremote() | 97 | #define displayremote() |
85 | #endif | 98 | #endif |
86 | 99 | ||
100 | static void check_logfindex(void) | ||
101 | { | ||
102 | if(logfindex >= MAX_LOGF_LINES) { | ||
103 | /* wrap */ | ||
104 | logfwrap = true; | ||
105 | logfindex = 0; | ||
106 | } | ||
107 | } | ||
108 | |||
87 | #ifdef __PCTOOL__ | 109 | #ifdef __PCTOOL__ |
88 | void _logf(const char *format, ...) | 110 | void _logf(const char *format, ...) |
89 | { | 111 | { |
@@ -98,17 +120,17 @@ void _logf(const char *format, ...) | |||
98 | void _logf(const char *format, ...) | 120 | void _logf(const char *format, ...) |
99 | { | 121 | { |
100 | int len; | 122 | int len; |
123 | int tlen; | ||
124 | unsigned char buf[MAX_LOGF_ONE_LINE_SIZE]; | ||
101 | unsigned char *ptr; | 125 | unsigned char *ptr; |
102 | va_list ap; | 126 | va_list ap; |
127 | bool multiline = false; | ||
128 | |||
103 | va_start(ap, format); | 129 | va_start(ap, format); |
130 | vsnprintf(buf, MAX_LOGF_ONE_LINE_SIZE, format, ap); | ||
131 | va_end(ap); | ||
104 | 132 | ||
105 | if(logfindex >= MAX_LOGF_LINES) { | 133 | len = strlen(buf); |
106 | /* wrap */ | ||
107 | logfwrap = true; | ||
108 | logfindex = 0; | ||
109 | } | ||
110 | ptr = logfbuffer[logfindex]; | ||
111 | len = vsnprintf(ptr, MAX_LOGF_ENTRY, format, ap); | ||
112 | #ifdef HAVE_SERIAL | 134 | #ifdef HAVE_SERIAL |
113 | serial_tx(ptr); | 135 | serial_tx(ptr); |
114 | serial_tx("\r\n"); | 136 | serial_tx("\r\n"); |
@@ -118,10 +140,26 @@ void _logf(const char *format, ...) | |||
118 | usb_serial_send("\r\n",2); | 140 | usb_serial_send("\r\n",2); |
119 | #endif | 141 | #endif |
120 | 142 | ||
121 | va_end(ap); | 143 | tlen = 0; |
144 | check_logfindex(); | ||
145 | while(len > MAX_LOGF_ENTRY) | ||
146 | { | ||
147 | ptr = logfbuffer[logfindex]; | ||
148 | strncpy(ptr, buf + tlen, MAX_LOGF_ENTRY); | ||
149 | ptr[MAX_LOGF_ENTRY] = LOGF_TERMINATE_CONTINUE_LINE; | ||
150 | logfindex++; | ||
151 | check_logfindex(); | ||
152 | len -= MAX_LOGF_ENTRY; | ||
153 | tlen += MAX_LOGF_ENTRY; | ||
154 | multiline = true; | ||
155 | } | ||
156 | ptr = logfbuffer[logfindex]; | ||
157 | strcpy(ptr, buf + tlen); | ||
158 | |||
122 | if(len < MAX_LOGF_ENTRY) | 159 | if(len < MAX_LOGF_ENTRY) |
123 | /* pad with spaces up to the MAX_LOGF_ENTRY byte border */ | 160 | /* pad with spaces up to the MAX_LOGF_ENTRY byte border */ |
124 | memset(ptr+len, ' ', MAX_LOGF_ENTRY-len); | 161 | memset(ptr+len, ' ', MAX_LOGF_ENTRY-len); |
162 | ptr[MAX_LOGF_ENTRY] = (multiline)?LOGF_TERMINATE_MULTI_LINE:LOGF_TERMINATE_ONE_LINE; | ||
125 | 163 | ||
126 | logfindex++; /* leave it where we write the next time */ | 164 | logfindex++; /* leave it where we write the next time */ |
127 | 165 | ||