NTP
一、NTP 通信概述
很多场景中,由于业务需要,模块需要保持正确的系统时钟,才能正常工作。但是模块上电后的初试时间戳是 946713600(即 2000/01/01,16:00:00),所以同步时钟成为了开发者要解决的重要问题。对于 Cat.1 模块, 移动/电信卡, 通常会下发基站时间, 那么 sntp 就不是必要的, 而联通卡通常不会下发, 就需要 sntp 了
NTP(Network Time Protocol,网络时间协议)是用于同步系统时间的协议。它通过网络连接多个设备,确保这些设备的系统时钟保持一致。
本例程展示了如何使用 SNTP 授时服务来同步时间。
NTP 和简化版的 SNTP(Simple Network Time Protocol)主要区别在于精确度和复杂性。SNTP 通常用于不需要高精度同步的设备,如嵌入式系统。而 NTP 则用于要求较高时间精度的场景。
二、演示功能概述
本 demo 将连接 NTP 服务器进行时间同步。
三、准备硬件环境
3.1 780E 开发板一套,包括天线、USB 数据线.
淘宝购买链接:Air780E 核心板淘宝购买链接 ;
此核心板的详细使用说明参考:Air780E 产品手册 中的 << 开发板 Core_Air780E 使用说明 V1.0.5.pdf>>,X.X.X 指版本号;核心板使用过程中遇到任何问题,可以直接参考这份使用说明 pdf 文档。
3.2 SIM 卡
请准备一张可正常上网的 SIM 卡,该卡可以是物联网卡或您的个人手机卡。
特别提醒:请确保 SIM 卡未欠费且网络功能正常,以便顺利进行后续操作。
3.3 数据通信线
typec 接口 USB 数据线即可。
3.4 PC 电脑
WINDOWS 系统。
四、准备软件环境
4.1 基本的下载调试工具
使用说明参考:Luatools 下载和详细使用 ;
五、获取 NTP 授时软硬件资料
5.1 文档和工具:
- 780E 模块使用固件:SDK& Demo - 合宙文档中心,本 demo 使用的固件版本是:LuatOS-SoC_V1112_EC618_FULL.soc
- 本教程使用的 demo:https://gitee.com/openLuat/LuatOS-Air780E/tree/master/demo/sntp
- 将固件和脚本烧录到模块中:Luatools 下载和使用教程 - 合宙模组资料中心
- 源码和固件已打包,如下所示: 点我,下载完整压缩文件包
5.2 demo 使用 api 介绍
socket.sntp(sntp_server)
作用:sntp 时间同步
传入值类型 |
解释 |
---|---|
string/table |
sntp 服务器地址 选填 |
int |
适配器序号, 只能是 socket.ETH0(外置以太网),socket.LWIP_ETH(内置以太网),socket.LWIP_STA(内置 WIFI 的 STA),socket.LWIP_AP(内置 WIFI 的 AP),socket.LWIP_GP(内置蜂窝网络的 GPRS),socket.USB(外置 USB 网卡),如果不填,优先选择 soc 平台自带能上外网的适配器,若仍然没有,选择最后一个注册的适配器 |
返回值
无
os.time(mytime)
作用:时间戳函数
参数
传入值类型 |
解释 |
---|---|
table |
日期时间的 table |
return |
时间戳 |
返回值
无
os.date(fmt, time)
作用:日期函数
参数
传入值类型 |
解释 |
---|---|
string |
格式化字符串,可以是 nil |
table |
日期时间的 table |
返回值
返回值类型 |
解释 |
---|---|
table/string |
根据 fmt 的不同,返回值不同 |
json.encode(obj,t)
作用:将对象序列化为 json 字符串
参数
传入值类型 |
解释 |
---|---|
obj |
需要序列化的对象 |
string |
浮点数精度和模式,这项不存在的时候,为默认值”7f”,数字只支持”0~14”,模式只支持”f/g” |
返回值
返回值类型 |
解释 |
---|---|
string |
序列化后的 json 字符串, 失败的话返回 nil |
string |
序列化失败的报错信息 |
json.decode(str)
作用:将字符串反序列化为对象
参数
传入值类型 |
解释 |
---|---|
string |
需要反序列化的 json 字符串 |
返回值
返回值类型 |
解释 |
---|---|
obj |
反序列化后的对象(通常是 table), 失败的话返回 nil |
result |
成功返回 1,否则返回 0 |
err |
反序列化失败的报错信息 |
六、代码示例介绍
6.1 使用 ntp 服务器同步时间
6.1.1 demo 介绍
-- 开始时间同步
socket.sntp()
-- 自定义ntp地址
-- socket.sntp("ntp.aliyun.com")
-- socket.sntp({"baidu.com", "abc.com", "ntp.air32.cn"})
-- 通常只需要几百毫秒就能成功,超时时间2s
local ret = sys.waitUntil("NTP_UPDATE", 5000)
if ret then
-- 以下是获取/打印时间的演示,注意时区问题
log.info("sntp", "时间同步成功", "本地时间", os.date())
log.info("sntp", "时间同步成功", "UTC时间", os.date("!%c"))
log.info("sntp", "时间同步成功", "RTC时钟(UTC时间)", json.encode(rtc.get()))
-- os.time(rtc.get()) 需要 2023.07.21 之后的版本, 因为月份的命名差异mon/month
-- log.info("sntp", "时间同步成功", "utc时间戳", os.time(rtc.get()))
log.info("sntp", "时间同步成功", "本地时间戳", os.time())
local t = os.date("*t")
log.info("sntp", "时间同步成功", "本地时间os.date() json格式", json.encode(t))
log.info("sntp", "时间同步成功", "本地时间os.date(os.time())", os.time(t))
-- log.info("sntp", "时间同步成功", "本地时间", os.time())
-- 正常使用, 一小时一次, 已经足够了, 甚至1天一次也可以
-- sys.wait(3600000)
-- 这里为了演示, 用5秒一次
sys.wait(5000)
else
log.info("sntp", "时间同步失败")
sys.wait(60000) -- 1分钟后重试
end
-- 时间戳, 精确到毫秒. 2023.11.15 新增
-- 注意, 至少成功完成2次sntp,该时间戳才比较准确
-- 如果仅完成了一次sntp, 时间戳比标准时间会慢一个网络延时的时长(10~500ms)不等
if socket.ntptm then
local tm = socket.ntptm()
log.info("tm数据", json.encode(tm))
log.info("时间戳", string.format("%u.%03d", tm.tsec, tm.tms))
sys.wait(5000)
end
end
end)
sys.subscribe("NTP_ERROR", function()
log.info("socket", "sntp error")
-- socket.sntp()
end)
6.1.2 将程序下载到开发板
参考:将固件和脚本烧录到模块中:Luatools 下载和使用教程 - 合宙模组资料中心
七、功能验证
八、总结
本 demo 介绍了如何使用 ntp 服务器同步时间。
扩展
常见问题
1、ntp 同步时间后,这个 clock 精度高吗,需要多久同步一次
并不能保证任何时间任何地点都能百分百同步到正确的时间。 所以,如果用户项目中的业务逻辑严格依赖于时间同步功能 则不要使用本功能模块,建议使用自己的应用服务器来同步时间。
2、多长时间 ntp 同步一次
正常使用, 一小时一次, 已经足够了, 甚至 1 天一次也可以。
3、这个函数 socket.sntp()后每次在程序中调用 os.time 也是实时时间了吗?
是的,只要时间同步成功了,就是实时时间了。
给读者的话
本篇文章由
Linden
开发;本篇文章描述的内容,如果有错误、细节缺失、细节不清晰或者其他任何问题,总之就是无法解决您遇到的问题;
请登录合宙技术交流论坛,点击文档找错赢奖金-Air780E-LuatOS-软件指南-网络驱动-NTP通信;
用截图标注+文字描述的方式跟帖回复,记录清楚您发现的问题;
我们会迅速核实并且修改文档;
同时也会为您累计找错积分,您还可能赢取月度找错奖金!