前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >开发者成长激励计划-开发笔记:基于IoT NTP实现实时时钟

开发者成长激励计划-开发笔记:基于IoT NTP实现实时时钟

原创
作者头像
flavorfan
修改2022-08-28 21:47:59
1.9K1
修改2022-08-28 21:47:59
举报
文章被收录于专栏:范传康的专栏范传康的专栏

设备的RTC大部分场景是有用的,但RTC芯片增加了成本,而实现NTP网络协议又增加了系统的复杂性。如果物联网系统能够提供NTP校时是性价比最高的方案。

1. IOT平台的NTP支持

1)设备开发的系统级Topic

在腾讯云iotexplorer的产品开发>设备开发>Topic列表

设备端pub一个”请求“,格式正确的化,iot hub会回复一个,设备端需要sub这个主题进行解析。

2)腾讯云文档接口描述

根据文档就知道了具体流程,和消息报文的格式。

2. 实现过程

2.1 设备端 pub/sub topic

代码语言:javascript
复制
void mqtt_report_task_entry(void *arg) {
    // 初始mqtt链接   
    // ... 
    // sub 其他主题:property report reply, data
    // ...
    // sub 系统
    size = snprintf(ntp_replay_topic_name, TOPIC_NAME_MAX_SIZE, "$sys/operation/result/%s/%s", product_id, device_name);

    if (size < 0 || size > sizeof(ntp_replay_topic_name) - 1) {
        printf("sub topic 2 content length not enough! content size:%d  buf size:%d", size, (int)sizeof(ntp_replay_topic_name));
    }
    // 注册回调函数处理ntp回复报文 ntp_message_handler
    if (tos_tf_module_mqtt_sub(ntp_replay_topic_name, QOS0, ntp_message_handler) != 0) {
        printf("module mqtt sub 2 fail\n");
    } else {
        printf("module mqtt sub 2 success\n");
    }
    
    // 循环处理pub主题
    while (1) {
        // 等待sem信号,以及fifo传来pub主题类型
        tos_sem_pend(&status_change, TOS_TIME_FOREVER);
        err = tos_chr_fifo_pop(&status_fifo, &dev_status);
        // 其他主题发送请求 
        // ...
        // 1: ntp time sync
        else if (dev_status == PUB_TYPE_NTP) { 
            snprintf(payload, sizeof(payload), SYS_MQTT_GET_RESOURCE_TIME);
            if (tos_tf_module_mqtt_pub(ntp_topic_name, QOS0, payload) != 0) {
                printf("module mqtt pub fail\n");
                // break;
                continue;
            } else {
                printf("module mqtt pub success\n");
            }   
        } 
    }
}

2.2 sub 回调函数处理数据

代码语言:javascript
复制
 void ntp_message_handler(mqtt_message_t* msg)
 {
     //  {
     // 		 "type": "get",
     // 		 "time": 1621562342,
     // 		 "ntptime1": 1621562342773,
     // 		 "ntptime2": 1621562342773
     // }
     cJSON* cjson_root   = NULL;
     cJSON* cjson_time   = NULL;
     cJSON* cjson_ntptime1 = NULL;
     cJSON* cjson_ntptime2 = NULL;
    
     uint32_t time_get = 0;
     uint64_t ntptime1 = 0;
     uint64_t ntptime2 = 0;

     cjson_root = cJSON_Parse((char*)msg->payload + 1);
     if (cjson_root == NULL) {
         printf("report reply message parser fail\r\n");
         goto end;
     }

     cjson_time = cJSON_GetObjectItem(cjson_root, "time");
     if (cjson_time == NULL) {
         printf("report reply message parser fail\r\n");
         goto end;
     }
     time_get = cjson_time->valueint;

     cjson_ntptime1 = cJSON_GetObjectItem(cjson_root, "ntptime1");
     if (cjson_ntptime1 == NULL) {
         printf("report reply message parser fail\r\n");
         goto end;
     }
     ntptime1 =  cjson_ntptime1->valuelonglong;

     cjson_ntptime2 = cJSON_GetObjectItem(cjson_root, "ntptime2");
     if (cjson_ntptime2 == NULL) {
         printf("report reply message parser fail\r\n");
         goto end;
     }
     ntptime2 = cjson_ntptime2->valuelonglong;

     printf("time_get:%d\r\n", time_get);
     printf("ntptime1:%lld \r\n", ntptime1);
     printf("ntptime2:%lld \r\n", ntptime2);

    tos_systick_set(ntptime2);
    g_last_time = ntptime2;

    g_sys_status.ntp_ok = 1;
    retry_wait = 0;
 end:
     cJSON_Delete(cjson_root);
     cjson_root = NULL;
     return;
 }

2.3 使用RTC

代码语言:javascript
复制
void get_localtime()
{
    k_tick_t now;
    struct tm *time_info_get;
    //shanghai +8: + 28800
    now = tos_systick_get() / 1000 + 28800 ;
    time_info_get = localtime(&now);
    g_time_info = *time_info_get;
}

void disp_date_time(u8 mode)
{
    char lcd_buf[30] = {0};
    get_localtime();
        
    if(mode)
    {
        sprintf(lcd_buf, "%4d-%02d-%02d", g_time_info.tm_year + 1900, g_time_info.tm_mon + 1, g_time_info.tm_mday);
        LCD_ShowString(0,80,lcd_buf, WHITE, BLACK, 32, 0);
    }    
    sprintf(lcd_buf, "%02d:%02d:%02d", g_time_info.tm_hour, g_time_info.tm_min, g_time_info.tm_sec);
    LCD_ShowString(0,110,lcd_buf, WHITE, BLACK, 32, 0); 
}

3. CJson 64bit支持

cJSON本身不支持64位的整形数据解析和增加,k_tick_t是64bit长整型,需要修改。

主要参照《cJSON支持64位数据解析_zh7152106的博客》实现。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. IOT平台的NTP支持
    • 1)设备开发的系统级Topic
      • 2)腾讯云文档接口描述
      • 2. 实现过程
        • 2.1 设备端 pub/sub topic
          • 2.2 sub 回调函数处理数据
            • 2.3 使用RTC
            • 3. CJson 64bit支持
            相关产品与服务
            物联网开发平台
            腾讯云物联网开发平台(IoT Explorer)是面向智慧生活与产业物联应用的一站式物联网PaaS平台,为各行业用户提供一站式设备智能化服务。平台提供海量设备连接与消息通信能力,基于腾讯连连小程序应用开发能力、音视频能力及AI增值服务,聚合腾讯生态内容能力。提升传统行业设备智能化的效率,降低用户的开发运维成本。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档