Skip to content

Commit

Permalink
Merge pull request #2123 from particle-iot/feature/64-bit-time-t-rtc-…
Browse files Browse the repository at this point in the history
…refactoring

32/64-bit time_t compatibility and RTC HAL refactoring
  • Loading branch information
avtolstoy authored Jun 3, 2020
2 parents 60d01f7 + fd84fc0 commit 009b606
Show file tree
Hide file tree
Showing 48 changed files with 1,344 additions and 529 deletions.
2 changes: 1 addition & 1 deletion build/arm-tools.mk
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ quote="
lt=\<
dollar=$$
arm_gcc_version_str:=$(strip $(shell $(CC) -dumpversion))
expected_version:=5.3.1
expected_version:=9.2.1
#$(info result $(shell test $(quote)$(arm_gcc_version_str)$(quote) $(lt) $(quote)$(expected_version)$(quote);echo $$?))
ifeq ($(shell test $(quote)$(arm_gcc_version_str)$(quote) $(lt) $(quote)$(expected_version)$(quote); echo $$?),0)
$(error "ARM gcc version $(expected_version) or later required, but found $(arm_gcc_version_str)")
Expand Down
3 changes: 2 additions & 1 deletion communication/inc/communication_dynalib.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "dynalib.h"
#include "protocol_selector.h"
#include "hal_platform.h"
#include "time_compat.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -71,7 +72,7 @@ DYNALIB_FN(BASE_IDX + 2, communication, extract_public_ec_key, int(uint8_t*, siz
DYNALIB_FN(BASE_IDX2 + 0, communication, spark_protocol_set_connection_property, int(ProtocolFacade*, unsigned, unsigned, const particle::protocol::connection_properties_t*, void*))
DYNALIB_FN(BASE_IDX2 + 1, communication, spark_protocol_command, int(ProtocolFacade*, ProtocolCommands::Enum, uint32_t, const void*))
DYNALIB_FN(BASE_IDX2 + 2, communication, spark_protocol_time_request_pending, bool(ProtocolFacade*, void*))
DYNALIB_FN(BASE_IDX2 + 3, communication, spark_protocol_time_last_synced, system_tick_t(ProtocolFacade*, time_t*, void*))
DYNALIB_FN(BASE_IDX2 + 3, communication, spark_protocol_time_last_synced, system_tick_t(ProtocolFacade*, time32_t*, time_t*))
DYNALIB_FN(BASE_IDX2 + 4, communication, spark_protocol_get_describe_data, int(ProtocolFacade*, spark_protocol_describe_data*, void*))
DYNALIB_FN(BASE_IDX2 + 5, communication, spark_protocol_post_description, int(ProtocolFacade*, int, void*))
DYNALIB_FN(BASE_IDX2 + 6, communication, spark_protocol_to_system_error, int(int))
Expand Down
5 changes: 3 additions & 2 deletions communication/inc/spark_protocol_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "system_defs.h"
#include "completion_handler.h"
#include "hal_platform.h"
#include "time_compat.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -96,7 +97,7 @@ struct SparkCallbacks
/**
* Sets the time. Time is given in milliseconds since the epoch, UCT.
*/
void (*set_time)(time_t t, unsigned int param, void* reserved);
void (*set_time)(uint32_t t, unsigned int param, void* reserved);

// size == 40

Expand Down Expand Up @@ -191,7 +192,7 @@ void spark_protocol_get_product_details(ProtocolFacade* protocol, product_detail

int spark_protocol_set_connection_property(ProtocolFacade* protocol, unsigned property_id, unsigned data, const particle::protocol::connection_properties_t* conn_prop, void* reserved);
bool spark_protocol_time_request_pending(ProtocolFacade* protocol, void* reserved=NULL);
system_tick_t spark_protocol_time_last_synced(ProtocolFacade* protocol, time_t* tm, void* reserved=NULL);
system_tick_t spark_protocol_time_last_synced(ProtocolFacade* protocol, time32_t* tm32, time_t* tm);

int spark_protocol_to_system_error (int error);

Expand Down
13 changes: 10 additions & 3 deletions communication/src/spark_protocol_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,17 @@ bool spark_protocol_time_request_pending(ProtocolFacade* protocol, void* reserve
(void)reserved;
return protocol->time_request_pending();
}
system_tick_t spark_protocol_time_last_synced(ProtocolFacade* protocol, time_t* tm, void* reserved)
system_tick_t spark_protocol_time_last_synced(ProtocolFacade* protocol, time32_t* tm32, time_t* tm)
{
(void)reserved;
return protocol->time_last_synced(tm);
time_t t;
auto ms = protocol->time_last_synced(&t);
if (tm32) {
*tm32 = (time32_t)t;
}
if (tm) {
*tm = t;
}
return ms;
}

int spark_protocol_get_describe_data(ProtocolFacade* protocol, spark_protocol_describe_data* data, void* reserved)
Expand Down
2 changes: 1 addition & 1 deletion communication/src/timesyncmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class TimeSyncManager
}

template <typename Callback>
bool handle_time_response(time_t tm, system_tick_t mil, Callback set_time) {
bool handle_time_response(uint32_t tm, system_tick_t mil, Callback set_time) {
LOG(INFO, "Received TIME response: %lu", (unsigned long)tm);
set_time(tm, 0, NULL);
expectingResponse_ = false;
Expand Down
4 changes: 2 additions & 2 deletions communication/tests/ConstructorFixture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ bool ConstructorFixture::nothing_to_receive = false;
bool ConstructorFixture::function_called = false;
int ConstructorFixture::variable_to_get = -98765;
bool ConstructorFixture::signal_called_with = false;
time_t ConstructorFixture::set_time_called_with = -1;
int64_t ConstructorFixture::set_time_called_with = -1;
EventHandlerCalledWith ConstructorFixture::event_handlers_called_with[2];

ConstructorFixture::ConstructorFixture()
Expand Down Expand Up @@ -361,7 +361,7 @@ SparkReturnType::Enum ConstructorFixture::mock_variable_type(const char *variabl
return SparkReturnType::INT;
}

void ConstructorFixture::mock_set_time(time_t t, unsigned int, void*)
void ConstructorFixture::mock_set_time(uint32_t t, unsigned int, void*)
{
set_time_called_with = t;
}
Expand Down
4 changes: 2 additions & 2 deletions communication/tests/ConstructorFixture.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ struct ConstructorFixture
static system_tick_t mock_millis(void);
static bool mock_ota_status_check(void);
static SparkReturnType::Enum mock_variable_type(const char *variable_key);
static void mock_set_time(time_t t, unsigned int param, void* reserved);
static time_t set_time_called_with;
static void mock_set_time(uint32_t t, unsigned int param, void* reserved);
static int64_t set_time_called_with;
static EventHandlerCalledWith event_handlers_called_with[2];
static void mock_event_handler_0(const char *event_name, const char *data);
static void mock_event_handler_1(const char *event_name, const char *data);
Expand Down
2 changes: 1 addition & 1 deletion communication/tests/TestSparkProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ SUITE(CoreProtocolConstruction)
core_protocol.handshake();
bytes_received[0] = bytes_sent[0] = 0;
core_protocol.event_loop();
CHECK_EQUAL(1398367917, set_time_called_with);
CHECK_EQUAL(1398367917LL, set_time_called_with);
}

TEST(IsInitializedIsFalse)
Expand Down
18 changes: 11 additions & 7 deletions hal/inc/exrtc_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,30 @@

#if HAL_PLATFORM_EXTERNAL_RTC

#include "rtc_hal.h"
#include "system_tick_hal.h"
#include <stdint.h>
#include <time.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef void (*hal_exrtc_alarm_handler_t)(void* context);
typedef hal_rtc_alarm_handler hal_exrtc_alarm_handler;
typedef hal_rtc_alarm_flags hal_exrtc_alarm_flags;

int hal_exrtc_set_unixtime(time_t unixtime, void* reserved);
time_t hal_exrtc_get_unixtime(void* reserved);
int hal_exrtc_set_unix_alarm(time_t unixtime, hal_exrtc_alarm_handler_t handler, void* context, void* reserved);
int hal_exrtc_cancel_unixalarm(void* reserved);
int hal_exrtc_init(void* reserved);
int hal_exrtc_set_time(const struct timeval* tv, void* reserved);
int hal_exrtc_get_time(struct timeval* tv, void* reserved);
int hal_exrtc_set_alarm(const struct timeval* tv, uint32_t flags, hal_exrtc_alarm_handler handler, void* context, void* reserved);
int hal_exrtc_cancel_alarm(void* reserved);
bool hal_exrtc_time_is_valid(void* reserved);

int hal_exrtc_enable_watchdog(time_t ms, void* reserved);
int hal_exrtc_enable_watchdog(system_tick_t ms, void* reserved);
int hal_exrtc_disable_watchdog(void* reserved);
int hal_exrtc_feed_watchdog(void* reserved);

int hal_exrtc_sleep_timer(time_t ms, void* reserved);
int hal_exrtc_sleep_timer(system_tick_t ms, void* reserved);

int hal_exrtc_calibrate_xt(int adjValue, void* reserved);

Expand Down
31 changes: 20 additions & 11 deletions hal/inc/hal_dynalib.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

#include "dynalib.h"

#include "time_compat.h"

#ifdef DYNALIB_EXPORT
#include "rng_hal.h"
#include "eeprom_hal.h"
Expand Down Expand Up @@ -60,10 +62,13 @@ DYNALIB_FN(BASE_IDX + 1, hal, HAL_Delay_Microseconds, void(uint32_t))
DYNALIB_FN(BASE_IDX + 2, hal, HAL_Timer_Get_Micro_Seconds, system_tick_t(void))
DYNALIB_FN(BASE_IDX + 3, hal, HAL_Timer_Get_Milli_Seconds, system_tick_t(void))

DYNALIB_FN(BASE_IDX + 4, hal, HAL_RTC_Configuration, void(void))
DYNALIB_FN(BASE_IDX + 5, hal, HAL_RTC_Get_UnixTime, time_t(void))
DYNALIB_FN(BASE_IDX + 6, hal, HAL_RTC_Set_UnixTime, void(time_t))
DYNALIB_FN(BASE_IDX + 7, hal, HAL_RTC_Set_UnixAlarm, void(time_t))
DYNALIB_FN(BASE_IDX + 4, hal, hal_rtc_init, void(void))

// These functions are deprecated
DYNALIB_FN(BASE_IDX + 5, hal, hal_rtc_get_unixtime_deprecated, time32_t(void))
DYNALIB_FN(BASE_IDX + 6, hal, hal_rtc_set_unixtime_deprecated, void(time32_t))

DYNALIB_FN(BASE_IDX + 7, hal, hal_rtc_set_alarm, int(const struct timeval*, uint32_t, hal_rtc_alarm_handler, void*, void*))

DYNALIB_FN(BASE_IDX + 8, hal, HAL_EEPROM_Init, void(void))
DYNALIB_FN(BASE_IDX + 9, hal, HAL_EEPROM_Read, uint8_t(uint32_t))
Expand All @@ -72,18 +77,22 @@ DYNALIB_FN(BASE_IDX + 11, hal, HAL_EEPROM_Length, size_t(void))

DYNALIB_FN(BASE_IDX + 12, hal, HAL_disable_irq, int(void))
DYNALIB_FN(BASE_IDX + 13, hal, HAL_enable_irq, void(int))
DYNALIB_FN(BASE_IDX + 14, hal, HAL_RTC_Cancel_UnixAlarm, void(void))
DYNALIB_FN(BASE_IDX + 14, hal, hal_rtc_cancel_alarm, void(void))

DYNALIB_FN(BASE_IDX + 15, hal,HAL_EEPROM_Get, void(uint32_t, void *, size_t))
DYNALIB_FN(BASE_IDX + 16, hal,HAL_EEPROM_Put, void(uint32_t, const void *, size_t))
DYNALIB_FN(BASE_IDX + 17, hal,HAL_EEPROM_Clear, void(void))
DYNALIB_FN(BASE_IDX + 18, hal,HAL_EEPROM_Has_Pending_Erase, bool(void))
DYNALIB_FN(BASE_IDX + 19, hal,HAL_EEPROM_Perform_Pending_Erase, void(void))
DYNALIB_FN(BASE_IDX + 20, hal, HAL_RTC_Time_Is_Valid, uint8_t(void*))
DYNALIB_FN(BASE_IDX + 15, hal, HAL_EEPROM_Get, void(uint32_t, void *, size_t))
DYNALIB_FN(BASE_IDX + 16, hal, HAL_EEPROM_Put, void(uint32_t, const void *, size_t))
DYNALIB_FN(BASE_IDX + 17, hal, HAL_EEPROM_Clear, void(void))
DYNALIB_FN(BASE_IDX + 18, hal, HAL_EEPROM_Has_Pending_Erase, bool(void))
DYNALIB_FN(BASE_IDX + 19, hal, HAL_EEPROM_Perform_Pending_Erase, void(void))
DYNALIB_FN(BASE_IDX + 20, hal, hal_rtc_time_is_valid, bool(void*))

DYNALIB_FN(BASE_IDX + 21, hal, hal_timer_millis, uint64_t(void*))
DYNALIB_FN(BASE_IDX + 22, hal, hal_timer_micros, uint64_t(void*))

DYNALIB_FN(BASE_IDX + 23, hal, hal_rtc_get_time, int(struct timeval*, void*))
DYNALIB_FN(BASE_IDX + 24, hal, hal_rtc_set_time, int(const struct timeval*, void*))


DYNALIB_END(hal)

#undef BASE_IDX
3 changes: 2 additions & 1 deletion hal/inc/hal_dynalib_socket_posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,11 @@ DYNALIB_FN(13, hal_socket, sock_sendto, int(int, const void*, size_t, int, const
DYNALIB_FN(14, hal_socket, sock_socket, int(int, int, int))
DYNALIB_FN(15, hal_socket, sock_fcntl, int(int, int, ...))
DYNALIB_FN(16, hal_socket, sock_poll, int(struct pollfd*, nfds_t, int))
DYNALIB_FN(17, hal_socket, sock_select, int(int, fd_set*, fd_set*, fd_set*, struct timeval*))
DYNALIB_FN(17, hal_socket, sock_select32, int(int, fd_set*, fd_set*, fd_set*, LIBC_TIMEVAL32*))
DYNALIB_FN(18, hal_socket, sock_recvmsg, int(int, struct msghdr*, int))
DYNALIB_FN(19, hal_socket, sock_sendmsg, int(int, const struct msghdr*, int))
DYNALIB_FN(20, hal_socket, sock_ioctl, int(int, long, void*))
DYNALIB_FN(21, hal_socket, sock_select, int(int, fd_set*, fd_set*, fd_set*, struct timeval*))

DYNALIB_END(hal_socket)

Expand Down
26 changes: 20 additions & 6 deletions hal/inc/rtc_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

#include <stdint.h>
#include <time.h>
#include <stdbool.h>
#include "time_compat.h"

/* Exported types ------------------------------------------------------------*/

Expand All @@ -42,13 +44,25 @@
extern "C" {
#endif

void HAL_RTC_Configuration(void);
typedef void (*hal_rtc_alarm_handler)(void* context);

time_t HAL_RTC_Get_UnixTime(void);
void HAL_RTC_Set_UnixTime(time_t value);
void HAL_RTC_Set_UnixAlarm(time_t value);
void HAL_RTC_Cancel_UnixAlarm(void);
uint8_t HAL_RTC_Time_Is_Valid(void* reserved);
typedef enum hal_rtc_alarm_flags {
HAL_RTC_ALARM_FLAG_IN = 0x01 // In provided amount of time, instead of an absolute timestamp
} hal_rtc_alarm_flags;

void hal_rtc_init(void);
int hal_rtc_get_time(struct timeval* tv, void* reserved);
int hal_rtc_set_time(const struct timeval* tv, void* reserved);
bool hal_rtc_time_is_valid(void* reserved);
// XXX: only one alarm and its handler can be registered at a time
int hal_rtc_set_alarm(const struct timeval* tv, uint32_t flags, hal_rtc_alarm_handler handler, void* context, void* reserved);
void hal_rtc_cancel_alarm(void);

// These functions are deprecated and are only used for backwards compatibility
// due to time_t size change
time32_t hal_rtc_get_unixtime_deprecated(void);
void hal_rtc_set_unixtime_deprecated(time32_t value);
//

#ifdef __cplusplus
}
Expand Down
43 changes: 43 additions & 0 deletions hal/network/lwip/socket_hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,37 @@ int sock_getsockname(int s, struct sockaddr* name, socklen_t* namelen) {
}

int sock_getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen) {
#ifdef LIBC_64_BIT_TIME_T
if (optname == SO_SNDTIMEO || optname == SO_RCVTIMEO) {
if (optlen && *optlen == sizeof(LIBC_TIMEVAL32) && optval) {
struct timeval tv = {};
socklen_t sz = sizeof(tv);
int r = lwip_getsockopt(s, level, optname, &tv, &sz);
if (!r) {
LIBC_TIMEVAL32* tv32 = (LIBC_TIMEVAL32*)optval;
tv32->tv_sec = tv.tv_sec;
tv32->tv_usec = tv.tv_usec;
}
return r;
}
}
#endif // LIBC_64_BIT_TIME_T
return lwip_getsockopt(s, level, optname, optval, optlen);
}

int sock_setsockopt(int s, int level, int optname, const void* optval, socklen_t optlen) {
#ifdef LIBC_64_BIT_TIME_T
if (optname == SO_SNDTIMEO || optname == SO_RCVTIMEO) {
if (optlen == sizeof(LIBC_TIMEVAL32) && optval) {
LIBC_TIMEVAL32* tv32 = (LIBC_TIMEVAL32*)optval;
struct timeval tv = {
.tv_sec = tv32->tv_sec,
.tv_usec = tv32->tv_usec
};
return lwip_setsockopt(s, level, optname, &tv, sizeof(tv));
}
}
#endif // LIBC_64_BIT_TIME_T
return lwip_setsockopt(s, level, optname, optval, optlen);
}

Expand Down Expand Up @@ -104,6 +131,22 @@ int sock_select(int nfds, fd_set* readfds, fd_set* writefds,
return lwip_select(nfds, readfds, writefds, exceptfds, timeout);
}

#ifdef LIBC_64_BIT_TIME_T
int sock_select32(int nfds, fd_set* readfds, fd_set* writefds,
fd_set* exceptfds, LIBC_TIMEVAL32* timeout) {
struct timeval tv = {};
if (timeout) {
tv.tv_sec = timeout->tv_sec;
tv.tv_usec = timeout->tv_usec;
return sock_select(nfds, readfds, writefds, exceptfds, &tv);
}
return sock_select(nfds, readfds, writefds, exceptfds, nullptr);
}
#else
int sock_select32(int nfds, fd_set* readfds, fd_set* writefds,
fd_set* exceptfds, LIBC_TIMEVAL32* timeout) __attribute__((alias("sock_select")));
#endif // LIBC_64_BIT_TIME_T

ssize_t sock_recvmsg(int s, struct msghdr *message, int flags) {
return lwip_recvmsg(s, message, flags);
}
Expand Down
6 changes: 6 additions & 0 deletions hal/network/lwip/socket_hal_posix_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define SOCKET_HAL_POSIX_IMPL_H

#include <lwip/sockets.h>
#include "time_compat.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -56,6 +57,11 @@ struct sockaddr_ll {
u8_t sll_addr[8];
};

#ifdef LIBC_64_BIT_TIME_T
int sock_select32(int nfds, fd_set* readfds, fd_set* writefds,
fd_set* exceptfds, LIBC_TIMEVAL32* timeout);
#endif // LIBC_64_BIT_TIME_T

/**
* @}
*
Expand Down
34 changes: 34 additions & 0 deletions hal/shared/time_compat.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2020 Particle Industries, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/

#include "time_compat.h"

#ifndef HAL_TIME_COMPAT_EXCLUDE

struct tm* localtime32_r(const time32_t* timep, struct tm* result) {
if (!timep) {
return nullptr;
}
time_t tmp = *timep;
return localtime_r(&tmp, result);
}

time32_t mktime32(struct tm* tm) {
return (time32_t)mktime(tm);
}

#endif // HAL_TIME_COMPAT_EXCLUDE
Loading

0 comments on commit 009b606

Please sign in to comment.