Created
March 27, 2019 16:24
-
-
Save stephanemainchain/8f9ad6ae4ed2ee2287b4244b548bfecb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2016-2017 IS2T. All rights reserved. | |
* For demonstration purpose only. | |
* IS2T PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. | |
*/ | |
/* Includes ------------------------------------------------------------------*/ | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include "cmsis_os.h" | |
#include "microej.h" | |
#include "LLMJVM_impl.h" | |
#include "native_time.h" | |
#include "us_ticker_api.h" | |
#include <inttypes.h> | |
/* Private function header ---------------------------------------------------*/ | |
static void wake_up_timer_callback(void const* timerId); | |
/* Defines -------------------------------------------------------------------*/ | |
/* | |
* Useful macros and definitions | |
*/ | |
// ID for the Wake Up Timer | |
#define WAKE_UP_TIMER_ID 42 | |
/* Globals -------------------------------------------------------------------*/ | |
// Application time offset | |
static int64_t LLMJVM_MBED_application_time_offset = 0; | |
//Absolute time in ticks at which timer will be launched | |
static int64_t LLMJVM_MBED_next_wake_up_time = INT64_MAX; | |
// Binary Semaphore to wakeup microJVM | |
static osSemaphoreId LLMJVM_MBED_Semaphore; | |
static osSemaphoreDef(LLMJVM_MBED_Semaphore); | |
// Wake up timer | |
osTimerId LLMJVM_MBED_wake_up_timer; | |
static osTimerDef(LLMJVM_MBED_wake_up_timer, wake_up_timer_callback); | |
/* Private functions ---------------------------------------------------------*/ | |
// Since LLMJVM_schedule() prototype does not match the timer callback prototype, | |
// we create a wrapper around it and check the ID of the timer. | |
static void wake_up_timer_callback(void const* timerId) | |
{ | |
if((uint32_t)timerId == WAKE_UP_TIMER_ID) | |
{ | |
osTimerStop(LLMJVM_MBED_wake_up_timer); | |
LLMJVM_schedule(); | |
} | |
} | |
/* Public functions ----------------------------------------------------------*/ | |
/* | |
* Implementation of functions from LLMJVM_impl.h | |
* and other helping functions. | |
*/ | |
// Creates the timer used to callback the LLMJVM_schedule() function. | |
// After its creation, the timer is idle. | |
int32_t LLMJVM_IMPL_initialize() | |
{ | |
// Create a timer to scheduler alarm for the VM | |
LLMJVM_MBED_wake_up_timer = osTimerCreate(osTimer(LLMJVM_MBED_wake_up_timer), osTimerOnce, (void*)(WAKE_UP_TIMER_ID)); | |
if(LLMJVM_MBED_wake_up_timer == NULL) | |
{ | |
printf("ERROR : osTimerCreate\r\n"); | |
return LLMJVM_ERROR; | |
} | |
LLMJVM_MBED_Semaphore = osSemaphoreCreate(osSemaphore(LLMJVM_MBED_Semaphore), 0); | |
if(LLMJVM_MBED_Semaphore == NULL) | |
{ | |
printf("ERROR : osSemaphoreCreate\r\n"); | |
return LLMJVM_ERROR; | |
} | |
/* Get Time timer initialize */ | |
us_ticker_init(); | |
return LLMJVM_OK; | |
} | |
// Once the task is started, save a handle to it. | |
int32_t LLMJVM_IMPL_vmTaskStarted() | |
{ | |
return LLMJVM_OK; | |
} | |
// Schedules requests from the VM | |
int32_t LLMJVM_IMPL_scheduleRequest(int64_t absoluteTime) | |
{ | |
int32_t relativeTime; | |
//First check if absolute time is lower than current schedule time | |
if(absoluteTime < LLMJVM_MBED_next_wake_up_time) | |
{ | |
// Save new alarm absolute time | |
LLMJVM_MBED_next_wake_up_time = absoluteTime; | |
// Stop current timer (no delay) | |
osTimerStop(LLMJVM_MBED_wake_up_timer); | |
// Determine relative time/tick | |
relativeTime = (int32_t)(absoluteTime - LLMJVM_IMPL_getCurrentTime(MICROEJ_TRUE)); | |
if(relativeTime > 0) | |
{ | |
// Schedule the new alarm | |
osTimerStart(LLMJVM_MBED_wake_up_timer, (uint32_t)relativeTime); | |
if(LLMJVM_MBED_wake_up_timer != 0) | |
{ | |
return LLMJVM_ERROR; | |
} | |
else | |
{ | |
return LLMJVM_OK; | |
} | |
} | |
else | |
{ | |
// 'absoluteTime' has been reached already, notify the VM now | |
return LLMJVM_schedule(); | |
} | |
} | |
// else : nothing to do. An sooner alarm is scheduled. | |
return LLMJVM_OK; | |
} | |
// Suspends the VM task if the pending flag is not set | |
int32_t LLMJVM_IMPL_idleVM() | |
{ | |
int32_t token = osSemaphoreWait(LLMJVM_MBED_Semaphore, osWaitForever); | |
return (token == -1) ? LLMJVM_ERROR : LLMJVM_OK; | |
} | |
// Wakes up the VM task and reset next wake up time | |
int32_t LLMJVM_IMPL_wakeupVM() | |
{ | |
osStatus res; | |
res = osSemaphoreRelease(LLMJVM_MBED_Semaphore); | |
LLMJVM_MBED_next_wake_up_time = INT64_MAX; | |
return (res == osOK) ? LLMJVM_OK : LLMJVM_ERROR; | |
} | |
// Clear the pending wake up flag | |
int32_t LLMJVM_IMPL_ackWakeup() | |
{ | |
/* Make sure no token are available in wake up semaphore */ | |
int32_t token = 0; | |
do { | |
token = osSemaphoreWait(LLMJVM_MBED_Semaphore, 0); | |
} | |
while (token > 0); | |
return (token == 0) ? LLMJVM_OK : LLMJVM_ERROR; | |
} | |
int32_t LLMJVM_IMPL_getCurrentTaskID() | |
{ | |
return (int32_t) osThreadGetId(); | |
} | |
void LLMJVM_native_setTime(int64_t t) | |
{ | |
int64_t currentTime = LLMJVM_IMPL_getCurrentTime(MICROEJ_TRUE); | |
LLMJVM_MBED_application_time_offset = t - currentTime; | |
} | |
// Sets application time | |
void LLMJVM_IMPL_setApplicationTime(int64_t t) | |
{ | |
LLMJVM_native_setTime(t); | |
} | |
int64_t LLMJVM_native_getTime(uint8_t system) | |
{ | |
int64_t systemTime = us_ticker_read64()/1000; | |
return system ? systemTime : systemTime + LLMJVM_MBED_application_time_offset; | |
} | |
// Gets the system or the application time in milliseconds | |
int64_t LLMJVM_IMPL_getCurrentTime(uint8_t system) | |
{ | |
return LLMJVM_native_getTime(system); | |
} | |
// Gets the current system time in nanoseconds | |
int64_t LLMJVM_IMPL_getTimeNanos() | |
{ | |
return us_ticker_read64()*1000; | |
} | |
int32_t LLMJVM_IMPL_shutdown(void) | |
{ | |
// nothing to do | |
return LLMJVM_OK; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment