esp-idf 支持许多posix接口, 其中就包含 time
相关的,我可以通过相关接口获取和修改系统时间
#include "esp_err.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_netif_sntp.h"
#include "esp_sntp.h"
#include "esp_wifi.h"
#include "esp_wifi_default.h"
#include "esp_wifi_types_generic.h"
#include "freertos/FreeRTOS.h"
#include "freertos/idf_additions.h"
#include "freertos/task.h"
#include "nvs_flash.h"
#include "time.h"
#include <assert.h>
#include <lwip/netdb.h>
#include <stdio.h>
static const char *TAG = "HTTPS";
bool isConnected = false;
static EventGroupHandle_t s_wifi_event_group;
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
static int s_retry_num = 0;
static void event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data) {
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT &&
event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (s_retry_num < 5) {
esp_wifi_connect();
s_retry_num += 1;
ESP_LOGI("STA", "retry connect to the AP");
} else {
// 超时
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) {
wifi_event_sta_connected_t *event =
(wifi_event_sta_connected_t *)event_data;
ESP_LOGI("STA", "connected: %s", event->ssid);
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
// 拿到 IP, 应该可以冲浪了
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
}
void wifiInit() {
// 初始化 netif 和事件轮训
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
// 默认配置设置wifi
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
// 注册事件回调
ESP_ERROR_CHECK(esp_event_handler_instance_register(
WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, NULL));
ESP_ERROR_CHECK(esp_event_handler_instance_register(
IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, NULL));
// 初始化 sta 和 netif, 个人感觉是为netif接入sta
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
// sta 配置, 你要连接哪个wifi
wifi_config_t wifi_config = {
.sta =
{
.ssid = "Man_2.4GHz",
.password = "liang114514",
},
};
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
// 开始干活
ESP_ERROR_CHECK(esp_wifi_start());
}
static void time_sync_notification_cb(struct timeval *tv) {
ESP_LOGI(TAG, "Notification of a time synchronization event");
}
static void initialize_sntp(void) {
ESP_LOGI("SNTP", "Initializing SNTP");
esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG("pool.ntp.org");
sntp_set_time_sync_notification_cb(time_sync_notification_cb);
esp_netif_sntp_init(&config);
}
static void obtain_time(void) {
initialize_sntp();
// 等待时间同步
time_t now = 0;
struct tm timeinfo = {0};
int retry = 0;
const int retry_count = 10;
while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET &&
++retry < retry_count) {
ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry,
retry_count);
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
time(&now);
localtime_r(&now, &timeinfo);
}
void app_main() {
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
s_wifi_event_group = xEventGroupCreate();
wifiInit();
// 无限等待, 返回
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE, pdFALSE, portMAX_DELAY);
time_t now;
struct tm timeinfo;
time(&now);
localtime_r(&now, &timeinfo);
if (timeinfo.tm_year < (2016 - 1900)) {
ESP_LOGI(
TAG,
"Time is not set yet. Connecting to WiFi and getting time over NTP.");
obtain_time();
}
// 设置时区(以中国标准时间为例)
setenv("TZ", "CST-8", 1);
tzset();
// 循环输出时间
char strftime_buf[64];
while (1) {
time(&now);
localtime_r(&now, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%d %H:%M:%S",
&timeinfo);
ESP_LOGI(TAG, "Current date/time in Shanghai: %s", strftime_buf);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}