From 4884fe5a222bfe2fce4e4ec17b2f072aab4f3262 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sim=C3=B5es?= Date: Mon, 6 Mar 2017 19:28:29 +0000 Subject: [PATCH] Implement HAL_Time_TicksToTimeMilliSec (#145) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Implement HAL_Time_TicksToTimeMicroSec - rename function to HAL_Time_TicksToTimeMicroSec to clarify output - changed the output from 'ticks' (100ns intervals) to miliseconds to follow CMSIS API and because having a time base granularity of 1 milisecond is more than enough (100ns intervals is really too much for an embedded system) this also allows an extra efficiency of using 32bits vars and math for this instead of 64bits - update code accordingly where required - add ChibiOS implementation Signed-off-by: José Simões * Rework types and adjust code accordingly - adjust return type of HAL_Time_CurrentTicks to uint32_t - update code accordingly - uncomment timeout code in WireProtocol - minor reworks in code per reviewer request Signed-off-by: José Simões * Rework code to use milliseconds calculations instead of microseconds - as the system clock is in milliseconds it doesn't make sense to be performing the calculations in microseconds - update code accordingly - adjust target ChibiOS config to use 1ms as sys time base - adjust target ChibiOS config to use classic periodic tick (was set to use tick-less) Signed-off-by: José Simões * Replace code with ChibiOS macro rewrite and correct return type - ChibiOS macro STMS(n) will overflow when doing the math with uint32_t Signed-off-by: José Simões --- src/CLR/Core/GarbageCollector.cpp | 4 ++-- src/CLR/Include/WireProtocol.h | 4 ++-- src/CLR/Include/nanoCLR_Runtime.h | 8 +++++--- src/CLR/WireProtocol/WireProtocol.cpp | 18 +++++++++--------- src/CLR/WireProtocol/WireProtocol_Message.c | 3 ++- src/HAL/Include/nanoHAL_Time.h | 11 +++++++++++ src/PAL/Include/nanoPAL.h | 2 +- .../ST_NUCLEO144_F746ZG/nanoCLR/chconf.h | 4 ++-- .../ChibiOS/ST_NUCLEO_F091RC/nanoCLR/chconf.h | 4 ++-- .../ST_STM32F4_DISCOVERY/nanoCLR/chconf.h | 4 ++-- .../CMSIS-OS/ChibiOS/nanoCLR/CMakeLists.txt | 5 +++++ .../CMSIS-OS/ChibiOS/nanoCLR/targetHAL_Time.c | 19 +++++++++++++++++++ .../os/mbed-os/nanoBooter/WireProtocol.cpp | 2 +- targets/os/win32/Include/targetHAL_Time.h | 16 ++++++++-------- targets/os/win32/nanoCLR/Time.cpp | 8 +++++--- 15 files changed, 76 insertions(+), 36 deletions(-) create mode 100644 targets/CMSIS-OS/ChibiOS/nanoCLR/targetHAL_Time.c diff --git a/src/CLR/Core/GarbageCollector.cpp b/src/CLR/Core/GarbageCollector.cpp index c9e95a9877..f43d985f40 100644 --- a/src/CLR/Core/GarbageCollector.cpp +++ b/src/CLR/Core/GarbageCollector.cpp @@ -150,7 +150,7 @@ CLR_UINT32 CLR_RT_GarbageCollector::ExecuteGarbageCollection() CLR_RT_ExecutionEngine::ExecutionConstraint_Suspend(); #if defined(NANOCLR_TRACE_MEMORY_STATS) - CLR_UINT64 stats_start = 0; + CLR_UINT32 stats_start = 0; if(s_CLR_RT_fTrace_MemoryStats >= c_CLR_RT_Trace_Info) { @@ -171,7 +171,7 @@ CLR_UINT32 CLR_RT_GarbageCollector::ExecuteGarbageCollection() #if defined(NANOCLR_TRACE_MEMORY_STATS) if(s_CLR_RT_fTrace_MemoryStats >= c_CLR_RT_Trace_Info) { - int milliSec = ((int)::HAL_Time_TicksToTime( HAL_Time_CurrentTicks() - stats_start ) + TIME_CONVERSION__TICKUNITS - 1) / TIME_CONVERSION__TICKUNITS; + int milliSec = (int)::HAL_Time_TicksToTimeMilliSec( HAL_Time_CurrentTicks() - stats_start ); CLR_Debug::Printf( "GC: %dmsec %d bytes used, %d bytes available\r\n", milliSec, m_totalBytes - m_freeBytes, m_freeBytes ); } diff --git a/src/CLR/Include/WireProtocol.h b/src/CLR/Include/WireProtocol.h index cb6d654f41..20d0ef2439 100644 --- a/src/CLR/Include/WireProtocol.h +++ b/src/CLR/Include/WireProtocol.h @@ -116,7 +116,7 @@ struct WP_Message static const int CompletePayload = 6; }; - static const UINT32 c_PayloadTimeout = 60000000; // 6 secs (100 nsecs units) + static const UINT64 c_PayloadTimeout = 6 * 1000; // 6 secs (from milliseconds time) WP_Controller* m_parent; WP_Packet m_header; @@ -125,7 +125,7 @@ struct WP_Message private: UINT8* m_pos; UINT32 m_size; - UINT64 m_payloadTicks; + UINT32 m_payloadTicks; int m_rxState; public: diff --git a/src/CLR/Include/nanoCLR_Runtime.h b/src/CLR/Include/nanoCLR_Runtime.h index 0c8c87ba39..c7d9373836 100644 --- a/src/CLR/Include/nanoCLR_Runtime.h +++ b/src/CLR/Include/nanoCLR_Runtime.h @@ -2943,8 +2943,8 @@ struct CLR_RT_ExecutionEngine struct ExecutionConstraintCompensation { CLR_INT32 m_recursion; - CLR_INT64 m_start; - CLR_INT64 m_cumulative; + CLR_INT32 m_start; + CLR_INT32 m_cumulative; void Suspend() { @@ -2967,7 +2967,9 @@ struct CLR_RT_ExecutionEngine CLR_INT64 Adjust( CLR_INT64 time ) const { - return time + ::HAL_Time_TicksToTime( m_cumulative ); + // need to 'convert' this from milliseconds to 100ns ticks so it won't break the code calling Adjust() + // FIXME: evaluate if the caller code can be adjusted to drop this workaround conversion + return time + ::HAL_Time_TicksToTimeMilliSec( m_cumulative ) / NANOHAL_TIME_CONVERSION_MICRO_TO_HUNDREDS_NANOSECONDS; } }; diff --git a/src/CLR/WireProtocol/WireProtocol.cpp b/src/CLR/WireProtocol/WireProtocol.cpp index 7d405f6bc1..25bb3f307a 100644 --- a/src/CLR/WireProtocol/WireProtocol.cpp +++ b/src/CLR/WireProtocol/WireProtocol.cpp @@ -239,7 +239,7 @@ bool WP_Message::Process() } else { - // FIXME: m_payloadTicks = HAL_Time_CurrentTicks(); + m_payloadTicks = HAL_Time_CurrentTicks(); m_rxState = ReceiveState::ReadingPayload; m_pos = (UINT8*)m_payload; m_size = m_header.m_size; @@ -268,14 +268,14 @@ bool WP_Message::Process() { TRACE0(TRACE_STATE, "RxState=ReadingPayload\n"); - // FIXME: UINT64 curTicks = HAL_Time_CurrentTicks(); + UINT32 curTicks = HAL_Time_CurrentTicks(); // If the time between consecutive payload bytes exceeds the timeout threshold then assume that // the rest of the payload is not coming. Reinitialize to synch on the next header. - // FIXME: if(HAL_Time_TicksToTime(curTicks - m_payloadTicks) < (UINT64)c_PayloadTimeout) + if(HAL_Time_TicksToTimeMilliSec(curTicks - m_payloadTicks) < c_PayloadTimeout) { - // FIXME: m_payloadTicks = curTicks; + m_payloadTicks = curTicks; if(m_parent->m_phy->ReceiveBytes(m_parent->m_state, m_pos, m_size) == false) { @@ -288,11 +288,11 @@ bool WP_Message::Process() m_rxState = ReceiveState::CompletePayload; } } - // FIXME: else - //{ - // TRACE0(TRACE_ERRORS, "RxError: Payload InterCharacterTimeout exceeded\n"); - // m_rxState = ReceiveState::Initialize; - //} + else + { + TRACE0(TRACE_ERRORS, "RxError: Payload InterCharacterTimeout exceeded\n"); + m_rxState = ReceiveState::Initialize; + } } break; diff --git a/src/CLR/WireProtocol/WireProtocol_Message.c b/src/CLR/WireProtocol/WireProtocol_Message.c index 80e1cefae2..aa890b391e 100644 --- a/src/CLR/WireProtocol/WireProtocol_Message.c +++ b/src/CLR/WireProtocol/WireProtocol_Message.c @@ -8,6 +8,7 @@ uint8_t receptionBuffer[2048]; static uint16_t lastOutboundMessage; +uint32_t m_payloadTicks; static uint8_t* marker; ////////////////////////////////////////// @@ -241,7 +242,7 @@ bool WP_Message_Process(WP_Message* message) } else { - // FIXME: m_payloadTicks = HAL_Time_CurrentTicks(); + m_payloadTicks = HAL_Time_CurrentTicks(); message->m_rxState = ReceiveState_ReadingPayload; message->m_pos = message->m_payload; message->m_size = message->m_header.m_size; diff --git a/src/HAL/Include/nanoHAL_Time.h b/src/HAL/Include/nanoHAL_Time.h index 326abe0aa6..709f4f0149 100644 --- a/src/HAL/Include/nanoHAL_Time.h +++ b/src/HAL/Include/nanoHAL_Time.h @@ -8,4 +8,15 @@ #include +#define NANOHAL_TIME_CONVERSION_MICRO_TO_SECONDS 1000000 +#define NANOHAL_TIME_CONVERSION_MICRO_TO_HUNDREDS_NANOSECONDS 10000 + +////////////////////////////////////////// +// TODO delete these when working on #130 +typedef unsigned long long UINT64; +typedef unsigned int UINT32; +////////////////////////////////////////// + +UINT64 HAL_Time_TicksToTimeMilliSec(UINT32 Ticks); + #endif //_NANOHAL_TIME_H_ diff --git a/src/PAL/Include/nanoPAL.h b/src/PAL/Include/nanoPAL.h index 2eebc270b3..e452a096d2 100644 --- a/src/PAL/Include/nanoPAL.h +++ b/src/PAL/Include/nanoPAL.h @@ -308,7 +308,7 @@ BOOL Time_TimeSpanToStringEx(const INT64& ticks, LPSTR& buf, size_t& len); LPCSTR Time_CurrentDateTimeToString(); -INT64 HAL_Time_TicksToTime(UINT64 Ticks); + INT64 HAL_Time_CurrentTime(); //#include diff --git a/targets/CMSIS-OS/ChibiOS/ST_NUCLEO144_F746ZG/nanoCLR/chconf.h b/targets/CMSIS-OS/ChibiOS/ST_NUCLEO144_F746ZG/nanoCLR/chconf.h index d0b64b9599..1add85cad8 100644 --- a/targets/CMSIS-OS/ChibiOS/ST_NUCLEO144_F746ZG/nanoCLR/chconf.h +++ b/targets/CMSIS-OS/ChibiOS/ST_NUCLEO144_F746ZG/nanoCLR/chconf.h @@ -36,7 +36,7 @@ * @details Frequency of the system timer that drives the system ticks. This * setting also defines the system tick time unit. */ -#define CH_CFG_ST_FREQUENCY 10000 +#define CH_CFG_ST_FREQUENCY 1000 // this is 1 millisecond /** * @brief Time delta constant for the tick-less mode. @@ -46,7 +46,7 @@ * The value one is not valid, timeouts are rounded up to * this value. */ -#define CH_CFG_ST_TIMEDELTA 2 +#define CH_CFG_ST_TIMEDELTA 0 /** @} */ diff --git a/targets/CMSIS-OS/ChibiOS/ST_NUCLEO_F091RC/nanoCLR/chconf.h b/targets/CMSIS-OS/ChibiOS/ST_NUCLEO_F091RC/nanoCLR/chconf.h index 2d8f32ed0c..d7983cfc8a 100644 --- a/targets/CMSIS-OS/ChibiOS/ST_NUCLEO_F091RC/nanoCLR/chconf.h +++ b/targets/CMSIS-OS/ChibiOS/ST_NUCLEO_F091RC/nanoCLR/chconf.h @@ -42,7 +42,7 @@ * @details Frequency of the system timer that drives the system ticks. This * setting also defines the system tick time unit. */ -#define CH_CFG_ST_FREQUENCY 1000000 +#define CH_CFG_ST_FREQUENCY 1000 // this is 1 millisecond /** * @brief Time delta constant for the tick-less mode. @@ -52,7 +52,7 @@ * The value one is not valid, timeouts are rounded up to * this value. */ -#define CH_CFG_ST_TIMEDELTA 2 +#define CH_CFG_ST_TIMEDELTA 0 /** @} */ diff --git a/targets/CMSIS-OS/ChibiOS/ST_STM32F4_DISCOVERY/nanoCLR/chconf.h b/targets/CMSIS-OS/ChibiOS/ST_STM32F4_DISCOVERY/nanoCLR/chconf.h index b6adf274ce..e39675857d 100644 --- a/targets/CMSIS-OS/ChibiOS/ST_STM32F4_DISCOVERY/nanoCLR/chconf.h +++ b/targets/CMSIS-OS/ChibiOS/ST_STM32F4_DISCOVERY/nanoCLR/chconf.h @@ -42,7 +42,7 @@ * @details Frequency of the system timer that drives the system ticks. This * setting also defines the system tick time unit. */ -#define CH_CFG_ST_FREQUENCY 10000 +#define CH_CFG_ST_FREQUENCY 1000 // this is 1 millisecond /** * @brief Time delta constant for the tick-less mode. @@ -52,7 +52,7 @@ * The value one is not valid, timeouts are rounded up to * this value. */ -#define CH_CFG_ST_TIMEDELTA 2 +#define CH_CFG_ST_TIMEDELTA 0 /** @} */ diff --git a/targets/CMSIS-OS/ChibiOS/nanoCLR/CMakeLists.txt b/targets/CMSIS-OS/ChibiOS/nanoCLR/CMakeLists.txt index 882768cfcd..227bb032df 100644 --- a/targets/CMSIS-OS/ChibiOS/nanoCLR/CMakeLists.txt +++ b/targets/CMSIS-OS/ChibiOS/nanoCLR/CMakeLists.txt @@ -7,6 +7,11 @@ list(APPEND TARGET_CHIBIOS_NANOCLR_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/WireProtocol_App_Interface.c) list(APPEND TARGET_CHIBIOS_NANOCLR_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/WireProtocol_MonitorCommands.c) list(APPEND TARGET_CHIBIOS_NANOCLR_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Aborts_CortexM3.cpp) + +# append target HAL source files +list(APPEND TARGET_CHIBIOS_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Time.c") + + # make var global set(TARGET_CHIBIOS_NANOCLR_SOURCES ${TARGET_CHIBIOS_NANOCLR_SOURCES} CACHE INTERNAL "make global") diff --git a/targets/CMSIS-OS/ChibiOS/nanoCLR/targetHAL_Time.c b/targets/CMSIS-OS/ChibiOS/nanoCLR/targetHAL_Time.c new file mode 100644 index 0000000000..b57333cf7c --- /dev/null +++ b/targets/CMSIS-OS/ChibiOS/nanoCLR/targetHAL_Time.c @@ -0,0 +1,19 @@ +// +// Copyright (c) 2017 The nanoFramework project contributors +// See LICENSE file in the project root for full license information. +// + +#include + +////////////////////////////////////////// +// TODO delete these when working on #130 +typedef unsigned int UINT32; +typedef signed int INT32; +////////////////////////////////////////// + +// Converts ticks (CMSIS sysTicks) to milliseconds +UINT64 HAL_Time_TicksToTimeMilliSec(UINT32 ticks) { + + // this is a rewrite of ChibiOS ST2MS(n) macro because it will overflow if doing the math using uint32_t + return (((ticks) * 1000ULL + (uint64_t)CH_CFG_ST_FREQUENCY - 1ULL) / (uint64_t)CH_CFG_ST_FREQUENCY); +} diff --git a/targets/os/mbed-os/nanoBooter/WireProtocol.cpp b/targets/os/mbed-os/nanoBooter/WireProtocol.cpp index 352df91f4c..1193dc293b 100644 --- a/targets/os/mbed-os/nanoBooter/WireProtocol.cpp +++ b/targets/os/mbed-os/nanoBooter/WireProtocol.cpp @@ -260,7 +260,7 @@ bool WP_Message::Process() // If the time between consecutive payload bytes exceeds the timeout threshold then assume that // the rest of the payload is not coming. Reinitialize to synch on the next header. - // FIXME: if(HAL_Time_TicksToTime(curTicks - m_payloadTicks) < (UINT64)c_PayloadTimeout) + // FIXME: if(HAL_Time_TicksToTimeMilliSec(curTicks - m_payloadTicks) < (UINT64)c_PayloadTimeout) { // FIXME: m_payloadTicks = curTicks; diff --git a/targets/os/win32/Include/targetHAL_Time.h b/targets/os/win32/Include/targetHAL_Time.h index cf0c35fb95..fcf7430287 100644 --- a/targets/os/win32/Include/targetHAL_Time.h +++ b/targets/os/win32/Include/targetHAL_Time.h @@ -22,15 +22,15 @@ // //#define TIME_ZONE_OFFSET ((INT64)Time_GetTimeZoneOffset() * 600000000) // -//INT64 HAL_Time_TicksToTime(UINT64 Ticks); -//UINT64 HAL_Time_TicksToTime(); -UINT64 HAL_Time_CurrentTicks(); -#define HAL_Time_CurrentTicks HAL_Time_CurrentTicks -// -//// FIXME -//INT64 HAL_Time_TicksToTime(UINT64 Ticks) -// + +UINT32 HAL_Time_CurrentTicks(); + + + + + + ///// ///// Converts 64bit time value to SystemTime structure. 64bit time is assumed as an offset from 1/1/1601:00:00:00.000 in 100ns. ///// diff --git a/targets/os/win32/nanoCLR/Time.cpp b/targets/os/win32/nanoCLR/Time.cpp index c5b2b78c37..ff20ef5d0f 100644 --- a/targets/os/win32/nanoCLR/Time.cpp +++ b/targets/os/win32/nanoCLR/Time.cpp @@ -17,17 +17,19 @@ void HAL_Time_Sleep_MicroSeconds_InterruptEnabled( UINT32 uSec ) // UNDONE: FIXME: return EmulatorNative::GetITimeDriver()->Sleep_MicroSecondsInterruptsEnabled( uSec ); } -UINT64 HAL_Time_CurrentTicks() +UINT32 HAL_Time_CurrentTicks() { + // TODO need to check if using the Win32 100ns ticks works return 0; // UNDONE: FIXME: EmulatorNative::GetITimeDriver()->CurrentTicks(); } -INT64 HAL_Time_TicksToTime( UINT64 Ticks ) +UINT64 HAL_Time_TicksToTimeMilliSec( UINT32 Ticks ) { - _ASSERTE(Ticks <= 0x7FFFFFFFFFFFFFFF); + _ASSERTE(Ticks <= 0x7FFFFFFF); //No need to go to managed code just to return Time. + // TODO need to convert from whathever ticks are these to milliseconds return Ticks; }