Skip to content

Commit

Permalink
Add support for selecting hardware RTC as time source (#342)
Browse files Browse the repository at this point in the history
- move code from corlib DateTime to ChibiOS level that returns time from systicks or RTC
(thanks to @MikroBusNet)
- rename HAL_Time_FromSystemTime to HAL_Time_ConvertFromSystemTime for clarity
- add CMake option to allow specifing the inclusion of hardware RTC
- add target_platform.h config file for ChibiOS nanoCLR to use CMake option for RTC subsystem
- update halconf.h files on all platforms to use CMake option for RTC subsystem
- general update of code files, CMakes and nanoCLR accordingly
- update CMake variants template to include NF_FEATURE_RTC option
- update Travis CI script to include RTC on all targets
- fixes #340

Signed-off-by: José Simões <[email protected]>
  • Loading branch information
josesimoes authored Jun 1, 2017
1 parent 0b4c46c commit e09977b
Show file tree
Hide file tree
Showing 23 changed files with 207 additions and 443 deletions.
12 changes: 6 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ matrix:
- env: TRAVIS_EMPTY_JOB_WORKAROUND=true

include:
- env: CMAKE_OPTIONS="-DTOOLCHAIN_PREFIX=/home/travis/gcc-arm-none-eabi-5_2-2015q4 -DCHIBIOS_BOARD=ST_STM32F4_DISCOVERY -DTARGET_SERIES=STM32F4xx -DUSE_FPU=TRUE -DCMAKE_BUILD_TYPE=MinSizeRel -DNF_FEATURE_DEBUGGER=TRUE "
- env: CMAKE_OPTIONS="-DTOOLCHAIN_PREFIX=/home/travis/gcc-arm-none-eabi-5_2-2015q4 -DCHIBIOS_BOARD=ST_STM32F429I_DISCOVERY -DTARGET_SERIES=STM32F4xx -DUSE_FPU=TRUE -DCMAKE_BUILD_TYPE=MinSizeRel -DNF_FEATURE_DEBUGGER=TRUE "
- env: CMAKE_OPTIONS="-DTOOLCHAIN_PREFIX=/home/travis/gcc-arm-none-eabi-5_2-2015q4 -DCHIBIOS_BOARD=ST_NUCLEO64_F091RC -DTARGET_SERIES=STM32F0xx -DCMAKE_BUILD_TYPE=MinSizeRel -DNF_FEATURE_DEBUGGER=TRUE "
- env: CMAKE_OPTIONS="-DTOOLCHAIN_PREFIX=/home/travis/gcc-arm-none-eabi-5_2-2015q4 -DCHIBIOS_BOARD=ST_NUCLEO144_F746ZG -DTARGET_SERIES=STM32F7xx -DUSE_FPU=TRUE -DCMAKE_BUILD_TYPE=MinSizeRel -DNF_FEATURE_DEBUGGER=TRUE "
- env: CMAKE_OPTIONS="-DTOOLCHAIN_PREFIX=/home/travis/gcc-arm-none-eabi-5_2-2015q4 -DCHIBIOS_BOARD=MBN_QUAIL -DTARGET_SERIES=STM32F4xx -DUSE_FPU=TRUE -DCMAKE_BUILD_TYPE=MinSizeRel -DNF_FEATURE_DEBUGGER=TRUE "
- env: CMAKE_OPTIONS="-DTOOLCHAIN_PREFIX=/home/travis/gcc-arm-none-eabi-5_2-2015q4 -DCHIBIOS_BOARD=ST_STM32F769I_DISCOVERY -DTARGET_SERIES=STM32F7xx -DUSE_FPU=TRUE -DCMAKE_BUILD_TYPE=MinSizeRel -DNF_FEATURE_DEBUGGER=TRUE "
- env: CMAKE_OPTIONS="-DTOOLCHAIN_PREFIX=/home/travis/gcc-arm-none-eabi-5_2-2015q4 -DCHIBIOS_BOARD=ST_STM32F4_DISCOVERY -DTARGET_SERIES=STM32F4xx -DUSE_FPU=TRUE -DCMAKE_BUILD_TYPE=MinSizeRel -DNF_FEATURE_DEBUGGER=TRUE -DNF_FEATURE_RTC=ON "
- env: CMAKE_OPTIONS="-DTOOLCHAIN_PREFIX=/home/travis/gcc-arm-none-eabi-5_2-2015q4 -DCHIBIOS_BOARD=ST_STM32F429I_DISCOVERY -DTARGET_SERIES=STM32F4xx -DUSE_FPU=TRUE -DCMAKE_BUILD_TYPE=MinSizeRel -DNF_FEATURE_DEBUGGER=TRUE -DNF_FEATURE_RTC=ON "
- env: CMAKE_OPTIONS="-DTOOLCHAIN_PREFIX=/home/travis/gcc-arm-none-eabi-5_2-2015q4 -DCHIBIOS_BOARD=ST_NUCLEO64_F091RC -DTARGET_SERIES=STM32F0xx -DCMAKE_BUILD_TYPE=MinSizeRel -DNF_FEATURE_DEBUGGER=TRUE -DNF_FEATURE_RTC=ON "
- env: CMAKE_OPTIONS="-DTOOLCHAIN_PREFIX=/home/travis/gcc-arm-none-eabi-5_2-2015q4 -DCHIBIOS_BOARD=ST_NUCLEO144_F746ZG -DTARGET_SERIES=STM32F7xx -DUSE_FPU=TRUE -DCMAKE_BUILD_TYPE=MinSizeRel -DNF_FEATURE_DEBUGGER=TRUE -DNF_FEATURE_RTC=ON "
- env: CMAKE_OPTIONS="-DTOOLCHAIN_PREFIX=/home/travis/gcc-arm-none-eabi-5_2-2015q4 -DCHIBIOS_BOARD=MBN_QUAIL -DTARGET_SERIES=STM32F4xx -DUSE_FPU=TRUE -DCMAKE_BUILD_TYPE=MinSizeRel -DNF_FEATURE_DEBUGGER=TRUE -DNF_FEATURE_RTC=ON "
- env: CMAKE_OPTIONS="-DTOOLCHAIN_PREFIX=/home/travis/gcc-arm-none-eabi-5_2-2015q4 -DCHIBIOS_BOARD=ST_STM32F769I_DISCOVERY -DTARGET_SERIES=STM32F7xx -DUSE_FPU=TRUE -DCMAKE_BUILD_TYPE=MinSizeRel -DNF_FEATURE_DEBUGGER=TRUE -DNF_FEATURE_RTC=ON "

## cache GCC toolchain to speedup next builds
cache:
Expand Down
2 changes: 1 addition & 1 deletion CMake/Modules/FindNF_CoreCLR.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ set(NF_CoreCLR_SRCS
Messaging_stub.cpp

# HAL
HAL_Time.cpp
nanoHAL_Time.cpp

# PAL
nanoPAL_BlockStorage.c
Expand Down
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,16 @@ if(NF_FEATURE_DEBUGGER)
endif()
endif()

#################################################################
# RTC (real time clock) (default is OFF so RTC is NOT included)
option(NF_FEATURE_RTC "option to use hardware RTC")

if(NF_FEATURE_RTC)
set(HAL_USE_RTC_OPTION TRUE CACHE INTERNAL "NF feature RTC")
else()
set(HAL_USE_RTC_OPTION FALSE CACHE INTERNAL "NF feature RTC")
endif()

#################################################################

#################################################################
Expand Down
6 changes: 4 additions & 2 deletions cmake-variants.TEMPLATE.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
"CHIBIOS_SOURCE" : "<path-to-chibios-source-mind-the-forward-slash>",
"CHIBIOS_BOARD" : "<valid-chibios-board-name-from-boards-collection>",
"NF_FEATURE_DEBUGGER" : "TRUE-to-include-nF-debugger",
"API_Windows.Devices.Gpio" : "OFF"
"NF_FEATURE_RTC" : "OFF-default-ON-to-enable-hardware-RTC",
"API_Windows.Devices.Gpio" : "OFF-default-ON-to-add-this-API"
}
},
"OPTION2_NAME_HERE": {
Expand All @@ -51,7 +52,8 @@
"CHIBIOS_SOURCE" : "<path-to-chibios-source-mind-the-forward-slash>",
"CHIBIOS_BOARD" : "<valid-chibios-board-name-from-boards-collection>",
"NF_FEATURE_DEBUGGER" : "TRUE-to-include-nF-debugger",
"API_Windows.Devices.Gpio" : "OFF"
"NF_FEATURE_RTC" : "OFF-default-ON-to-enable-hardware-RTC",
"API_Windows.Devices.Gpio" : "OFF-default-ON-to-add-this-API"
}
},
"default$": "",
Expand Down
36 changes: 36 additions & 0 deletions docs/architecture/date-and-time.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Date and Time

**About this document**

This document describes how **nanoFramework** handles Date & Time and the available option regarding this matter.


## UTC and local time

Time (and date) is fundamental for the inner works of **nanoFramework**. But an application running on top of it can make use of it, or not, thus making relevant the discussion and evaluation of the related features and associated code.
Because **nanoFramework** runs on constrained resources platforms inclusion of features that increase both RAM and FLASH usage has to be considered and evaluated.

[`DateTime`](https://msdn.microsoft.com/en-us/library/system.datetime(v=vs.110).aspx) supports the use of Local and UTC times by its [`DateTime.Kind`](https://msdn.microsoft.com/en-us/library/system.datetime.kind(v=vs.110).aspx) property. Supporting this requires adding several _blocks_ such as: an API for setting the platform timezone, handling the huge number of available timezones, managing the daylight savings changes, manage conversion to/from the different kinds, etc.

Considering all the above, **nanoFramework** addresses this matter providing the _absolute minimal viable_ options.
There is support for `DateTime` (obviously) but all DateTime are considered UTC. There is no support for `DateTime.Kind.Local`, setting timezone or converting to/from the different kinds.
If an application requires this, it has to implement it at its own level.


## Time source

The _time base_ source is, by default, the `SysTick` available in the CMSIS RTOS API.
This is the _source_ of the time when a `DateTime` object is instantiated.

Because almost all hardware platforms capable of running **nanoFramework** include an hardware [RTC](https://en.wikipedia.org/wiki/Real-time_clock) this peripheral can be used as the _source_ for time objects.
Note that for all other internals of **nanoFramework** the CMSIS RTOS API `SysTick` keeps being used as the time base.

This option is exposed to the board designer by the `NF_FEATURE_RTC` configuration option. Setting it to `ON` when calling CMake brings in the RTC subsystem and all the calls to `DateTime` make use of the time base provided by this peripheral.


## RTC and hardware

Leveraging the RTC hardware peripheral allows several interesting/valuable features:
- more accurate timekeeping (when compared with a regular timer);
- possibility for timekeeping in sleep/deep sleep modes;
- setting alarms to wake-up the system at a future time;
38 changes: 8 additions & 30 deletions src/CLR/CorLib/corlib_native_System_DateTime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,25 +176,10 @@ HRESULT Library_corlib_native_System_DateTime::get_UtcNow___STATIC__SystemDateTi
NATIVE_PROFILE_CLR_CORE();
NANOCLR_HEADER();

// TODO: move to target platform layer
//CLR_INT64* pRes = NewObject( stack );
//SYSTEMTIME st;
//RTCDateTime _dateTime;

//rtcGetTime(&RTCD1, &_dateTime);
//st.wMilliseconds =(unsigned short) (_dateTime.millisecond % 1000);
//_dateTime.millisecond /= 1000;
//st.wSecond = (unsigned short) (_dateTime.millisecond % 60);
//_dateTime.millisecond /= 60;
//st.wMinute = (unsigned short) (_dateTime.millisecond % 60);
//_dateTime.millisecond /= 60;
//st.wMinute = (unsigned short) (_dateTime.millisecond % 24);
//st.wDay = (unsigned short) _dateTime.day;
//st.wMonth = (unsigned short) _dateTime.month;
//st.wYear = (unsigned short) _dateTime.year;
//st.wDayOfWeek = (unsigned short) _dateTime.dayofweek;

//*pRes = HAL_Time_FromSystemTime( &st );
CLR_INT64* pRes = NewObject( stack );

// request full date&time
*pRes = HAL_Time_CurrentDateTime(false) | s_UTCMask;

NANOCLR_NOCLEANUP_NOLABEL();
}
Expand All @@ -204,17 +189,10 @@ HRESULT Library_corlib_native_System_DateTime::get_Today___STATIC__SystemDateTim
NATIVE_PROFILE_CLR_CORE();
NANOCLR_HEADER();

// TODO: move to target platform layer
// CLR_INT64* pRes = NewObject( stack );
//SYSTEMTIME st;
// RTCDateTime _dateTime;

// rtcGetTime(&RTCD1, &_dateTime);
// st.wDay = (unsigned short) _dateTime.day;
// st.wMonth = (unsigned short) _dateTime.month;
// st.wYear = (unsigned short) _dateTime.year;
CLR_INT64* pRes = NewObject( stack );

// *pRes = HAL_Time_FromSystemTime( &st );
// request date part only
*pRes = HAL_Time_CurrentDateTime(true) | s_UTCMask;

NANOCLR_NOCLEANUP_NOLABEL();
}
Expand Down Expand Up @@ -293,6 +271,6 @@ void Library_corlib_native_System_DateTime::Compress( CLR_RT_StackFrame& stack,

if(val)
{
*val = HAL_Time_FromSystemTime( &st );
*val = HAL_Time_ConvertFromSystemTime( &st );
}
}
2 changes: 1 addition & 1 deletion src/CLR/Core/CLR_RT_HeapBlock_Timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ void CLR_RT_HeapBlock_Timer::AdjustNextFixedExpire( const SYSTEMTIME& systemTime
}

st.wMilliseconds = 0;
baseTime = HAL_Time_FromSystemTime( &st );
baseTime = HAL_Time_ConvertFromSystemTime( &st );

m_timeExpire = fNext ? baseTime + add : baseTime;
m_timeFrequency = add;
Expand Down
10 changes: 9 additions & 1 deletion src/HAL/Include/nanoHAL_Time.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@

signed long long HAL_Time_SysTicksToTime(unsigned int sysTicks);

/// <summary>
/// System time and date for DateTime managed class.
/// This value will be provided by the system tick or from an RTC if hardware support exists and if the board designer has enabled it in the configuration options.
/// The datePartOnly allows returning only the date part with the time fields zeroed.
/// </summary>
/// <returns>Returns current time in 100ns elapsed since 1/1/1601:00:00:00.000 UTC.</returns>
signed long long HAL_Time_CurrentDateTime(bool datePartOnly);

/// <summary>
/// Time according to this system.
/// </summary>
Expand Down Expand Up @@ -80,7 +88,7 @@ HRESULT HAL_Time_AccDaysInMonth(signed int year, signed int month, signed int* d
/// Converts SYSTEMTIME structure to 64bit time, which is assumed as an offset from 1/1/1601:00:00:00.000 in 100ns.
/// </summary>
/// <returns>Time value.</returns>
signed long long HAL_Time_FromSystemTime(const SYSTEMTIME* systemTime);
signed long long HAL_Time_ConvertFromSystemTime(const SYSTEMTIME* systemTime);

/// APIs to convert between types
// FIXME bool HAL_Time_TimeSpanToStringEx( const signed long long& ticks, char*& buf, size_t& len );
Expand Down
5 changes: 4 additions & 1 deletion src/HAL/HAL_Time.cpp → src/HAL/nanoHAL_Time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ signed long long HAL_Time_CurrentTime()
return HAL_Time_SysTicksToTime( HAL_Time_CurrentSysTicks() );
};

signed long long HAL_Time_FromSystemTime(const SYSTEMTIME* systemTime)
/// <summary>
/// Converts a SYSTEMTIME value to HAL time value
/// </summary>
signed long long HAL_Time_ConvertFromSystemTime(const SYSTEMTIME* systemTime)
{
signed long long r = YEARS_TO_DAYS(systemTime->wYear) + MONTH_TO_DAYS(systemTime->wYear, systemTime->wMonth) + systemTime->wDay - 1;
r = (((( (r * HOURS_TO_DAY) + systemTime->wHour) * MINUTES_TO_HOUR + systemTime->wMinute) * SECONDS_TO_MINUTES + systemTime->wSecond ) * MILLISECONDS_TO_SECONDS + systemTime->wMilliseconds) * TIMEUNIT_TO_MILLISECONDS;
Expand Down
8 changes: 5 additions & 3 deletions targets/CMSIS-OS/ChibiOS/MBN_QUAIL/nanoCLR/halconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#ifndef HALCONF_H
#define HALCONF_H

#include <target_platform.h>
#include "mcuconf.h"

/**
Expand Down Expand Up @@ -107,9 +108,10 @@
/**
* @brief Enables the RTC subsystem.
*/
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
#define HAL_USE_RTC TRUE
#endif
// this option is set at target_board.h (from config file)
// #if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
// #define HAL_USE_RTC TRUE
// #endif

/**
* @brief Enables the SDC subsystem.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#ifndef HALCONF_H
#define HALCONF_H

#include <target_platform.h>
#include "mcuconf.h"

/**
Expand Down Expand Up @@ -114,9 +115,10 @@
/**
* @brief Enables the RTC subsystem.
*/
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
#define HAL_USE_RTC TRUE
#endif
// this option is set at target_board.h (from config file)
// #if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
// #define HAL_USE_RTC TRUE
// #endif

/**
* @brief Enables the SDC subsystem.
Expand Down
8 changes: 5 additions & 3 deletions targets/CMSIS-OS/ChibiOS/ST_NUCLEO64_F091RC/nanoCLR/halconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#ifndef HALCONF_H
#define HALCONF_H

#include <target_platform.h>
#include "mcuconf.h"

/**
Expand Down Expand Up @@ -107,9 +108,10 @@
/**
* @brief Enables the RTC subsystem.
*/
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
#define HAL_USE_RTC TRUE
#endif
// this option is set at target_board.h (from config file)
// #if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
// #define HAL_USE_RTC TRUE
// #endif

/**
* @brief Enables the SDC subsystem.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#ifndef HALCONF_H
#define HALCONF_H

#include <target_platform.h>
#include "mcuconf.h"

/**
Expand Down Expand Up @@ -107,9 +108,10 @@
/**
* @brief Enables the RTC subsystem.
*/
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
#define HAL_USE_RTC TRUE
#endif
// this option is set at target_board.h (from config file)
// #if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
// #define HAL_USE_RTC TRUE
// #endif

/**
* @brief Enables the SDC subsystem.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#ifndef HALCONF_H
#define HALCONF_H

#include <target_platform.h>
#include "mcuconf.h"

/**
Expand Down Expand Up @@ -107,9 +108,10 @@
/**
* @brief Enables the RTC subsystem.
*/
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
#define HAL_USE_RTC TRUE
#endif
// this option is set at target_board.h (from config file)
// #if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
// #define HAL_USE_RTC TRUE
// #endif

/**
* @brief Enables the SDC subsystem.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#ifndef HALCONF_H
#define HALCONF_H

#include <target_platform.h>
#include "mcuconf.h"

/**
Expand Down Expand Up @@ -114,9 +115,10 @@
/**
* @brief Enables the RTC subsystem.
*/
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
#define HAL_USE_RTC TRUE
#endif
// this option is set at target_board.h (from config file)
// #if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
// #define HAL_USE_RTC TRUE
// #endif

/**
* @brief Enables the SDC subsystem.
Expand Down
Loading

0 comments on commit e09977b

Please sign in to comment.