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

2022-08-28 21:47:59 浏览数 (2)

设备的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 failn");
    } else {
        printf("module mqtt sub 2 successn");
    }
    
    // 循环处理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 failn");
                // break;
                continue;
            } else {
                printf("module mqtt pub successn");
            }   
        } 
    }
}

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 failrn");
         goto end;
     }

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

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

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

     printf("time_get:%drn", time_get);
     printf("ntptime1:%lld rn", ntptime1);
     printf("ntptime2:%lld rn", 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, "M-d-d", 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, "d:d:d", 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的博客》实现。

0 人点赞