From d86ceecd8c02cccca1e4a937b7e81e2c694eb2c7 Mon Sep 17 00:00:00 2001 From: Alex Alashkin Date: Tue, 14 Sep 2021 09:28:28 +0300 Subject: [PATCH] Add AzureRTOS basic support --- mongoose.c | 18 +++++++++++++++--- mongoose.h | 45 ++++++++++++++++++++++++++++++++++++++++++++ src/arch.h | 3 +++ src/arch_azurertos.h | 38 +++++++++++++++++++++++++++++++++++++ src/config.h | 4 ++++ src/sock.c | 12 ++++++++++-- src/util.c | 6 +++++- 7 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 src/arch_azurertos.h diff --git a/mongoose.c b/mongoose.c index 371afade..51f00bd0 100644 --- a/mongoose.c +++ b/mongoose.c @@ -2950,6 +2950,8 @@ static void mg_set_non_blocking_mode(SOCKET fd) { setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off)); #elif MG_ARCH == MG_ARCH_FREERTOS_LWIP lwip_fcntl(fd, F_SETFL, O_NONBLOCK); +#elif MG_ARCH == MG_ARCH_AZURERTOS + fcntl(fd, F_SETFL, O_NONBLOCK); #else fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK, FD_CLOEXEC); #endif @@ -2994,7 +2996,7 @@ SOCKET mg_open_listener(const char *url, struct mg_addr *addr) { #endif bind(fd, &usa.sa, slen) == 0 && // NOTE(lsm): FreeRTOS uses backlog value as a connection limit - (type == SOCK_DGRAM || listen(fd, 128) == 0)) { + (type == SOCK_DGRAM || listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE) == 0)) { // In case port was set to 0, get the real port number if (getsockname(fd, &usa.sa, &slen) == 0) { addr->port = usa.sin.sin_port; @@ -3117,7 +3119,7 @@ static void close_conn(struct mg_connection *c) { } static void setsockopts(struct mg_connection *c) { -#if MG_ARCH == MG_ARCH_FREERTOS_TCP +#if MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_AZURERTOS (void) c; #else int on = 1; @@ -3191,6 +3193,12 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) { socklen_t sa_len = sizeof(usa); SOCKET fd = accept(FD(lsn), &usa.sa, &sa_len); if (fd == INVALID_SOCKET) { +#if MG_ARCH == MG_ARCH_AZURERTOS + // AzureRTOS, in non-block socket mode can mark listening socket readable + // even it is not. See comment for 'select' func implementation in nx_bsd.c + // That's not an error, just should try later + if (MG_SOCK_ERRNO != EAGAIN) +#endif LOG(LL_ERROR, ("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERRNO)); #if (!defined(_WIN32) && (MG_ARCH != MG_ARCH_FREERTOS_TCP)) } else if ((long) fd >= FD_SETSIZE) { @@ -4441,7 +4449,7 @@ double mg_time(void) { ((int64_t) ftime.dwHighDateTime << 32)) / 10000000.0) - 11644473600; -#elif MG_ARCH == MG_ARCH_FREERTOS_TCP +#elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_AZURERTOS return mg_millis() / 1000.0; #else struct timeval tv; @@ -4457,6 +4465,8 @@ void mg_usleep(unsigned long usecs) { ets_delay_us(usecs); #elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_FREERTOS_LWIP vTaskDelay(pdMS_TO_TICKS(usecs / 1000)); +#elif MG_ARCH == MG_ARCH_AZURERTOS + tx_thread_sleep((usecs / 1000) * TX_TIMER_TICKS_PER_SECOND); #else usleep((useconds_t) usecs); #endif @@ -4471,6 +4481,8 @@ unsigned long mg_millis(void) { return xTaskGetTickCount() * portTICK_PERIOD_MS; #elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_FREERTOS_LWIP return xTaskGetTickCount() * portTICK_PERIOD_MS; +#elif MG_ARCH == MG_ARCH_AZURERTOS + return tx_time_get() * (1000 /* MS per SEC */ / TX_TIMER_TICKS_PER_SECOND); #else struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); diff --git a/mongoose.h b/mongoose.h index 59c89101..de76cee8 100644 --- a/mongoose.h +++ b/mongoose.h @@ -88,6 +88,10 @@ extern "C" { #define MG_PATH_MAX PATH_MAX #endif +#ifndef MG_SOCK_LISTEN_BACKLOG_SIZE +#define MG_SOCK_LISTEN_BACKLOG_SIZE 128 +#endif + #define MG_ARCH_CUSTOM 0 #define MG_ARCH_UNIX 1 @@ -96,6 +100,7 @@ extern "C" { #define MG_ARCH_ESP8266 4 #define MG_ARCH_FREERTOS_TCP 5 #define MG_ARCH_FREERTOS_LWIP 6 +#define MG_ARCH_AZURERTOS 7 #if !defined(MG_ARCH) #if defined(__unix__) || defined(__APPLE__) @@ -108,6 +113,8 @@ extern "C" { #define MG_ARCH MG_ARCH_ESP32 #elif defined(FREERTOS_IP_H) #define MG_ARCH MG_ARCH_FREERTOS_TCP +#elif defined(AZURE_RTOS_THREADX) +#define MG_ARCH MG_ARCH_AZURERTOS #endif #if !defined(MG_ARCH) @@ -135,6 +142,44 @@ extern "C" { +#if MG_ARCH == MG_ARCH_AZURERTOS + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#ifdef __REDLIB__ +#define va_copy(d,s)__builtin_va_copy(d,s) +#endif + +#define PATH_MAX FX_MAXIMUM_PATH +#define MG_DIRSEP '\\' + +#define socklen_t int +#define closesocket(x) soc_close(x) +#define gmtime_r(a, b) gmtime(a) +#define MG_INT64_FMT "%lld" + +static __inline struct tm *localtime_r(time_t *t, struct tm *tm) { + (void) tm; + return localtime(t); +} + +#undef FOPEN_MAX + +#endif + + #if MG_ARCH == MG_ARCH_ESP32 #include diff --git a/src/arch.h b/src/arch.h index 21339519..1d7d0c0b 100644 --- a/src/arch.h +++ b/src/arch.h @@ -7,6 +7,7 @@ #define MG_ARCH_ESP8266 4 #define MG_ARCH_FREERTOS_TCP 5 #define MG_ARCH_FREERTOS_LWIP 6 +#define MG_ARCH_AZURERTOS 7 #if !defined(MG_ARCH) #if defined(__unix__) || defined(__APPLE__) @@ -19,6 +20,8 @@ #define MG_ARCH MG_ARCH_ESP32 #elif defined(FREERTOS_IP_H) #define MG_ARCH MG_ARCH_FREERTOS_TCP +#elif defined(AZURE_RTOS_THREADX) +#define MG_ARCH MG_ARCH_AZURERTOS #endif #if !defined(MG_ARCH) diff --git a/src/arch_azurertos.h b/src/arch_azurertos.h new file mode 100644 index 00000000..633cf33f --- /dev/null +++ b/src/arch_azurertos.h @@ -0,0 +1,38 @@ +#pragma once + +#if MG_ARCH == MG_ARCH_AZURERTOS + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#ifdef __REDLIB__ +#define va_copy(d,s)__builtin_va_copy(d,s) +#endif + +#define PATH_MAX FX_MAXIMUM_PATH +#define MG_DIRSEP '\\' + +#define socklen_t int +#define closesocket(x) soc_close(x) +#define gmtime_r(a, b) gmtime(a) +#define MG_INT64_FMT "%lld" + +static __inline struct tm *localtime_r(time_t *t, struct tm *tm) { + (void) tm; + return localtime(t); +} + +#undef FOPEN_MAX + +#endif diff --git a/src/config.h b/src/config.h index a7c54913..645dea42 100644 --- a/src/config.h +++ b/src/config.h @@ -62,3 +62,7 @@ #ifndef MG_PATH_MAX #define MG_PATH_MAX PATH_MAX #endif + +#ifndef MG_SOCK_LISTEN_BACKLOG_SIZE +#define MG_SOCK_LISTEN_BACKLOG_SIZE 128 +#endif diff --git a/src/sock.c b/src/sock.c index f72bd5b6..4c12064a 100644 --- a/src/sock.c +++ b/src/sock.c @@ -120,6 +120,8 @@ static void mg_set_non_blocking_mode(SOCKET fd) { setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off)); #elif MG_ARCH == MG_ARCH_FREERTOS_LWIP lwip_fcntl(fd, F_SETFL, O_NONBLOCK); +#elif MG_ARCH == MG_ARCH_AZURERTOS + fcntl(fd, F_SETFL, O_NONBLOCK); #else fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK, FD_CLOEXEC); #endif @@ -164,7 +166,7 @@ SOCKET mg_open_listener(const char *url, struct mg_addr *addr) { #endif bind(fd, &usa.sa, slen) == 0 && // NOTE(lsm): FreeRTOS uses backlog value as a connection limit - (type == SOCK_DGRAM || listen(fd, 128) == 0)) { + (type == SOCK_DGRAM || listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE) == 0)) { // In case port was set to 0, get the real port number if (getsockname(fd, &usa.sa, &slen) == 0) { addr->port = usa.sin.sin_port; @@ -287,7 +289,7 @@ static void close_conn(struct mg_connection *c) { } static void setsockopts(struct mg_connection *c) { -#if MG_ARCH == MG_ARCH_FREERTOS_TCP +#if MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_AZURERTOS (void) c; #else int on = 1; @@ -361,6 +363,12 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) { socklen_t sa_len = sizeof(usa); SOCKET fd = accept(FD(lsn), &usa.sa, &sa_len); if (fd == INVALID_SOCKET) { +#if MG_ARCH == MG_ARCH_AZURERTOS + // AzureRTOS, in non-block socket mode can mark listening socket readable + // even it is not. See comment for 'select' func implementation in nx_bsd.c + // That's not an error, just should try later + if (MG_SOCK_ERRNO != EAGAIN) +#endif LOG(LL_ERROR, ("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERRNO)); #if (!defined(_WIN32) && (MG_ARCH != MG_ARCH_FREERTOS_TCP)) } else if ((long) fd >= FD_SETSIZE) { diff --git a/src/util.c b/src/util.c index 8e3626a8..9ccff224 100644 --- a/src/util.c +++ b/src/util.c @@ -313,7 +313,7 @@ double mg_time(void) { ((int64_t) ftime.dwHighDateTime << 32)) / 10000000.0) - 11644473600; -#elif MG_ARCH == MG_ARCH_FREERTOS_TCP +#elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_AZURERTOS return mg_millis() / 1000.0; #else struct timeval tv; @@ -329,6 +329,8 @@ void mg_usleep(unsigned long usecs) { ets_delay_us(usecs); #elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_FREERTOS_LWIP vTaskDelay(pdMS_TO_TICKS(usecs / 1000)); +#elif MG_ARCH == MG_ARCH_AZURERTOS + tx_thread_sleep((usecs / 1000) * TX_TIMER_TICKS_PER_SECOND); #else usleep((useconds_t) usecs); #endif @@ -343,6 +345,8 @@ unsigned long mg_millis(void) { return xTaskGetTickCount() * portTICK_PERIOD_MS; #elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_FREERTOS_LWIP return xTaskGetTickCount() * portTICK_PERIOD_MS; +#elif MG_ARCH == MG_ARCH_AZURERTOS + return tx_time_get() * (1000 /* MS per SEC */ / TX_TIMER_TICKS_PER_SECOND); #else struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts);