OpenHarmony轻量系统-获取当地时间
本篇文章想在OpenHarmony上实现SNTP获取本地时间,并将此功能集成为一个模块,便于我们的主程序调用。 想了解更多关于开源的内容,请访问: 51CTO 鸿蒙开发者社区 https://ost.51cto.com 前言 在轻量设备里面,我们常常需要获取本地时间,用于时间显示,log记录,帮助RTC芯片纠正时间等等。我们在之前设计了一个智慧时钟,需要使用到本地当前时间,因此本篇文章想在OpenHarmony上实现SNTP获取本地时间,并将此功能集成为一个模块,便于我们的主程序调用。 环境 OpenHarmony3.1 润和hispark_pegasus Hi3861开发板 DevEco Device Tool 串口调试助手 SNTP介绍 SNTP(Simple Network Time Protocal简单网络时间协议),用于跨广域网或局域网同步时间的协议,主要用来同步因特网中的计算机时钟,具有较高的精确度(几十毫秒)。 SNTP协议相对于NTP,优化了网络传播延时的影响,同时也能保证时间达到一定的精确度。 SNTP协议采用客户端/服务器的工作方式,可以采用单播(点对点)或者广播(一点对多点)模式操作。SNTP服务器通过接收 GPS信号或自带的原子钟作为系统的时间基准。单播模式下,SNTP客户端能够通过定期访问 SNTP服务器获得准确的时间信息,用于调整客户端自身所在系统的时间,达到同步时间的目的。 时间戳 SNTP发送回来的时间戳是NTP时间戳。 NTP时间戳和UTC时间戳的主要区别在于它们的起始时间: NTP时间戳的起始点是1900年1月1日00:00:00。 UTC时间戳(Unix时间戳)的起始点是1970年1月1日00:00:00。 软件设计流程 流程图 文件树状图 复制 . ├── include //sntp库 │ └── lwip │ └── apps │ ├── sntp.h │ └── sntp_opts.h ├── src //sntp源文件 │ ├── BUILD.gn │ ├── sntp.c │ ├── sntp_debug.c │ ├── sntp_port.c │ └── sntp_port.h └── test //模块主代码 ├── BUILD.gn ├── sntp_test.c //模块源代码 ├── sntp_test.h //模块接口、wifi配置 ├── wifi_connecter.c //wifi连接库 └── wifi_connecter.h 使用方法 下载源码。 将SNTP文件夹放入applications/sample/wifi-iot/app路径下。 在applications/sample/wifi-iot/app/BUILD.gn的features内添加以下代码。 复制 "sntp/src:sntp", "sntp/test:sntp_test", 在自己的主程序中引用sntp_test.h文件,调用set_sntp_init()函数初始化,随后即可通过访问sntp_time_sec变量获取当前时间(NTP时间戳0时区)。 流程介绍 连接WIFI 连接的WIFI需要可以访问互联网,否则设备无法联网获取时间。 WIFI当前设置为:(配置在/sntp/test/sntp_test.h)。 SSID:M20P PSK:12345678 设置SNTP服务器 常用SNTP服务器有以下四个: 复制 "cn.ntp.org.cn", // 中国 NTP 快速授时服务 "ntp.ntsc.ac.cn", // 国家授时中心 NTP 服务器 "time.pool.aliyun.com", // 阿里云公共 NTP 服务器 "cn.pool.ntp.org", // 国际 NTP 快速授时服务 在本文章中,SNTP_SERVER_DNS默认为0,因此我们使用IP进行配置SNTP服务器。 复制 #if SNTP_SERVER_DNS static const char* g_ntpServerList[] = { // refers from https://dns.icoa.cn/ntp/#china "cn.ntp.org.cn", // 中国 NTP 快速授时服务 "ntp.ntsc.ac.cn", // 国家授时中心 NTP 服务器 "time.pool.aliyun.com", // 阿里云公共 NTP 服务器 "cn.pool.ntp.org", // 国际 NTP 快速授时服务 }; #define SNTP_SERVERS ARRAY_SIZE(g_ntpServerList) void SntpSetServernames(void) { for (size_t i = 0; i < SNTP_SERVERS; i++) { sntp_setservername(i, g_ntpServerList[i]); } } #else ip4_addr_t g_ntpServerList[SNTP_MAX_SERVERS]; void SntpSetServers(void) { IP4_ADDR(&g_ntpServerList[0], 114, 67, 237, 130); // cn.ntp.org.cn IP4_ADDR(&g_ntpServerList[1], 114, 118, 7, 163); // ntp.ntsc.ac.cn IP4_ADDR(&g_ntpServerList[2], 182, 92, 12, 11); // time.pool.aliyun.com IP4_ADDR(&g_ntpServerList[3], 193, 182, 111, 12); // cn.pool.ntp.org #define SNTP_SERVERS 4 for (size_t i = 0; i < SNTP_SERVERS; i++) { sntp_setserver(i, (ip_addr_t*)&g_ntpServerList[i]); } } #endif void set_sntp_init(void) { /****************************/ #if SNTP_SERVER_DNS ip4_addr_t dnsServerAddr; IP4_ADDR(&dnsServerAddr, 192, 168, 1, 1); dns_setserver(0, (struct ip_addr *)&dnsServerAddr); dns_init(); SntpSetServernames(); #else SntpSetServers(); #endif /****************************/ } SNTP初始化以及获取时间 复制 sntp_setoperatingmode(SNTP_OPMODE_POLL); sntp_init(); printf("sntp_enabled: %d\r\n", sntp_enabled()); for (size_t i = 0; i < SNTP_SERVERS; i++) { printf("sntp_getreachability(%d): %d\r\n", i, sntp_getreachability(i)); } osDelay(500); for (size_t i = 0; i < SNTP_SERVERS; i++) { printf("sntp_getreachability(%d): %d\r\n", i, sntp_getreachability(i)); } 时间显示 本样例源码仅作为一个底层模块,因此尚未有主程序。可以自行创建一个主程序进行测试获取时间,或者按照以下方式修改源码:在sntp/test/sntp_test.c的SntpSetServers函数末尾添加以下代码(显示获取到的时间): 复制 time_t ut; ut = (unsigned int)((unsigned int)sntp_time_sec + ((unsigned int)2085978496L)); //转换成UTC时间(0时区) struct tm *now_time = gmtime(&ut); printf("%d %d %d\n", now_time->tm_hour, now_time->tm_min, now_time->tm_sec); 在sntp/test/sntp_test.c末尾添加以下代码(开机自启动): 复制 SYS_RUN(set_sntp_init); 1. 测试 文章相关附件可以点击下面的原文链接前往下载: https://ost.51cto.com/resource/3095。 (编辑:52站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |