python-on-a-chip online compiler

Dependencies:   mbed TSI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pm.c Source File

pm.c

Go to the documentation of this file.
00001 /*
00002 # This file is Copyright 2006 Dean Hall.
00003 # This file is part of the PyMite VM.
00004 # This file is licensed under the MIT License.
00005 # See the LICENSE file for details.
00006 */
00007 
00008 
00009 #undef __FILE_ID__
00010 #define __FILE_ID__ 0x15
00011 
00012 
00013 /**
00014  * \file
00015  * \brief PyMite User API
00016  *
00017  * High-level functions to initialize and run PyMite
00018  */
00019 
00020 
00021 #include "pm.h"
00022 
00023 
00024 /** Number of millisecond-ticks to pass before scheduler is run */
00025 #define PM_THREAD_TIMESLICE_MS  10
00026 
00027 
00028 /** Stores the timer millisecond-ticks since system start */
00029 volatile uint32_t pm_timerMsTicks = 0;
00030 
00031 /** Stores tick timestamp of last scheduler run */
00032 volatile uint32_t pm_lastRescheduleTimestamp = 0;
00033 
00034 
00035 PmReturn_t
00036 pm_init(uint8_t *heap_base, uint32_t heap_size,
00037         PmMemSpace_t memspace, uint8_t const * const pusrimg)
00038 {
00039     PmReturn_t retval;
00040 
00041     /* Initialize the hardware platform */
00042     retval = plat_init();
00043     PM_RETURN_IF_ERROR(retval);
00044 
00045     /* Initialize the heap and the globals */
00046     retval = heap_init(heap_base, heap_size);
00047     PM_RETURN_IF_ERROR(retval);
00048 
00049     retval = global_init();
00050     PM_RETURN_IF_ERROR(retval);
00051 
00052     /* Load usr image info if given */
00053     if (pusrimg != C_NULL)
00054     {
00055         retval = img_appendToPath(memspace, pusrimg);
00056     }
00057 
00058     return retval;
00059 }
00060 
00061 
00062 PmReturn_t
00063 pm_run(uint8_t const *modstr)
00064 {
00065     PmReturn_t retval;
00066     pPmObj_t pmod;
00067     pPmObj_t pstring;
00068     uint8_t const *pmodstr = modstr;
00069     uint8_t objid1;
00070     uint8_t objid2;
00071 
00072     /* Import module from global struct */
00073     retval = string_new(&pmodstr, &pstring);
00074     PM_RETURN_IF_ERROR(retval);
00075     heap_gcPushTempRoot(pstring, &objid1);
00076     retval = mod_import(pstring, &pmod);
00077     PM_RETURN_IF_ERROR(retval);
00078 
00079     /* Load builtins into thread */
00080     heap_gcPushTempRoot(pmod, &objid2);
00081     retval = global_setBuiltins((pPmFunc_t)pmod);
00082     PM_RETURN_IF_ERROR(retval);
00083 
00084     /* Interpret the module's bcode */
00085     retval = interp_addThread((pPmFunc_t)pmod);
00086     PM_RETURN_IF_ERROR(retval);
00087     heap_gcPopTempRoot(objid1);
00088     retval = interpret(INTERP_RETURN_ON_NO_THREADS);
00089 
00090     /*
00091      * De-initialize the hardware platform.
00092      * Ignore plat_deinit's retval so interpret's retval returns to caller.
00093      */
00094     plat_deinit();
00095 
00096     return retval;
00097 }
00098 
00099 
00100 /* Warning: Can be called in interrupt context! */
00101 PmReturn_t
00102 pm_vmPeriodic(uint16_t usecsSinceLastCall)
00103 {
00104     /*
00105      * Add the full milliseconds to pm_timerMsTicks and store additional
00106      * microseconds for the next run. Thus, usecsSinceLastCall must be
00107      * less than 2^16-1000 so it will not overflow usecResidual.
00108      */
00109     static uint16_t usecResidual = 0;
00110 
00111     C_ASSERT(usecsSinceLastCall < 64536);
00112 
00113     usecResidual += usecsSinceLastCall;
00114     while (usecResidual >= 1000)
00115     {
00116         usecResidual -= 1000;
00117         pm_timerMsTicks++;
00118     }
00119 
00120     /* Check if enough time has passed for a scheduler run */
00121     if ((pm_timerMsTicks - pm_lastRescheduleTimestamp)
00122         >= PM_THREAD_TIMESLICE_MS)
00123     {
00124         interp_setRescheduleFlag((uint8_t)1);
00125         pm_lastRescheduleTimestamp = pm_timerMsTicks;
00126     }
00127     return PM_RET_OK;
00128 }