Skip to content

Commit

Permalink
Implement HAL_Time_TicksToTimeMilliSec (#145)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>

* 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 <[email protected]>

* 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 <[email protected]>

* 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 <[email protected]>
  • Loading branch information
josesimoes authored and cw2 committed Mar 6, 2017
1 parent 5c0ce2e commit 4884fe5
Show file tree
Hide file tree
Showing 15 changed files with 76 additions and 36 deletions.
4 changes: 2 additions & 2 deletions src/CLR/Core/GarbageCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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 );
}
Expand Down
4 changes: 2 additions & 2 deletions src/CLR/Include/WireProtocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -125,7 +125,7 @@ struct WP_Message
private:
UINT8* m_pos;
UINT32 m_size;
UINT64 m_payloadTicks;
UINT32 m_payloadTicks;
int m_rxState;

public:
Expand Down
8 changes: 5 additions & 3 deletions src/CLR/Include/nanoCLR_Runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand All @@ -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;
}
};

Expand Down
18 changes: 9 additions & 9 deletions src/CLR/WireProtocol/WireProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;

Expand Down
3 changes: 2 additions & 1 deletion src/CLR/WireProtocol/WireProtocol_Message.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

uint8_t receptionBuffer[2048];
static uint16_t lastOutboundMessage;
uint32_t m_payloadTicks;
static uint8_t* marker;

//////////////////////////////////////////
Expand Down Expand Up @@ -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;
Expand Down
11 changes: 11 additions & 0 deletions src/HAL/Include/nanoHAL_Time.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,15 @@

#include <targetHAL_Time.h>

#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_
2 changes: 1 addition & 1 deletion src/PAL/Include/nanoPAL.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <TimeService_decl.h>
Expand Down
4 changes: 2 additions & 2 deletions targets/CMSIS-OS/ChibiOS/ST_NUCLEO144_F746ZG/nanoCLR/chconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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

/** @} */

Expand Down
4 changes: 2 additions & 2 deletions targets/CMSIS-OS/ChibiOS/ST_NUCLEO_F091RC/nanoCLR/chconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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

/** @} */

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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

/** @} */

Expand Down
5 changes: 5 additions & 0 deletions targets/CMSIS-OS/ChibiOS/nanoCLR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand Down
19 changes: 19 additions & 0 deletions targets/CMSIS-OS/ChibiOS/nanoCLR/targetHAL_Time.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Copyright (c) 2017 The nanoFramework project contributors
// See LICENSE file in the project root for full license information.
//

#include <nanoHAL_Time.h>

//////////////////////////////////////////
// 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);
}
2 changes: 1 addition & 1 deletion targets/os/mbed-os/nanoBooter/WireProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
16 changes: 8 additions & 8 deletions targets/os/win32/Include/targetHAL_Time.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();






///// <summary>
///// Converts 64bit time value to SystemTime structure. 64bit time is assumed as an offset from 1/1/1601:00:00:00.000 in 100ns.
///// </summary>
Expand Down
8 changes: 5 additions & 3 deletions targets/os/win32/nanoCLR/Time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down

0 comments on commit 4884fe5

Please sign in to comment.