在輕量設備里面,我們常常需要獲取本地時間,用于時間顯示,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: %drn", sntp_enabled());
for (size_t i = 0; i < SNTP_SERVERS; i++) {
printf("sntp_getreachability(%d): %drn", i, sntp_getreachability(i));
}
osDelay(500);
for (size_t i = 0; i < SNTP_SERVERS; i++) {
printf("sntp_getreachability(%d): %drn", 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 %dn", now_time- >tm_hour, now_time- >tm_min, now_time- >tm_sec);
在sntp/test/sntp_test.c末尾添加以下代碼(開機自啟動):
SYS_RUN(set_sntp_init);
本文主要是對鴻蒙開發技術OpenHarmony中的輕量系統-獲取當地時間; 更多的鴻蒙實戰開發可以去主頁閱讀,或找我保存一下鴻蒙開發技術文檔 :
鴻蒙開發技術分布路線圖如下,高清完整版找我保存 。
最后結果
審核編輯 黃宇
-
芯片
+關注
關注
450文章
49636瀏覽量
417151 -
RTC
+關注
關注
2文章
511瀏覽量
65897 -
sntp
+關注
關注
0文章
4瀏覽量
3685 -
鴻蒙
+關注
關注
56文章
2267瀏覽量
42486 -
OpenHarmony
+關注
關注
25文章
3548瀏覽量
15737
發布評論請先 登錄
相關推薦
評論