pm.c

Go to the documentation of this file.
00001 /*
00002 # This file is Copyright 2006, 2007, 2009, 2010 Dean Hall.
00003 #
00004 # This file is part of the PyMite VM.
00005 # The PyMite VM is free software: you can redistribute it and/or modify
00006 # it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2.
00007 #
00008 # The PyMite VM is distributed in the hope that it will be useful,
00009 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00011 # A copy of the GNU GENERAL PUBLIC LICENSE Version 2
00012 # is seen in the file COPYING in this directory.
00013 */
00014 
00015 
00016 #undef __FILE_ID__
00017 #define __FILE_ID__ 0x15
00018 
00019 
00028 #include "pm.h"
00029 
00030 
00032 #define PM_THREAD_TIMESLICE_MS  10
00033 
00034 
00036 volatile uint32_t pm_timerMsTicks = 0;
00037 
00039 volatile uint32_t pm_lastRescheduleTimestamp = 0;
00040 
00041 
00042 PmReturn_t
00043 pm_init(PmMemSpace_t memspace, uint8_t const * const pusrimg)
00044 {
00045     PmReturn_t retval;
00046 
00047     /* Initialize the hardware platform */
00048     retval = plat_init();
00049     PM_RETURN_IF_ERROR(retval);
00050 
00051     /* Initialize the heap and the globals */
00052     retval = heap_init();
00053     PM_RETURN_IF_ERROR(retval);
00054 
00055     retval = global_init();
00056     PM_RETURN_IF_ERROR(retval);
00057 
00058     /* Load usr image info if given */
00059     if (pusrimg != C_NULL)
00060     {
00061         retval = img_appendToPath(memspace, pusrimg);
00062     }
00063 
00064     return retval;
00065 }
00066 
00067 
00068 PmReturn_t
00069 pm_run(uint8_t const *modstr)
00070 {
00071     PmReturn_t retval;
00072     pPmObj_t pmod;
00073     pPmObj_t pstring;
00074     uint8_t const *pmodstr = modstr;
00075 
00076     /* Import module from global struct */
00077     retval = string_new(&pmodstr, &pstring);
00078     PM_RETURN_IF_ERROR(retval);
00079     retval = mod_import(pstring, &pmod);
00080     PM_RETURN_IF_ERROR(retval);
00081 
00082     /* Load builtins into thread */
00083     retval = global_setBuiltins((pPmFunc_t)pmod);
00084     PM_RETURN_IF_ERROR(retval);
00085 
00086     /* Interpret the module's bcode */
00087     retval = interp_addThread((pPmFunc_t)pmod);
00088     PM_RETURN_IF_ERROR(retval);
00089     retval = interpret(INTERP_RETURN_ON_NO_THREADS);
00090 
00091     /*
00092      * De-initialize the hardware platform.
00093      * Ignore plat_deinit's retval so interpret's retval returns to caller.
00094      */
00095     plat_deinit();
00096 
00097     return retval;
00098 }
00099 
00100 
00101 /* Warning: Can be called in interrupt context! */
00102 PmReturn_t
00103 pm_vmPeriodic(uint16_t usecsSinceLastCall)
00104 {
00105     /*
00106      * Add the full milliseconds to pm_timerMsTicks and store additional
00107      * microseconds for the next run. Thus, usecsSinceLastCall must be
00108      * less than 2^16-1000 so it will not overflow usecResidual.
00109      */
00110     static uint16_t usecResidual = 0;
00111 
00112     C_ASSERT(usecsSinceLastCall < 64536);
00113 
00114     usecResidual += usecsSinceLastCall;
00115     while (usecResidual >= 1000)
00116     {
00117         usecResidual -= 1000;
00118         pm_timerMsTicks++;
00119     }
00120 
00121     /* Check if enough time has passed for a scheduler run */
00122     if ((pm_timerMsTicks - pm_lastRescheduleTimestamp)
00123         >= PM_THREAD_TIMESLICE_MS)
00124     {
00125         interp_setRescheduleFlag((uint8_t)1);
00126         pm_lastRescheduleTimestamp = pm_timerMsTicks;
00127     }
00128     return PM_RET_OK;
00129 }

Generated on Mon Oct 18 07:40:48 2010 for Python-on-a-chip by  doxygen 1.5.9