Browse Source

feat: add network-synchronized log timestamps

dev-rebuild
蔡享 1 month ago
parent
commit
aa3dbec157
  1. 3
      applications/VK_Client.c
  2. 121
      applications/VK_Log.c
  3. 3
      applications/VK_Log.h
  4. 20
      applications/drv_ec800k.c
  5. 3
      applications/drv_ec800k.h

3
applications/VK_Client.c

@ -257,6 +257,9 @@ int16_t client_tcp_connect(Cclient_t *client) {
}
}
/* Query once after PDP is available, so network time has had a chance to sync. */
BSP_LTE_InitLogClock();
//
BSP_LTE_SendCmd(AT_CFG_TRANS_SIZE, DEFAULT_EXPECT, DEFAULT_ERROR,
LTE_CMD_WAIT_NORMAL);

121
applications/VK_Log.c

@ -1,5 +1,110 @@
#include "VK_Log.h"
#include <ulog.h>
#include <string.h>
typedef struct
{
rt_uint16_t year;
rt_uint8_t month;
rt_uint8_t day;
rt_uint8_t hour;
rt_uint8_t minute;
rt_uint8_t second;
rt_tick_t base_tick;
rt_bool_t valid;
} log_clock_t;
static log_clock_t log_clock;
static rt_bool_t is_leap_year(rt_uint16_t year)
{
return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
}
static rt_uint8_t days_in_month(rt_uint16_t year, rt_uint8_t month)
{
static const rt_uint8_t days[] = {31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
return (month == 2 && is_leap_year(year)) ? 29 : days[month - 1];
}
static void log_clock_add_seconds(rt_uint32_t seconds,
rt_uint16_t *year, rt_uint8_t *month,
rt_uint8_t *day, rt_uint8_t *hour,
rt_uint8_t *minute, rt_uint8_t *second)
{
rt_uint32_t days;
*second += seconds % 60;
if (*second >= 60) { *second -= 60; seconds = seconds / 60 + 1; }
else { seconds /= 60; }
*minute += seconds % 60;
if (*minute >= 60) { *minute -= 60; seconds = seconds / 60 + 1; }
else { seconds /= 60; }
*hour += seconds % 24;
days = seconds / 24;
if (*hour >= 24) { *hour -= 24; days++; }
while (days > 0) {
rt_uint8_t month_days = days_in_month(*year, *month);
if (*day < month_days) { (*day)++; days--; }
else {
*day = 1;
if (*month < 12) (*month)++;
else { *month = 1; (*year)++; }
days--;
}
}
}
int dev_log_time_set_from_at(const char *response)
{
const char *p;
rt_uint16_t year = 0;
rt_uint8_t fields[5];
int year_digits = 0;
int i;
if (response == RT_NULL) return -1;
p = rt_strstr(response, "+QLTS:");
if (p != RT_NULL) year_digits = 4;
else {
p = rt_strstr(response, "+CCLK:");
if (p == RT_NULL) return -1;
year_digits = 2;
}
p = strchr(p, '"');
if (p == RT_NULL || p[1] == '"') return -1;
p++;
for (i = 0; i < year_digits; i++) {
if (p[i] < '0' || p[i] > '9') return -1;
year = (rt_uint16_t)(year * 10 + p[i] - '0');
}
p += year_digits;
if (*p++ != '/') return -1;
for (i = 0; i < 5; i++) {
if (p[0] < '0' || p[0] > '9' || p[1] < '0' || p[1] > '9') return -1;
fields[i] = (rt_uint8_t)((p[0] - '0') * 10 + p[1] - '0');
p += 2;
if (i == 0 && *p++ != '/') return -1;
if (i == 1 && *p++ != ',') return -1;
if (i >= 2 && i < 4 && *p++ != ':') return -1;
}
if ((year_digits == 4 && (year < 2000 || year > 2099)) ||
(year_digits == 2 && year == 70 && fields[0] == 1 && fields[1] == 1) ||
fields[0] < 1 || fields[0] > 12 || fields[1] < 1 ||
fields[1] > days_in_month(year_digits == 2 ? (rt_uint16_t)(2000 + year) : year,
fields[0]) || fields[2] > 23 ||
fields[3] > 59 || fields[4] > 59) return -1;
log_clock.year = year_digits == 2 ? (rt_uint16_t)(2000 + year) : year;
log_clock.month = fields[0]; log_clock.day = fields[1];
log_clock.hour = fields[2]; log_clock.minute = fields[3];
log_clock.second = fields[4];
log_clock.base_tick = rt_tick_get();
log_clock.valid = RT_TRUE;
return 0;
}
static struct ulog_backend vcom_backend;
static rt_device_t log_dev = RT_NULL;
@ -16,8 +121,20 @@ static void vcom_log_output(struct ulog_backend *backend,
(void)tag;
(void)is_raw;
if (log_dev != RT_NULL && len > 0)
{
if (log_dev != RT_NULL && len > 0) {
char prefix[32];
rt_uint16_t year = log_clock.year;
rt_uint8_t month = log_clock.month, day = log_clock.day;
rt_uint8_t hour = log_clock.hour, minute = log_clock.minute;
rt_uint8_t second = log_clock.second;
if (log_clock.valid) {
log_clock_add_seconds((rt_uint32_t)((rt_tick_get() - log_clock.base_tick) /
RT_TICK_PER_SECOND),
&year, &month, &day, &hour, &minute, &second);
rt_snprintf(prefix, sizeof(prefix), "[%04u-%02u-%02u %02u:%02u:%02u] ",
year, month, day, hour, minute, second);
(void)rt_device_write(log_dev, 0, prefix, rt_strlen(prefix));
}
(void)rt_device_write(log_dev, 0, log, len);
}
}

3
applications/VK_Log.h

@ -10,6 +10,9 @@ extern "C"{
int dev_log_backend_init(rt_device_t dev);
/* Set the wall-clock baseline parsed from an EC800K QLTS/CCLK response. */
int dev_log_time_set_from_at(const char *response);
#ifdef __cplusplus

20
applications/drv_ec800k.c

@ -37,6 +37,7 @@ CLte_dev_t lte_dev = {
};
lte_diag_t lte_diag = {0};
static bool lte_log_clock_query_done = false;
void lte_diag_at_begin(const char *cmd) {
rt_size_t i;
@ -134,6 +135,22 @@ void BSP_LTE_SetDataTxPaused(bool paused) {
}
}
void BSP_LTE_InitLogClock(void) {
if (lte_log_clock_query_done) {
return;
}
lte_log_clock_query_done = true;
if (BSP_LTE_SendCmd(AT_QLTS, DEFAULT_EXPECT, DEFAULT_ERROR,
LTE_CMD_WAIT_NORMAL) == 0) {
if (dev_log_time_set_from_at((const char *)lte_dev.at_buf) != 0) {
LOG_W("EC800K clock is not synchronized; using untimestamped logs\n");
}
} else {
LOG_W("EC800K clock query failed; using untimestamped logs\n");
}
}
int16_t BSP_LTE_SendCmd(const char *cmd, const char *expect, const char *error,
uint32_t waittime) {
lte_diag_at_begin(cmd);
@ -365,6 +382,9 @@ void BSP_LTE_Config(void) {
LOG_I("BSP_LTE_SendATE error\n");
}
/* Allow the network to update the module clock after registration. */
BSP_LTE_SendCmd(AT_CTZU, DEFAULT_EXPECT, DEFAULT_ERROR, LTE_CMD_WAIT_NORMAL);
/*查询模块信息*/
if (lte_dev.dev_init_flag == true) {
BSP_LTE_SendCmd(AT_ATI, DEFAULT_EXPECT, DEFAULT_ERROR, LTE_CMD_WAIT_NORMAL);

3
applications/drv_ec800k.h

@ -71,6 +71,8 @@ extern "C" {
#define AT_CIPMODE "AT+CIPMODE=1\r\n"
#define AT_CCLK "AT+CCLK?\r\n"
#define AT_QLTS "AT+QLTS=2\r\n"
#define AT_CTZU "AT+CTZU=1\r\n"
#define AT_GTPOS "AT+GTPOS?\r\n"
#define AT_GTPOS0 "AT+GTPOS=0\r\n" // close
@ -317,6 +319,7 @@ void BSP_LTE_SendData(uint8_t *pdata, uint32_t length);
void BSP_LTE_SetDataTxPaused(bool paused);
void BSP_LTE_Config(void);
void BSP_LTE_InitLogClock(void);
int BSP_LTE_GetICCID(char *pICCID);

Loading…
Cancel
Save