Norimasa Okamoto
/
pymite
python-on-a-chip online compiler
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Tue Jul 12 2022 23:13:47 by 1.7.2