1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-30 08:24:11 +01:00
LibrePilot/flight/libraries/PyMite/vm/pm.c

130 lines
3.1 KiB
C
Raw Normal View History

/*
# This file is Copyright 2006, 2007, 2009, 2010 Dean Hall.
#
# This file is part of the PyMite VM.
# The PyMite VM is free software: you can redistribute it and/or modify
# it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2.
#
# The PyMite VM is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# A copy of the GNU GENERAL PUBLIC LICENSE Version 2
# is seen in the file COPYING in this directory.
*/
#undef __FILE_ID__
#define __FILE_ID__ 0x15
/**
* \file
* \brief PyMite User API
*
* High-level functions to initialize and run PyMite
*/
#include "pm.h"
/** Number of millisecond-ticks to pass before scheduler is run */
#define PM_THREAD_TIMESLICE_MS 10
/** Stores the timer millisecond-ticks since system start */
volatile uint32_t pm_timerMsTicks = 0;
/** Stores tick timestamp of last scheduler run */
volatile uint32_t pm_lastRescheduleTimestamp = 0;
PmReturn_t
pm_init(PmMemSpace_t memspace, uint8_t const * const pusrimg)
{
PmReturn_t retval;
/* Initialize the hardware platform */
retval = plat_init();
PM_RETURN_IF_ERROR(retval);
/* Initialize the heap and the globals */
retval = heap_init();
PM_RETURN_IF_ERROR(retval);
retval = global_init();
PM_RETURN_IF_ERROR(retval);
/* Load usr image info if given */
if (pusrimg != C_NULL)
{
retval = img_appendToPath(memspace, pusrimg);
}
return retval;
}
PmReturn_t
pm_run(uint8_t const *modstr)
{
PmReturn_t retval;
pPmObj_t pmod;
pPmObj_t pstring;
uint8_t const *pmodstr = modstr;
/* Import module from global struct */
retval = string_new(&pmodstr, &pstring);
PM_RETURN_IF_ERROR(retval);
retval = mod_import(pstring, &pmod);
PM_RETURN_IF_ERROR(retval);
/* Load builtins into thread */
retval = global_setBuiltins((pPmFunc_t)pmod);
PM_RETURN_IF_ERROR(retval);
/* Interpret the module's bcode */
retval = interp_addThread((pPmFunc_t)pmod);
PM_RETURN_IF_ERROR(retval);
retval = interpret(INTERP_RETURN_ON_NO_THREADS);
/*
* De-initialize the hardware platform.
* Ignore plat_deinit's retval so interpret's retval returns to caller.
*/
plat_deinit();
return retval;
}
/* Warning: Can be called in interrupt context! */
PmReturn_t
pm_vmPeriodic(uint16_t usecsSinceLastCall)
{
/*
* Add the full milliseconds to pm_timerMsTicks and store additional
* microseconds for the next run. Thus, usecsSinceLastCall must be
* less than 2^16-1000 so it will not overflow usecResidual.
*/
static uint16_t usecResidual = 0;
C_ASSERT(usecsSinceLastCall < 64536);
usecResidual += usecsSinceLastCall;
while (usecResidual >= 1000)
{
usecResidual -= 1000;
pm_timerMsTicks++;
}
/* Check if enough time has passed for a scheduler run */
if ((pm_timerMsTicks - pm_lastRescheduleTimestamp)
>= PM_THREAD_TIMESLICE_MS)
{
interp_setRescheduleFlag((uint8_t)1);
pm_lastRescheduleTimestamp = pm_timerMsTicks;
}
return PM_RET_OK;
}