RT-Thread ntp_sync时间同步问题
RT-Thread ntp_sync时间同步问题
硬件
RT-THREAD ART-PI开发板,使用4G模块EC200进行时钟同步。
现象
msh />ntp_sync
[I/ntp] Get local time from NTP server: Fri May 28 23:02:58 2021
[I/ntp] 1622214178
[I/ntp] year:2000, month:3, day:4
[I/ntp] hour:23, min:2, sec:58
[I/ntp] Get local time from NTP server: Fri May 28 23:02:58 2021
使用ntp_sync进行网络时钟同步。年月日时间没有同步,时分秒时间同步了。
解决
修改packages\netutils\ntp\ntp.c文件中代码。
struct tm *cur_tm;
cur_tm = localtime(&cur_time);
set_time(cur_tm->tm_hour, cur_tm->tm_min, cur_tm->tm_sec);
set_date(cur_tm->tm_year + 1900, cur_tm->tm_mon + 1, cur_tm->tm_mday);
更改为
struct tm *cur_tm;
struct tm cur_tm_t;
cur_tm = &cur_tm_t;
localtime_r(&cur_time, cur_tm);
set_time(cur_tm->tm_hour, cur_tm->tm_min, cur_tm->tm_sec);
set_date(cur_tm->tm_year + 1900, cur_tm->tm_mon + 1, cur_tm->tm_mday);
或者使用设备操作替换
rt_device_control(rt_device_find("rtc"), RT_DEVICE_CTRL_RTC_SET_TIME, &cur_time);
问题分析
函数localtime调用流程。
graph LR
A[localtime] --> B[localtime_r]
B --> C[gmtime_r]
其中它返回的地址是localtime函数中声明的静态变量static struct tm tmp。
其中cur_tm指针指向struct tm tmp的地址。而后面的函数set_time(cur_tm->tm_hour, cur_tm->tm_min, cur_tm->tm_sec);会调用localtime函数,同时更改静态变量的值,同步更新cur_tm->tm_year等值。造成set_date函数中参数变化,影响年月日的设置。
使用localtime_r函数,将值保存在声明的局部变量,可修复bug。
set_time中包含localtime(),影响cur_tm指针指向的变量。
rt_err_t set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second)
{
time_t now;
struct tm *p_tm;
struct tm tm_new;
rt_device_t device;
rt_err_t ret = -RT_ERROR;
/* get current time */
now = time(RT_NULL);
/* lock scheduler. */
rt_enter_critical();
/* converts calendar time into local time. */
p_tm = localtime(&now);
/* copy the statically located variable */
rt_memcpy(&tm_new, p_tm, sizeof(struct tm));
/* unlock scheduler. */
rt_exit_critical();
/* update time. */
tm_new.tm_hour = hour;
tm_new.tm_min = minute;
tm_new.tm_sec = second;
/* converts the local time into the calendar time. */
now = mktime(&tm_new);
device = rt_device_find("rtc");
if (device == RT_NULL)
{
return -RT_ERROR;
}
/* update to RTC device. */
ret = rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &now);
return ret;
}

浙公网安备 33010602011771号