5

OpenHarmony轻量系统-获取当地时间

 8 months ago
source link: https://www.51cto.com/article/778648.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

OpenHarmony轻量系统-获取当地时间

作者:X丶昕雪 2024-01-05 15:32:47
本篇文章想在OpenHarmony上实现SNTP获取本地时间,并将此功能集成为一个模块,便于我们的主程序调用。
085ebda96f6d00cb17217760a641e48f196059.png

想了解更多关于开源的内容,请访问:

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。

软件设计流程

resize,w_820,h_556

文件树状图

.
├── 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);
resize,w_820,h_907

文章相关附件可以点击下面的原文链接前往下载:

https://ost.51cto.com/resource/3095。

想了解更多关于开源的内容,请访问:

51CTO 鸿蒙开发者社区

https://ost.51cto.com

责任编辑:jianghua 来源: 51CTO 鸿蒙开发者社区

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK