Skip to content

Commit

Permalink
Work on scheduler and sys time
Browse files Browse the repository at this point in the history
- Major rework on all CLR events and time related functions
- Rename and update types on related functions
- Work on timer to wait for events
- Remove CPUSleep (no actual use in the current platforms)

Signed-off-by: josesimoes <[email protected]>
  • Loading branch information
josesimoes committed May 23, 2018
1 parent c8a7595 commit c2ba8db
Show file tree
Hide file tree
Showing 22 changed files with 113 additions and 80 deletions.
2 changes: 1 addition & 1 deletion src/HAL/Include/nanoHAL_Time.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,6 @@ bool HAL_Time_TimeSpanToStringEx( const int64_t& ticks, char*& buf, siz
const char* HAL_Time_CurrentDateTimeToString();


unsigned __int64 CPU_MilisecondsToSysTicks ( unsigned __int64 miliSeconds );
uint64_t CPU_MillisecondsToTicks ( uint64_t ticks );

#endif //_NANOHAL_TIME_H_
3 changes: 2 additions & 1 deletion src/HAL/Include/nanoHAL_v2.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ extern "C" {
#endif

void CPU_Reset();
//void CPU_Sleep(SLEEP_LEVEL_type level, uint64_t wakeEvents);
void CPU_Sleep(SLEEP_LEVEL_type level, uint64_t wakeEvents);

#ifdef __cplusplus
}
Expand Down Expand Up @@ -209,5 +209,6 @@ bool SystemState_QueryNoLock( SYSTEM_STATE_type state );

//--//

#define HAL_COMPLETION_IDLE_VALUE 0x0000FFFFFFFFFFFFull

#endif // _NANOHAL_V2_H_
24 changes: 11 additions & 13 deletions src/PAL/AsyncProcCall/AsyncCompletions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ void HAL_COMPLETION::Execute()

//--//

static const uint64_t HAL_Completion_IdleValue = 0x0000FFFFFFFFFFFFull;

void HAL_COMPLETION::InitializeList()
{
NATIVE_PROFILE_PAL_ASYNC_PROC_CALL();
Expand Down Expand Up @@ -66,7 +64,7 @@ void HAL_COMPLETION::DequeueAndExec()
//
// In case there's no other request to serve, set the next interrupt to be 356 years since last powerup (@25kHz).
//
Time_SetCompare( ptrNext->Next() ? ptrNext->EventTimeTicks : HAL_Completion_IdleValue );
Time_SetCompare( ptrNext->Next() ? ptrNext->EventTimeTicks : HAL_COMPLETION_IDLE_VALUE );

#if defined(_DEBUG)
ptr->EventTimeTicks = 0;
Expand Down Expand Up @@ -110,22 +108,22 @@ void HAL_COMPLETION::EnqueueTicks( uint64_t eventTimeTicks )
GLOBAL_UNLOCK(irq);
}

// the argument to enqueue is in miliseconds as we don't need anything bellow this in a reasonale use case scenario
void HAL_COMPLETION::EnqueueDelta64( uint64_t miliSecondsFromNow )
// the argument to enqueue is in milliseconds as we don't need anything bellow this in a reasonale use case scenario
void HAL_COMPLETION::EnqueueDelta64( uint64_t milliSecondsFromNow )
{
NATIVE_PROFILE_PAL_ASYNC_PROC_CALL();
// grab time first to be closest to now as possible from when this function was called
uint64_t now = HAL_Time_CurrentSysTicks();
uint64_t eventTimeTicks = CPU_MilisecondsToSysTicks( miliSecondsFromNow );
uint64_t eventTimeTicks = CPU_MillisecondsToTicks( milliSecondsFromNow * 1000);

EnqueueTicks( now + eventTimeTicks );
}

// the argument to enqueue is in miliseconds as we don't need anything bellow this in a reasonale use case scenario
void HAL_COMPLETION::EnqueueDelta( uint32_t miliSecondsFromNow )
void HAL_COMPLETION::EnqueueDelta( uint32_t milliSecondsFromNow )
{
NATIVE_PROFILE_PAL_ASYNC_PROC_CALL();
EnqueueDelta64( (uint64_t)miliSecondsFromNow );
EnqueueDelta64( (uint64_t)milliSecondsFromNow );
}

//--//
Expand All @@ -152,7 +150,7 @@ void HAL_COMPLETION::Abort()
//
// In case there's no other request to serve, set the next interrupt to be 356 years since last power up (@25kHz).
//
nextTicks = HAL_Completion_IdleValue;
nextTicks = HAL_COMPLETION_IDLE_VALUE;
}
else
{
Expand All @@ -169,7 +167,7 @@ void HAL_COMPLETION::Abort()

//--//

void HAL_COMPLETION::WaitForInterrupts(uint64_t expireTicks, uint32_t sleepLevel, uint64_t wakeEvents)
void HAL_COMPLETION::WaitForInterrupts(uint64_t expireTimeInTicks, uint32_t sleepLevel, uint64_t wakeEvents)
{
NATIVE_PROFILE_PAL_ASYNC_PROC_CALL();

Expand All @@ -186,7 +184,7 @@ void HAL_COMPLETION::WaitForInterrupts(uint64_t expireTicks, uint32_t sleepLevel
{
state = setCompare | nilCompare;
}
else if(ptr->EventTimeTicks > expireTicks)
else if(ptr->EventTimeTicks > expireTimeInTicks)
{
state = setCompare | resetCompare;
}
Expand All @@ -197,7 +195,7 @@ void HAL_COMPLETION::WaitForInterrupts(uint64_t expireTicks, uint32_t sleepLevel

if(state & setCompare)
{
Time_SetCompare(expireTicks);
Time_SetCompare(expireTimeInTicks);
}

CPU_Sleep((SLEEP_LEVEL_type)sleepLevel, wakeEvents);
Expand All @@ -207,7 +205,7 @@ void HAL_COMPLETION::WaitForInterrupts(uint64_t expireTicks, uint32_t sleepLevel
// let's get the first node again
// it could have changed since CPU_Sleep re-enabled interrupts
ptr = (HAL_COMPLETION*)g_HAL_Completion_List.FirstNode();
Time_SetCompare((state & resetCompare) ? ptr->EventTimeTicks : HAL_Completion_IdleValue);
Time_SetCompare((state & resetCompare) ? ptr->EventTimeTicks : HAL_COMPLETION_IDLE_VALUE);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/PAL/AsyncProcCall/Async_stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ __nfweak void HAL_COMPLETION::DequeueAndExec()
NATIVE_PROFILE_PAL_ASYNC_PROC_CALL();
}

__nfweak void HAL_COMPLETION::WaitForInterrupts( uint64_t expireTicks, uint32_t sleepLevel, uint64_t wakeEvents )
__nfweak void HAL_COMPLETION::WaitForInterrupts( uint64_t expireTimeInSysTicks, uint32_t sleepLevel, uint64_t wakeEvents )
{
NATIVE_PROFILE_PAL_ASYNC_PROC_CALL();
}
2 changes: 1 addition & 1 deletion src/PAL/Include/nanoPAL_AsyncProcCalls_decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ struct HAL_COMPLETION : public HAL_CONTINUATION

static void DequeueAndExec();

static void WaitForInterrupts( uint64_t expireTicks, uint32_t sleepLevel, uint64_t wakeEvents );
static void WaitForInterrupts( uint64_t expireTimeInSysTicks, uint32_t sleepLevel, uint64_t wakeEvents );
};

//--//
Expand Down
6 changes: 3 additions & 3 deletions src/PAL/Include/nanoPAL_Events.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ typedef void (*set_Event_Callback)( void* );
// Events_WaitForEvents(0, EVENTS_TIMEOUT_INFINITE) sleeps forever. Don't do that.
// Events_WaitForEvents(flags, EVENTS_TIMEOUT_INFINITE) waits forever for that event.

uint32_t Events_WaitForEvents( uint32_t powerLevel, uint32_t wakeupSystemEvents, uint32_t timeout_Milliseconds );
uint32_t Events_WaitForEvents( uint32_t powerLevel, uint32_t wakeupSystemEvents, uint32_t timeoutMilliseconds );

__inline uint32_t Events_WaitForEvents( uint32_t WakeupSystemEvents, uint32_t Timeout_Milliseconds )
__inline uint32_t Events_WaitForEvents( uint32_t wakeupSystemEvents, uint32_t timeoutMilliseconds )
{
return Events_WaitForEvents( SLEEP_LEVEL__SLEEP, WakeupSystemEvents, Timeout_Milliseconds );
return Events_WaitForEvents( SLEEP_LEVEL__SLEEP, wakeupSystemEvents, timeoutMilliseconds );
}

void Events_SetBoolTimer( bool* timerCompleteFlag, uint32_t millisecondsFromNow );
Expand Down
4 changes: 3 additions & 1 deletion targets/CMSIS-OS/ChibiOS/Include/targetHAL_Power.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
#include <nanoHAL_v2.h>

inline void CPU_Reset(){ NVIC_SystemReset(); };
inline void CPU_Sleep(SLEEP_LEVEL_type level, uint64_t wakeEvents){ osDelay(10); };

// CPU sleep is not currently implemented in this target
inline void CPU_Sleep(SLEEP_LEVEL_type level, uint64_t wakeEvents){ };

inline bool CPU_IsSoftRebootSupported() { return true; };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,6 @@ REGION_ALIAS("BSS_RAM", ram0);
REGION_ALIAS("HEAP_RAM", ram4);

/* RAM region to be used for the nanoFramework CLR managed heap.*/
REGION_ALIAS("CLR_MANAGED_HEAP_RAM", ext_ram);
REGION_ALIAS("CLR_MANAGED_HEAP_RAM", ram0);

INCLUDE rules.ld
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ HRESULT Library_nf_rt_events_native_nanoFramework_Runtime_Events_NativeEventDisp
CLR_RT_HeapBlock_NativeEventDispatcher* pNativeDisp = NULL;

const char * driverName;
unsigned __int64 driverData;
uint64_t driverData;

CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis);

Expand Down
18 changes: 8 additions & 10 deletions targets/CMSIS-OS/ChibiOS/nanoCLR/targetHAL_Time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,16 @@
#include <ch.h>

// Converts CMSIS sysTicks to .NET ticks (100 nanoseconds)
signed __int64 HAL_Time_SysTicksToTime(unsigned int sysTicks) {

// this is a rewrite of ChibiOS ST2US(n) macro because it will overflow if doing the math using uint32_t

int64_t HAL_Time_SysTicksToTime(unsigned int sysTicks)
{
// convert to microseconds from CMSIS SysTicks
int64_t microsecondsFromSysTicks = (((sysTicks) * 1000000ULL + (int64_t)CH_CFG_ST_FREQUENCY - 1ULL) / (int64_t)CH_CFG_ST_FREQUENCY);

// this is a rewrite of ChibiOS TIME_I2US(n) macro because it will overflow if doing the math using uint32_t
// need to convert from microseconds to 100 nanoseconds
return microsecondsFromSysTicks * 10;
return (((sysTicks * (int64_t)1000000) + (int64_t)CH_CFG_ST_FREQUENCY - 1) / (int64_t)CH_CFG_ST_FREQUENCY) * 10;
}

// Returns the current date time from the system tick or from the RTC if it's available (this depends on the respective configuration option)
signed __int64 HAL_Time_CurrentDateTime(bool datePartOnly)
int64_t HAL_Time_CurrentDateTime(bool datePartOnly)
{
#if defined(HAL_USE_RTC)

Expand Down Expand Up @@ -132,7 +129,8 @@ const char* HAL_Time_CurrentDateTimeToString()
return DateTimeToString(HAL_Time_CurrentDateTime(false));
}

unsigned __int64 CPU_MiliSecondsToSysTicks(unsigned __int64 miliSeconds)
uint64_t CPU_MillisecondsToTicks(uint64_t ticks)
{
return TIME_MS2I(miliSeconds);
// this is a rewrite of ChibiOS TIME_MS2I(n) macro because it will overflow if doing the math using uint32_t
return (((ticks * (uint64_t)CH_CFG_ST_FREQUENCY) + 999) / (uint64_t)1000);
}
20 changes: 11 additions & 9 deletions targets/CMSIS-OS/ChibiOS/nanoCLR/targetPAL_Events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <target_platform.h>
#include <hal.h>

uint64_t CPU_MiliSecondsToSysTicks(uint64_t miliSeconds);
uint64_t CPU_MillisecondsToTicks(uint64_t ticks);

// timer for bool events
static virtual_timer_t boolEventsTimer;
Expand Down Expand Up @@ -80,7 +80,11 @@ static void local_Events_SetBoolTimer_Callback( void* arg )
NATIVE_PROFILE_PAL_EVENTS();
bool* timerCompleteFlag = (bool*)arg;

chSysLock();

*timerCompleteFlag = true;

chSysUnlock();
}

void Events_SetCallback( set_Event_Callback pfn, void* arg )
Expand All @@ -102,17 +106,17 @@ void Events_SetBoolTimer( bool* timerCompleteFlag, uint32_t millisecondsFromNow
}
}

uint32_t Events_WaitForEvents( uint32_t powerLevel, uint32_t wakeupSystemEvents, uint32_t timeout_Milliseconds )
uint32_t Events_WaitForEvents( uint32_t powerLevel, uint32_t wakeupSystemEvents, uint32_t timeoutMilliseconds )
{
// schedule an interrupt for this far in the future
// timeout is in milliseconds, convert to Sleep Counts
uint64_t countsRemaining = CPU_MiliSecondsToSysTicks( (uint64_t)timeout_Milliseconds );
// timeout is in milliseconds, need to convert to ticks
uint64_t countsRemaining = CPU_MillisecondsToTicks( timeoutMilliseconds );

#if defined(HAL_PROFILE_ENABLED)
Events_WaitForEvents_Calls++;
#endif

uint64_t expireTicks = HAL_Time_CurrentTime() + countsRemaining;
uint64_t expireTimeInTicks = HAL_Time_CurrentTime() + countsRemaining;
bool runContinuations = true;

while(true)
Expand All @@ -123,7 +127,7 @@ uint32_t Events_WaitForEvents( uint32_t powerLevel, uint32_t wakeupSystemEvents,
return events;
}

if(expireTicks <= HAL_Time_CurrentTime())
if(expireTimeInTicks <= HAL_Time_CurrentTime())
{
break;
}
Expand All @@ -140,14 +144,12 @@ uint32_t Events_WaitForEvents( uint32_t powerLevel, uint32_t wakeupSystemEvents,
// try stalled continuations again after sleeping
runContinuations = true;

HAL_COMPLETION::WaitForInterrupts(expireTicks, powerLevel, wakeupSystemEvents );
HAL_COMPLETION::WaitForInterrupts(expireTimeInTicks, powerLevel, wakeupSystemEvents );
}

// no events, pass control to the OS
osThreadYield();
}

return 0;
}

void FreeManagedEvent(uint8_t category, uint8_t subCategory, uint16_t data1, uint32_t data2)
Expand Down
32 changes: 24 additions & 8 deletions targets/CMSIS-OS/ChibiOS/nanoCLR/targetPAL_Time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <hal.h>
#include <ch.h>


// timer for next event
static virtual_timer_t nextEventTimer;
void* nextEventCallbackDummyArg = NULL;
Expand All @@ -16,17 +17,15 @@ static void NextEventTimer_Callback( void* arg )
{
(bool*)arg;

chSysLock();

// this call also schedules the next one, if there is one
HAL_COMPLETION::DequeueAndExec();

chSysUnlock();
}

HRESULT Time_Initialize()
{
// nothing to do here has time management is handled by ChibiOS
// need to setup the timer at boot, but stoped
//chVTSet(&nextEventTimer, TIME_INFINITE, NextEventTimer_Callback, nextEventCallbackDummyArg);

return S_OK;
}

Expand All @@ -43,10 +42,27 @@ void Time_SetCompare ( uint64_t compareValueTicks )
// compare value is 0 so dequeue and schedule immediately
NextEventTimer_Callback(nextEventCallbackDummyArg);
}
else if(compareValueTicks == HAL_COMPLETION_IDLE_VALUE)
{
// wait for infinity, don't need to do anything here
return;
}
else
{
// need to convert from ticks to milliseconds
// no need to stop the time if it's running because the API does it anyway
chVTSet(&nextEventTimer, TIME_MS2I(compareValueTicks * TIME_CONVERSION__TO_MILLISECONDS), NextEventTimer_Callback, nextEventCallbackDummyArg);
if (HAL_Time_CurrentTime() >= compareValueTicks)
{
// already missed the event, dequeue and execute immediately
HAL_COMPLETION::DequeueAndExec();
}
else
{
// compareValueTicks is the time (in sys ticks) that is being requested to fire an HAL_COMPLETION::DequeueAndExec()
// need to subtract the current system time to set when the timer will fire
compareValueTicks -= HAL_Time_CurrentTime();

// no need to stop the timer if it's running because the API does it anyway
// need to convert from nF ticks to milliseconds and then to ChibiOS sys ticks to load the timer
chVTSet(&nextEventTimer, TIME_MS2I(compareValueTicks/ TIME_CONVERSION__TO_MILLISECONDS), NextEventTimer_Callback, nextEventCallbackDummyArg);
}
}
}
4 changes: 3 additions & 1 deletion targets/FreeRTOS/ESP32_DevKitC/Include/targetHAL_Power.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
#include <nanoHAL_v2.h>

inline void CPU_Reset(){ esp_restart(); };
inline void CPU_Sleep(SLEEP_LEVEL_type level, uint64_t wakeEvents){ vTaskDelay(0); };

// CPU sleep is not currently implemented in this target
inline void CPU_Sleep(SLEEP_LEVEL_type level, uint64_t wakeEvents){ };

inline bool CPU_IsSoftRebootSupported() { return true; };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ HRESULT Library_nf_rt_events_native_nanoFramework_Runtime_Events_NativeEventDisp
CLR_RT_HeapBlock_NativeEventDispatcher* pNativeDisp = NULL;

const char * driverName;
unsigned __int64 driverData;
uint64_t driverData;

CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis);

Expand Down
9 changes: 5 additions & 4 deletions targets/FreeRTOS/ESP32_DevKitC/nanoCLR/targetHAL_Time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#define ESP32_TICKS_PER_MS(x) ( ((uint64_t)x * configTICK_RATE_HZ) / 1000)

// Converts Tickcount to .NET ticks (100 nanoseconds)
signed __int64 HAL_Time_SysTicksToTime(unsigned int sysTicks) {
int64_t HAL_Time_SysTicksToTime(unsigned int sysTicks) {

// convert to microseconds from FreeRtyos Tickcount
int64_t microsecondsFromSysTicks = ((( xTaskGetTickCount() ) * 1000000ULL + (int64_t)configTICK_RATE_HZ - 1ULL) / (int64_t)configTICK_RATE_HZ);
Expand All @@ -23,7 +23,7 @@ signed __int64 HAL_Time_SysTicksToTime(unsigned int sysTicks) {
}

// Returns the current date time from the system tick or from the RTC if it's available (this depends on the respective configuration option)
signed __int64 HAL_Time_CurrentDateTime(bool datePartOnly)
int64_t HAL_Time_CurrentDateTime(bool datePartOnly)
{
#if defined(HAL_USE_RTC)
SYSTEMTIME st;
Expand Down Expand Up @@ -128,7 +128,8 @@ const char* HAL_Time_CurrentDateTimeToString()
return DateTimeToString(HAL_Time_CurrentDateTime(false));
}

unsigned __int64 CPU_MiliSecondsToSysTicks(unsigned __int64 miliSeconds)
uint64_t CPU_MillisecondsToTicks(uint64_t ticks)
{
return ESP32_TICKS_PER_MS(miliSeconds);
//return ESP32_TICKS_PER_MS(milliSeconds);
return ticks * 1000;
}
Loading

0 comments on commit c2ba8db

Please sign in to comment.