/* The example of esp-free-rtos
*
* This sample code is in the public domain.
*/
#include <stdlib.h>
#include <string.h>
#include "espressif/esp_common.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "esp8266.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"
#define SNTP_SERVER "ntp.nict.jp"
//#define SNTP_SERVER "pool.ntp.org"
#define SNTP_PORT 123
#define
SNTP_OFFSET_LI_VN_MODE 0
#define
SNTP_LI_MASK
0xC0
#define
SNTP_LI_NO_WARNING
0x00
#define SNTP_LI_LAST_MINUTE_61_SEC 0x01
#define SNTP_LI_LAST_MINUTE_59_SEC 0x02
#define SNTP_LI_ALARM_CONDITION
0x03 /* (clock not synchronized) */
#define
SNTP_VERSION_MASK
0x38
#define
SNTP_VERSION
(4/* NTP Version 4*/<<3)
#define
SNTP_MODE_MASK
0x07
#define
SNTP_MODE_CLIENT
0x03
#define
SNTP_MODE_SERVER
0x04
#define
SNTP_MODE_BROADCAST
0x05
/* number of seconds between 1900 and 1970 */
#define
DIFF_SEC_1900_1970
(2208988800UL)
int TaskIsAlive = 1;
SemaphoreHandle_t xSemaphore;
void sntp_update_rtc(time_t t, uint32_t us);
void showNetworkInfo() {
uint8_t hwaddr[6];
if (sdk_wifi_get_macaddr(STATION_IF, hwaddr)) {
printf("[%s] MAC
address="MACSTR"\n",pcTaskGetName(0),MAC2STR(hwaddr));
}
struct ip_info info;
if (sdk_wifi_get_ip_info(STATION_IF, &info)) {
printf("[%s] IP
address="IPSTR"\n",pcTaskGetName(0),IP2STR(&info.ip));
printf("[%s]
Netmask="IPSTR"\n",pcTaskGetName(0),IP2STR(&info.netmask));
printf("[%s]
Gateway="IPSTR"\n",pcTaskGetName(0),IP2STR(&info.gw));
}
}
// NTP Client Task
void task1(void *pvParameters)
{
typedef struct
{
uint8_t
li_vn_mode; // Eight bits.
li, vn, and mode.
// li. Two bits. Leap indicator.
// vn. Three bits. Version number of the
protocol.
// mode. Three bits. Client will pick mode 3 for client.
uint8_t
stratum;
// Eight bits. Stratum level of the local clock.
uint8_t
poll;
// Eight bits. Maximum interval between successive
messages.
uint8_t
precision; // Eight
bits. Precision of the local clock.
uint32_t
rootDelay; // 32 bits. Total
round trip delay time.
uint32_t rootDispersion; // 32 bits.
Max error aloud from primary clock source.
uint32_t
refId;
// 32 bits. Reference clock identifier.
uint32_t
refTm_s; // 32
bits. Reference time-stamp seconds.
uint32_t
refTm_f; // 32
bits. Reference time-stamp fraction of a second.
uint32_t
origTm_s; // 32 bits.
Originate time-stamp seconds.
uint32_t
origTm_f; // 32 bits.
Originate time-stamp fraction of a second.
uint32_t
rxTm_s; //
32 bits. Received time-stamp seconds.
uint32_t
rxTm_f; //
32 bits. Received time-stamp fraction of a second.
uint32_t
txTm_s; //
32 bits and the most important field the client cares
about. Transmit time-stamp seconds.
uint32_t
txTm_f; //
32 bits. Transmit time-stamp fraction of a second.
}
ntp_packet;
// Total: 384 bits or 48 bytes.
TickType_t nowTick;
nowTick = xTaskGetTickCount();
printf("[%s:%d] Start\n",pcTaskGetName(0),nowTick);
/* Wait until we have joined AP and are assigned an
IP */
int wifiStatus;
while (1) {
wifiStatus =
sdk_wifi_station_get_connect_status();
nowTick = xTaskGetTickCount();
printf("[%s:%d]
wifiStatus=%d\n",pcTaskGetName(0),nowTick,wifiStatus);
//if
(sdk_wifi_station_get_connect_status() == STATION_GOT_IP)
break;
if (wifiStatus == STATION_GOT_IP)
break;
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
nowTick = xTaskGetTickCount();
printf("[%s:%d] Connected to
AP\n",pcTaskGetName(0),nowTick);
showNetworkInfo();
/* Now start task2 */
xSemaphoreGive(xSemaphore);
/* Convert URL to IP */
struct hostent *server; // Server data structure.
server = gethostbyname(SNTP_SERVER);
LWIP_ASSERT("server != NULL", server != NULL);
/* set up address to connect to */
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
//addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
//addr.sin_port = PP_HTONS(SNTP_PORT);
addr.sin_port = htons(SNTP_PORT);
//addr.sin_addr.s_addr =
inet_addr("129.250.35.250");
// Copy the server's IP address to the server
address structure.
bcopy( ( char* )server->h_addr, ( char* )
&addr.sin_addr.s_addr, server->h_length );
/* create the socket */
int fd;
int ret;
fd = lwip_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP
); // Create a UDP socket.
LWIP_ASSERT("fd >= 0", fd >= 0);
/* set NTP packet */
ntp_packet packet;
memset( &packet, 0, sizeof( ntp_packet ) );
packet.li_vn_mode = SNTP_LI_NO_WARNING |
SNTP_VERSION | SNTP_MODE_CLIENT;
/* send NTP packet */
ret = lwip_sendto(fd, (char*)&packet,
sizeof(ntp_packet), 0, (struct sockaddr
*)&addr,sizeof(addr));
LWIP_ASSERT("ret == 48", ret == 48);
nowTick = xTaskGetTickCount();
printf("[%s:%d] lwip_sendto
ret=%d\n",pcTaskGetName(0),nowTick,ret);
/* recv NTP packet */
ret = lwip_recv(fd, (char*) &packet,
sizeof(ntp_packet), 0);
LWIP_ASSERT("ret > 0", ret > 0);
nowTick = xTaskGetTickCount();
printf("[%s:%d] lwip_recv
ret=%d\n",pcTaskGetName(0),nowTick,ret);
// NTPタイムをUNIXタイムに変換する
// NTPタイムは1900年1月1日0時0分からはじまる積算秒数
// UNITタイムは1970年1月1日0時0分からはじまる積算秒数
// 1900年から1970年の70年を秒で表すと2208988800秒になる
// NTPタイムから70年分の秒を引くとUNIXタイムが得られる
nowTick = xTaskGetTickCount();
uint32_t ntpTime = ntohl( packet.txTm_s ); // NTP
Time-stamp seconds.
printf("[%s:%d] The NTP Time =
%u\n",pcTaskGetName(0),nowTick,ntpTime);
// グリニッジ標準時間
time_t txTm = ntpTime - DIFF_SEC_1900_1970; // UNIT
Time-stamp seconds.
//printf("[%s:%d]
txTm=%ld\n",pcTaskGetName(0),nowTick,(unsigned long)txTm);
printf("[%s:%d] The UTC Time:
%s",pcTaskGetName(0),nowTick,ctime( ( const time_t* )
&txTm ) );
// 日本標準時にあわせるために+9時間しておく
txTm = txTm + (9 * 60 * 60);
printf("[%s:%d] The JST Time:
%s",pcTaskGetName(0),nowTick,ctime( ( const time_t* )
&txTm ) );
#if 0
uint32_t txUs = ntohl( packet.txTm_f ) / 4295;
//printf("[%s:%d]
txUs=%u\n",pcTaskGetName(0),nowTick,txUs);
sntp_update_rtc(txTm, txUs);
#endif
/* Make timeval */
struct timeval now = { .tv_sec = txTm };
/* Set the time as well as a timezone */
/*
EXTRA_COMPONENTS =
extras/timekeeping
*/
settimeofday(&now, NULL);
/* close */
ret = lwip_close(fd);
LWIP_ASSERT("ret == 0", ret == 0);
TaskIsAlive = 0;
vTaskDelete( NULL );
}
// Clock Task
void task2(void *pvParameters)
{
TickType_t nowTick;
nowTick = xTaskGetTickCount();
printf("[%s:%d] Start\n",pcTaskGetName(0),nowTick);
while(1) {
nowTick = xTaskGetTickCount();
time_t ts = time(NULL);
printf("[%s:%d]
%s",pcTaskGetName(0),nowTick,ctime(&ts));
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
vTaskDelete( NULL );
}
// Dummy Task
void task3(void *pvParameters)
{
TickType_t nowTick;
nowTick = xTaskGetTickCount();
printf("[%s:%d] Start\n",pcTaskGetName(0),nowTick);
xSemaphoreTake(xSemaphore, portMAX_DELAY);
nowTick = xTaskGetTickCount();
printf("[%s:%d] Take
Semaphore\n",pcTaskGetName(0),nowTick);
while(TaskIsAlive) {
nowTick = xTaskGetTickCount();
printf("[%s:%d]
Running...\n",pcTaskGetName(0),nowTick);
vTaskDelay(1);
}
vTaskDelete( NULL );
}
void user_init(void)
{
uart_set_baud(0, 115200);
printf("SDK version:%s\n",
sdk_system_get_sdk_version());
printf("pcTaskGetName=%s\n",pcTaskGetName(0));
/* Create Semaphore */
xSemaphore = xSemaphoreCreateBinary();
/* Check everything was created. */
configASSERT( xSemaphore );
xTaskCreate(task1, "NTP", 384, NULL, 2, NULL);
xTaskCreate(task2, "Clock", 256, NULL, 2, NULL);
xTaskCreate(task3, "Dummy", 256, NULL, 2, NULL);
}
|