Norimasa Okamoto
/
pymite
python-on-a-chip online compiler
- http://pymbed.appspot.com/
- https://code.google.com/p/python-on-a-chip/
- http://www.youtube.com/watch?v=Oyqc2bFRW9I
- https://bitbucket.org/va009039/pymbed/
more info: python-on-a-chip
vm/pm.c@15:94ca5c8003e5, 2016-04-14 (annotated)
- Committer:
- va009039
- Date:
- Thu Apr 14 22:32:57 2016 +0000
- Revision:
- 15:94ca5c8003e5
- Parent:
- 0:65f1469d6bfb
update Nucleo-F401RE.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 0:65f1469d6bfb | 1 | /* |
va009039 | 0:65f1469d6bfb | 2 | # This file is Copyright 2006 Dean Hall. |
va009039 | 0:65f1469d6bfb | 3 | # This file is part of the PyMite VM. |
va009039 | 0:65f1469d6bfb | 4 | # This file is licensed under the MIT License. |
va009039 | 0:65f1469d6bfb | 5 | # See the LICENSE file for details. |
va009039 | 0:65f1469d6bfb | 6 | */ |
va009039 | 0:65f1469d6bfb | 7 | |
va009039 | 0:65f1469d6bfb | 8 | |
va009039 | 0:65f1469d6bfb | 9 | #undef __FILE_ID__ |
va009039 | 0:65f1469d6bfb | 10 | #define __FILE_ID__ 0x15 |
va009039 | 0:65f1469d6bfb | 11 | |
va009039 | 0:65f1469d6bfb | 12 | |
va009039 | 0:65f1469d6bfb | 13 | /** |
va009039 | 0:65f1469d6bfb | 14 | * \file |
va009039 | 0:65f1469d6bfb | 15 | * \brief PyMite User API |
va009039 | 0:65f1469d6bfb | 16 | * |
va009039 | 0:65f1469d6bfb | 17 | * High-level functions to initialize and run PyMite |
va009039 | 0:65f1469d6bfb | 18 | */ |
va009039 | 0:65f1469d6bfb | 19 | |
va009039 | 0:65f1469d6bfb | 20 | |
va009039 | 0:65f1469d6bfb | 21 | #include "pm.h" |
va009039 | 0:65f1469d6bfb | 22 | |
va009039 | 0:65f1469d6bfb | 23 | |
va009039 | 0:65f1469d6bfb | 24 | /** Number of millisecond-ticks to pass before scheduler is run */ |
va009039 | 0:65f1469d6bfb | 25 | #define PM_THREAD_TIMESLICE_MS 10 |
va009039 | 0:65f1469d6bfb | 26 | |
va009039 | 0:65f1469d6bfb | 27 | |
va009039 | 0:65f1469d6bfb | 28 | /** Stores the timer millisecond-ticks since system start */ |
va009039 | 0:65f1469d6bfb | 29 | volatile uint32_t pm_timerMsTicks = 0; |
va009039 | 0:65f1469d6bfb | 30 | |
va009039 | 0:65f1469d6bfb | 31 | /** Stores tick timestamp of last scheduler run */ |
va009039 | 0:65f1469d6bfb | 32 | volatile uint32_t pm_lastRescheduleTimestamp = 0; |
va009039 | 0:65f1469d6bfb | 33 | |
va009039 | 0:65f1469d6bfb | 34 | |
va009039 | 0:65f1469d6bfb | 35 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 36 | pm_init(uint8_t *heap_base, uint32_t heap_size, |
va009039 | 0:65f1469d6bfb | 37 | PmMemSpace_t memspace, uint8_t const * const pusrimg) |
va009039 | 0:65f1469d6bfb | 38 | { |
va009039 | 0:65f1469d6bfb | 39 | PmReturn_t retval; |
va009039 | 0:65f1469d6bfb | 40 | |
va009039 | 0:65f1469d6bfb | 41 | /* Initialize the hardware platform */ |
va009039 | 0:65f1469d6bfb | 42 | retval = plat_init(); |
va009039 | 0:65f1469d6bfb | 43 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 44 | |
va009039 | 0:65f1469d6bfb | 45 | /* Initialize the heap and the globals */ |
va009039 | 0:65f1469d6bfb | 46 | retval = heap_init(heap_base, heap_size); |
va009039 | 0:65f1469d6bfb | 47 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 48 | |
va009039 | 0:65f1469d6bfb | 49 | retval = global_init(); |
va009039 | 0:65f1469d6bfb | 50 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 51 | |
va009039 | 0:65f1469d6bfb | 52 | /* Load usr image info if given */ |
va009039 | 0:65f1469d6bfb | 53 | if (pusrimg != C_NULL) |
va009039 | 0:65f1469d6bfb | 54 | { |
va009039 | 0:65f1469d6bfb | 55 | retval = img_appendToPath(memspace, pusrimg); |
va009039 | 0:65f1469d6bfb | 56 | } |
va009039 | 0:65f1469d6bfb | 57 | |
va009039 | 0:65f1469d6bfb | 58 | return retval; |
va009039 | 0:65f1469d6bfb | 59 | } |
va009039 | 0:65f1469d6bfb | 60 | |
va009039 | 0:65f1469d6bfb | 61 | |
va009039 | 0:65f1469d6bfb | 62 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 63 | pm_run(uint8_t const *modstr) |
va009039 | 0:65f1469d6bfb | 64 | { |
va009039 | 0:65f1469d6bfb | 65 | PmReturn_t retval; |
va009039 | 0:65f1469d6bfb | 66 | pPmObj_t pmod; |
va009039 | 0:65f1469d6bfb | 67 | pPmObj_t pstring; |
va009039 | 0:65f1469d6bfb | 68 | uint8_t const *pmodstr = modstr; |
va009039 | 0:65f1469d6bfb | 69 | uint8_t objid1; |
va009039 | 0:65f1469d6bfb | 70 | uint8_t objid2; |
va009039 | 0:65f1469d6bfb | 71 | |
va009039 | 0:65f1469d6bfb | 72 | /* Import module from global struct */ |
va009039 | 0:65f1469d6bfb | 73 | retval = string_new(&pmodstr, &pstring); |
va009039 | 0:65f1469d6bfb | 74 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 75 | heap_gcPushTempRoot(pstring, &objid1); |
va009039 | 0:65f1469d6bfb | 76 | retval = mod_import(pstring, &pmod); |
va009039 | 0:65f1469d6bfb | 77 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 78 | |
va009039 | 0:65f1469d6bfb | 79 | /* Load builtins into thread */ |
va009039 | 0:65f1469d6bfb | 80 | heap_gcPushTempRoot(pmod, &objid2); |
va009039 | 0:65f1469d6bfb | 81 | retval = global_setBuiltins((pPmFunc_t)pmod); |
va009039 | 0:65f1469d6bfb | 82 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 83 | |
va009039 | 0:65f1469d6bfb | 84 | /* Interpret the module's bcode */ |
va009039 | 0:65f1469d6bfb | 85 | retval = interp_addThread((pPmFunc_t)pmod); |
va009039 | 0:65f1469d6bfb | 86 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 87 | heap_gcPopTempRoot(objid1); |
va009039 | 0:65f1469d6bfb | 88 | retval = interpret(INTERP_RETURN_ON_NO_THREADS); |
va009039 | 0:65f1469d6bfb | 89 | |
va009039 | 0:65f1469d6bfb | 90 | /* |
va009039 | 0:65f1469d6bfb | 91 | * De-initialize the hardware platform. |
va009039 | 0:65f1469d6bfb | 92 | * Ignore plat_deinit's retval so interpret's retval returns to caller. |
va009039 | 0:65f1469d6bfb | 93 | */ |
va009039 | 0:65f1469d6bfb | 94 | plat_deinit(); |
va009039 | 0:65f1469d6bfb | 95 | |
va009039 | 0:65f1469d6bfb | 96 | return retval; |
va009039 | 0:65f1469d6bfb | 97 | } |
va009039 | 0:65f1469d6bfb | 98 | |
va009039 | 0:65f1469d6bfb | 99 | |
va009039 | 0:65f1469d6bfb | 100 | /* Warning: Can be called in interrupt context! */ |
va009039 | 0:65f1469d6bfb | 101 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 102 | pm_vmPeriodic(uint16_t usecsSinceLastCall) |
va009039 | 0:65f1469d6bfb | 103 | { |
va009039 | 0:65f1469d6bfb | 104 | /* |
va009039 | 0:65f1469d6bfb | 105 | * Add the full milliseconds to pm_timerMsTicks and store additional |
va009039 | 0:65f1469d6bfb | 106 | * microseconds for the next run. Thus, usecsSinceLastCall must be |
va009039 | 0:65f1469d6bfb | 107 | * less than 2^16-1000 so it will not overflow usecResidual. |
va009039 | 0:65f1469d6bfb | 108 | */ |
va009039 | 0:65f1469d6bfb | 109 | static uint16_t usecResidual = 0; |
va009039 | 0:65f1469d6bfb | 110 | |
va009039 | 0:65f1469d6bfb | 111 | C_ASSERT(usecsSinceLastCall < 64536); |
va009039 | 0:65f1469d6bfb | 112 | |
va009039 | 0:65f1469d6bfb | 113 | usecResidual += usecsSinceLastCall; |
va009039 | 0:65f1469d6bfb | 114 | while (usecResidual >= 1000) |
va009039 | 0:65f1469d6bfb | 115 | { |
va009039 | 0:65f1469d6bfb | 116 | usecResidual -= 1000; |
va009039 | 0:65f1469d6bfb | 117 | pm_timerMsTicks++; |
va009039 | 0:65f1469d6bfb | 118 | } |
va009039 | 0:65f1469d6bfb | 119 | |
va009039 | 0:65f1469d6bfb | 120 | /* Check if enough time has passed for a scheduler run */ |
va009039 | 0:65f1469d6bfb | 121 | if ((pm_timerMsTicks - pm_lastRescheduleTimestamp) |
va009039 | 0:65f1469d6bfb | 122 | >= PM_THREAD_TIMESLICE_MS) |
va009039 | 0:65f1469d6bfb | 123 | { |
va009039 | 0:65f1469d6bfb | 124 | interp_setRescheduleFlag((uint8_t)1); |
va009039 | 0:65f1469d6bfb | 125 | pm_lastRescheduleTimestamp = pm_timerMsTicks; |
va009039 | 0:65f1469d6bfb | 126 | } |
va009039 | 0:65f1469d6bfb | 127 | return PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 128 | } |