Skip to content

Commit 45751e2

Browse files
valeriosettimbolivar-nordic
authored andcommitted
logging: fix for 64 bit timestamp + new timestamp format option
Timestamps can be 32 or 64 bit long based on the platform and build configurations. The proper way to handle these timestamps is to use the ad-hoc log_timestamp_t variable. This patch fixes some timestamp's reference which were still using uint32_t changing them to log_timestamp_t. Moreover also a new config is added in order to print the timestamp as the Linux's kernel format. This might be useful in AMP platforms in which Linux's and Zephyr's logs must be interleaved in order to get a more comprehensive log solution. Signed-off-by: Valerio Setti <[email protected]>
1 parent fab5bb9 commit 45751e2

File tree

2 files changed

+88
-8
lines changed

2 files changed

+88
-8
lines changed

subsys/logging/Kconfig.formatting

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,13 @@ config LOG_BACKEND_FORMAT_TIMESTAMP
8888
help
8989
When enabled timestamp is formatted to hh:mm:ss:ms,us.
9090

91+
config LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP
92+
bool "Format timestamp in Linux format"
93+
default n
94+
help
95+
This formatting is something in the middle between the pure raw format
96+
and the hh:mm:ss:ms,us one. It resembles the Linux's kernel format in
97+
which timestamps are printed as fixed point values with seconds on the
98+
left side of the point and microseconds on the right side.
99+
91100
endmenu

subsys/logging/log_output.c

Lines changed: 79 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,18 @@ static const char *const colors[] = {
4444
};
4545

4646
static uint32_t freq;
47-
static uint32_t timestamp_div;
47+
static log_timestamp_t timestamp_div;
48+
49+
#define SECONDS_IN_DAY 86400U
50+
51+
static uint32_t days_in_month[12] = {31, 28, 31, 30, 31, 30, 31,
52+
31, 30, 31, 30, 31};
53+
54+
struct YMD_date {
55+
uint32_t year;
56+
uint32_t month;
57+
uint32_t day;
58+
};
4859

4960
extern void log_output_msg_syst_process(const struct log_output *output,
5061
struct log_msg *msg, uint32_t flag);
@@ -169,19 +180,68 @@ void log_output_flush(const struct log_output *output)
169180
output->control_block->offset = 0;
170181
}
171182

183+
static inline bool is_leap_year(uint32_t year)
184+
{
185+
return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
186+
}
187+
188+
static void __attribute__((unused)) get_YMD_from_seconds(uint64_t seconds,
189+
struct YMD_date *output_date)
190+
{
191+
uint64_t tmp;
192+
int i;
193+
194+
output_date->year = 1970;
195+
output_date->month = 1;
196+
output_date->day = 1;
197+
198+
/* compute the proper year */
199+
while (1) {
200+
tmp = (is_leap_year(output_date->year)) ?
201+
366*SECONDS_IN_DAY : 365*SECONDS_IN_DAY;
202+
if (tmp > seconds) {
203+
break;
204+
}
205+
seconds -= tmp;
206+
output_date->year++;
207+
}
208+
/* compute the proper month */
209+
for (i = 0; i < sizeof(days_in_month); i++) {
210+
tmp = ((i == 1) && is_leap_year(output_date->year)) ?
211+
(days_in_month[i] + 1) * SECONDS_IN_DAY :
212+
days_in_month[i] * SECONDS_IN_DAY;
213+
if (tmp > seconds) {
214+
output_date->month += i;
215+
break;
216+
}
217+
seconds -= tmp;
218+
}
219+
220+
output_date->day += seconds / SECONDS_IN_DAY;
221+
}
222+
172223
static int timestamp_print(const struct log_output *output,
173-
uint32_t flags, uint32_t timestamp)
224+
uint32_t flags, log_timestamp_t timestamp)
174225
{
175226
int length;
176227
bool format =
177228
(flags & LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP) |
178-
(flags & LOG_OUTPUT_FLAG_FORMAT_SYSLOG);
229+
(flags & LOG_OUTPUT_FLAG_FORMAT_SYSLOG) |
230+
IS_ENABLED(CONFIG_LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP);
179231

180232

181233
if (!format) {
234+
#ifndef CONFIG_LOG_TIMESTAMP_64BIT
182235
length = print_formatted(output, "[%08lu] ", timestamp);
236+
#else
237+
length = print_formatted(output, "[%016llu] ", timestamp);
238+
#endif
183239
} else if (freq != 0U) {
240+
#ifndef CONFIG_LOG_TIMESTAMP_64BIT
184241
uint32_t total_seconds;
242+
#else
243+
uint64_t total_seconds;
244+
#endif
185245
uint32_t remainder;
186246
uint32_t seconds;
187247
uint32_t hours;
@@ -216,14 +276,25 @@ static int timestamp_print(const struct log_output *output,
216276
length = print_formatted(output, "%s.%06uZ ",
217277
time_str, ms * 1000U + us);
218278
#else
279+
struct YMD_date date;
280+
281+
get_YMD_from_seconds(total_seconds, &date);
282+
hours = hours % 24;
219283
length = print_formatted(output,
220-
"1970-01-01T%02u:%02u:%02u.%06uZ ",
284+
"%04u-%02u-%02uT%02u:%02u:%02u.%06uZ ",
285+
date.year, date.month, date.day,
221286
hours, mins, seconds, ms * 1000U + us);
222287
#endif
223288
} else {
224-
length = print_formatted(output,
225-
"[%02u:%02u:%02u.%03u,%03u] ",
226-
hours, mins, seconds, ms, us);
289+
if (IS_ENABLED(CONFIG_LOG_OUTPUT_FORMAT_LINUX_TIMESTAMP)) {
290+
length = print_formatted(output,
291+
"[%02u:%02u:%02u.%03u,%03u] ",
292+
hours, mins, seconds, ms, us);
293+
} else {
294+
length = print_formatted(output,
295+
"[%5ld.%06d] ",
296+
total_seconds, ms * 1000U + us);
297+
}
227298
}
228299
} else {
229300
length = 0;
@@ -493,7 +564,7 @@ static void raw_string_print(struct log_msg *msg,
493564
}
494565

495566
static uint32_t prefix_print(const struct log_output *output,
496-
uint32_t flags, bool func_on, uint32_t timestamp, uint8_t level,
567+
uint32_t flags, bool func_on, log_timestamp_t timestamp, uint8_t level,
497568
uint8_t domain_id, int16_t source_id)
498569
{
499570
uint32_t length = 0U;

0 commit comments

Comments
 (0)