首页 > 其他 > 详细

RT-Thread ntp_sync时间同步问题

时间:2021-05-28 19:15:17      阅读:28      评论:0      收藏:0      [点我收藏+]

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;
}

RT-Thread ntp_sync时间同步问题

原文:https://www.cnblogs.com/lionxy/p/14823429.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!