RT-Thread-packages / netutils

IoT networking utilities for RT-Thread. Such as: ping, tftp, iperf, netio, ntp, telnet and tcpdump.
Apache License 2.0
74 stars 60 forks source link

netutils V1.3 ntp_sync 的堆栈太小了 #65

Closed dongly closed 3 years ago

dongly commented 3 years ago

RT-Thread 版本: master (5ba96109c60c4b1a) netutils 版本: ~V1.2~ V1.3 现象: 出现提示warning: ntp_sync stack is close to end of stack address,也出过堆栈溢出

[I/ntp] Get local time from NTP server: Wed May 19 18:23:40 2021

[I/ntp] Get local time from NTP server: Wed May 19 18:25:40 2021

warning: ntp_sync stack is close to end of stack address.
warning: ntp_sync stack is close to end of stack address.
[I/ntp] Get local time from NTP server: Wed May 19 18:27:40 2021

[I/ntp] Get local time from NTP server: Wed May 19 18:29:40 2021

[I/ntp] Get local time from NTP server: Wed May 19 18:31:40 2021

[I/ntp] Get local time from NTP server: Wed May 19 18:33:40 2021

[I/ntp] Get local time from NTP server: Wed May 19 18:35:40 2021

ps
thread   pri  status      sp     stack size max used left tick  error
-------- ---  ------- ---------- ----------  ------  ---------- ---
tshell    20  running 0x000002c0 0x00001000    17%   0x00000005 000
PLC       13  suspend 0x000000b0 0x00002000    04%   0x00000001 000
DI/DO     12  suspend 0x000000c0 0x000002a8    28%   0x00000001 000
inj_test  20  suspend 0x000000ac 0x00000200    33%   0x00000001 000
telnet    26  suspend 0x00000210 0x00001000    20%   0x00000064 000
acon      19  suspend 0x00000114 0x00000800    13%   0x00000064 000
AutoSave   0  suspend 0x0000009c 0x00000800    08%   0x00000005 000
ebThread  30  suspend 0x000000ac 0x00000100    67%   0x0000000a 000
syswatch   0  suspend 0x000000a4 0x00000200    56%   0x0000000e 000
ntp_sync  30  suspend 0x000000a4 0x00000514    98%   0x00000002 000
sys_work  23  suspend 0x0000010c 0x00000af0    47%   0x0000000a 000
tcpip     10  suspend 0x000000f0 0x00000400    77%   0x00000010 000
etx       12  suspend 0x000000ac 0x00000800    17%   0x00000010 000
erx       12  suspend 0x000000bc 0x00000800    32%   0x0000000b 000
tidle0    31  ready   0x00000078 0x00000400    16%   0x0000001b 000
main      10  suspend 0x00000148 0x00000800    57%   0x00000003 000
mysterywolf commented 3 years ago

v1.2还是v1.3

dongly commented 3 years ago

V1.3

mysterywolf commented 3 years ago

ok

dongly commented 3 years ago

我用 system workqueue 写了一个自动同步,单用的话资源可能稍多,我的工程其他也用到system workqueue,所以内存占用少了点

#include "board.h"
#include <ipc/workqueue.h>
#include <rtthread.h>
#define DBG_TAG "sys.ntpsync"
// #define DBG_LVL DBG_LOG
#define DBG_LVL DBG_INFO
#include <rtdbg.h>

#ifdef RTC_SYNC_USING_NTP_USER

static struct rt_work work_ntp_sync;
static int            rtc_ntp_sync_period = RTC_NTP_SYNC_PERIOD * RT_TICK_PER_SECOND;
static rt_bool_t      init_ok = RT_FALSE;

extern time_t ntp_sync_to_rtc(const char *host_name);

static void ntp_sync_work_func(struct rt_work *work, void *work_data)
{
    time_t now;
    now = ntp_sync_to_rtc(NULL);

    LOG_D("*work_data = %d\nntp = %d", *(rt_tick_t *)work_data, now);
    // 当前时间 > 2021-5-1 0:00:00Z 即认为 NTP 获取成功
    if (now > (time_t)1619827200)
    {
        LOG_I("NTP sync ok. Now is %s", ctime(&now));
        init_ok = RT_TRUE;
        rt_work_submit(work, *(rt_tick_t *)work_data);
    }
    else //未成功同步之前,每秒同步一次
    {
        rt_work_submit(work, 1000);
    }
}

int rt_rtc_ntp_sync_init(void)
{
    if (init_ok)
    {
        return 0;
    }

    rt_work_init(&work_ntp_sync, ntp_sync_work_func, &rtc_ntp_sync_period);
    rt_work_submit(&work_ntp_sync, 1);
    return RT_EOK;
}
INIT_APP_EXPORT(rt_rtc_ntp_sync_init);
#endif /* RTC_SYNC_USING_NTP_USER */
mysterywolf commented 3 years ago

我之前在实验的时候这个默认线程大小是比较合适的,你是因为你内部用了workqueue导致的堆栈偏高的吗?

mysterywolf commented 3 years ago

我多加一个配置选项可以让用户在env里边配置堆栈大小吧

dongly commented 3 years ago

这个不太清楚,有可能吧,我之前有些堆栈大小是合适的,后来不知什么时候,又不够大了. 另,可否未成功同步前,持续同步?有些应用是没有电池的,又想第一时间获取到正确的时间

mysterywolf commented 3 years ago

我没懂你什么意思 如果你没有硬件RTC的话 我们这里有一个软件RTC 你可以开启NTP自动同步之后往软件RTC里边同步

dongly commented 3 years ago

就是用软件RTC时,若因网络故障不能在上电初同步ntp,网络恢复后,就不能立即获得正确的时间,要等很长一段时间,我想把这段时间缩短一点

mysterywolf commented 3 years ago

请你详细描述一下,你的问题问的太笼统了。你是觉得NTP间隔一个小时同步时间很长是吗

dongly commented 3 years ago

我的设想是(可参考我上面的代码):

  1. 上电
  2. NTP同步,成功,转到 5
  3. 短延时 (如 1s)
  4. 转 2
  5. 长延时 (如 1小时)
  6. NTP 同步
  7. 转5
mysterywolf commented 3 years ago
  • 我的最终目标是:当网络正常时,以较短的时间(秒级的),通过NTP获取到正确的时间.
  • 现时的方式,上电了等上几十秒才开始第一次同步,若这次不能正确同步,再要等上1小时.我觉得这样的方式不太好.
  • 若机器的RTC的时间是正确,NTP间隔一个小时同步一次,一点也不长.但若当前时间不正确,1个小时就太长了.

我的设想是(可参考我上面的代码):

  1. 上电
  2. NTP同步,成功,转到 5
  3. 短延时 (如 1s)
  4. 转 2
  5. 长延时 (如 1小时)
  6. NTP 同步
  7. 转5

@armink 麻烦看一下这问题,ntp.c内不能探测网络连接状态,如果因为网络问题同步失败,只能以轮询的方式高频次调用NTP同步函数探测,直到同步成功,这种方法是不是有些不太好。这个问题是否应该留给用户自行解决?

armink commented 3 years ago

这种就外部用户手动调用 NTP 同步函数就好了