LP-89 - Port OP_15.05.01 fixes. Release notes:
[librepilot.git] / flight / libraries / PyMite / vm / pm.c
blob250339bdb00cee68df9a80bf90bccc93f94e0fda
1 /*
2 # This file is Copyright 2006, 2007, 2009, 2010 Dean Hall.
4 # This file is part of the PyMite VM.
5 # The PyMite VM is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2.
8 # The PyMite VM is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 # A copy of the GNU GENERAL PUBLIC LICENSE Version 2
12 # is seen in the file COPYING in this directory.
16 #undef __FILE_ID__
17 #define __FILE_ID__ 0x15
20 /**
21 * \file
22 * \brief PyMite User API
24 * High-level functions to initialize and run PyMite
28 #include "pm.h"
31 /** Number of millisecond-ticks to pass before scheduler is run */
32 #define PM_THREAD_TIMESLICE_MS 10
35 /** Stores the timer millisecond-ticks since system start */
36 volatile uint32_t pm_timerMsTicks = 0;
38 /** Stores tick timestamp of last scheduler run */
39 volatile uint32_t pm_lastRescheduleTimestamp = 0;
42 PmReturn_t
43 pm_init(PmMemSpace_t memspace, uint8_t const * const pusrimg)
45 PmReturn_t retval;
47 /* Initialize the hardware platform */
48 retval = plat_init();
49 PM_RETURN_IF_ERROR(retval);
51 /* Initialize the heap and the globals */
52 retval = heap_init();
53 PM_RETURN_IF_ERROR(retval);
55 retval = global_init();
56 PM_RETURN_IF_ERROR(retval);
58 /* Load usr image info if given */
59 if (pusrimg != C_NULL)
61 retval = img_appendToPath(memspace, pusrimg);
64 return retval;
68 PmReturn_t
69 pm_run(uint8_t const *modstr)
71 PmReturn_t retval;
72 pPmObj_t pmod;
73 pPmObj_t pstring;
74 uint8_t const *pmodstr = modstr;
76 /* Import module from global struct */
77 retval = string_new(&pmodstr, &pstring);
78 PM_RETURN_IF_ERROR(retval);
79 retval = mod_import(pstring, &pmod);
80 PM_RETURN_IF_ERROR(retval);
82 /* Load builtins into thread */
83 retval = global_setBuiltins((pPmFunc_t)pmod);
84 PM_RETURN_IF_ERROR(retval);
86 /* Interpret the module's bcode */
87 retval = interp_addThread((pPmFunc_t)pmod);
88 PM_RETURN_IF_ERROR(retval);
89 retval = interpret(INTERP_RETURN_ON_NO_THREADS);
92 * De-initialize the hardware platform.
93 * Ignore plat_deinit's retval so interpret's retval returns to caller.
95 plat_deinit();
97 return retval;
101 /* Warning: Can be called in interrupt context! */
102 PmReturn_t
103 pm_vmPeriodic(uint16_t usecsSinceLastCall)
106 * Add the full milliseconds to pm_timerMsTicks and store additional
107 * microseconds for the next run. Thus, usecsSinceLastCall must be
108 * less than 2^16-1000 so it will not overflow usecResidual.
110 static uint16_t usecResidual = 0;
112 C_ASSERT(usecsSinceLastCall < 64536);
114 usecResidual += usecsSinceLastCall;
115 while (usecResidual >= 1000)
117 usecResidual -= 1000;
118 pm_timerMsTicks++;
121 /* Check if enough time has passed for a scheduler run */
122 if ((pm_timerMsTicks - pm_lastRescheduleTimestamp)
123 >= PM_THREAD_TIMESLICE_MS)
125 interp_setRescheduleFlag((uint8_t)1);
126 pm_lastRescheduleTimestamp = pm_timerMsTicks;
128 return PM_RET_OK;