Port of MicroPython to the mbed platform. See micropython-repl for an interactive program.

Dependents:   micropython-repl

This a port of MicroPython to the mbed Classic platform.

This provides an interpreter running on the board's USB serial connection.

Getting Started

Import the micropython-repl program into your IDE workspace on developer.mbed.org. Compile and download to your board. Connect to the USB serial port in your usual manner. You should get a startup message similar to the following:

  MicroPython v1.7-155-gdddcdd8 on 2016-04-23; K64F with ARM
  Type "help()" for more information.
  >>>

Then you can start using micropython. For example:

  >>> from mbed import DigitalOut
  >>> from pins import LED1
  >>> led = DigitalOut(LED1)
  >>> led.write(1)

Requirements

You need approximately 100K of flash memory, so this will be no good for boards with smaller amounts of storage.

Caveats

This can be considered an alpha release of the port; things may not work; APIs may change in later releases. It is NOT an official part part the micropython project, so if anything doesn't work, blame me. If it does work, most of the credit is due to micropython.

  • Only a few of the mbed classes are available in micropython so far, and not all methods of those that are.
  • Only a few boards have their full range of pin names available; for others, only a few standard ones (USBTX, USBRX, LED1) are implemented.
  • The garbage collector is not yet implemented. The interpreter will gradually consume memory and then fail.
  • Exceptions from the mbed classes are not yet handled.
  • Asynchronous processing (e.g. events on inputs) is not supported.

Credits

  • Damien P. George and other contributors who created micropython.
  • Colin Hogben, author of this port.
Committer:
pythontech
Date:
Sat Apr 16 17:11:56 2016 +0000
Revision:
0:5868e8752d44
Child:
2:c89e95946844
Split off library from repl

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pythontech 0:5868e8752d44 1 /*
pythontech 0:5868e8752d44 2 * This file is part of the Micro Python project, http://micropython.org/
pythontech 0:5868e8752d44 3 *
pythontech 0:5868e8752d44 4 * The MIT License (MIT)
pythontech 0:5868e8752d44 5 *
pythontech 0:5868e8752d44 6 * Copyright (c) 2013, 2014 Damien P. George
pythontech 0:5868e8752d44 7 *
pythontech 0:5868e8752d44 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
pythontech 0:5868e8752d44 9 * of this software and associated documentation files (the "Software"), to deal
pythontech 0:5868e8752d44 10 * in the Software without restriction, including without limitation the rights
pythontech 0:5868e8752d44 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
pythontech 0:5868e8752d44 12 * copies of the Software, and to permit persons to whom the Software is
pythontech 0:5868e8752d44 13 * furnished to do so, subject to the following conditions:
pythontech 0:5868e8752d44 14 *
pythontech 0:5868e8752d44 15 * The above copyright notice and this permission notice shall be included in
pythontech 0:5868e8752d44 16 * all copies or substantial portions of the Software.
pythontech 0:5868e8752d44 17 *
pythontech 0:5868e8752d44 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
pythontech 0:5868e8752d44 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
pythontech 0:5868e8752d44 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
pythontech 0:5868e8752d44 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
pythontech 0:5868e8752d44 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
pythontech 0:5868e8752d44 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
pythontech 0:5868e8752d44 24 * THE SOFTWARE.
pythontech 0:5868e8752d44 25 */
pythontech 0:5868e8752d44 26
pythontech 0:5868e8752d44 27 #include <stdlib.h>
pythontech 0:5868e8752d44 28 #include <assert.h>
pythontech 0:5868e8752d44 29
pythontech 0:5868e8752d44 30 #include "py/mpstate.h"
pythontech 0:5868e8752d44 31 #include "py/nlr.h"
pythontech 0:5868e8752d44 32 #include "py/objmodule.h"
pythontech 0:5868e8752d44 33 #include "py/runtime.h"
pythontech 0:5868e8752d44 34 #include "py/builtin.h"
pythontech 0:5868e8752d44 35
pythontech 0:5868e8752d44 36 STATIC void module_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pythontech 0:5868e8752d44 37 (void)kind;
pythontech 0:5868e8752d44 38 mp_obj_module_t *self = MP_OBJ_TO_PTR(self_in);
pythontech 0:5868e8752d44 39
pythontech 0:5868e8752d44 40 #if MICROPY_PY___FILE__
pythontech 0:5868e8752d44 41 // If we store __file__ to imported modules then try to lookup this
pythontech 0:5868e8752d44 42 // symbol to give more information about the module.
pythontech 0:5868e8752d44 43 mp_map_elem_t *elem = mp_map_lookup(&self->globals->map, MP_OBJ_NEW_QSTR(MP_QSTR___file__), MP_MAP_LOOKUP);
pythontech 0:5868e8752d44 44 if (elem != NULL) {
pythontech 0:5868e8752d44 45 mp_printf(print, "<module '%q' from '%s'>", self->name, mp_obj_str_get_str(elem->value));
pythontech 0:5868e8752d44 46 return;
pythontech 0:5868e8752d44 47 }
pythontech 0:5868e8752d44 48 #endif
pythontech 0:5868e8752d44 49
pythontech 0:5868e8752d44 50 mp_printf(print, "<module '%q'>", self->name);
pythontech 0:5868e8752d44 51 }
pythontech 0:5868e8752d44 52
pythontech 0:5868e8752d44 53 STATIC void module_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
pythontech 0:5868e8752d44 54 mp_obj_module_t *self = MP_OBJ_TO_PTR(self_in);
pythontech 0:5868e8752d44 55 if (dest[0] == MP_OBJ_NULL) {
pythontech 0:5868e8752d44 56 // load attribute
pythontech 0:5868e8752d44 57 mp_map_elem_t *elem = mp_map_lookup(&self->globals->map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP);
pythontech 0:5868e8752d44 58 if (elem != NULL) {
pythontech 0:5868e8752d44 59 dest[0] = elem->value;
pythontech 0:5868e8752d44 60 }
pythontech 0:5868e8752d44 61 } else {
pythontech 0:5868e8752d44 62 // delete/store attribute
pythontech 0:5868e8752d44 63 mp_obj_dict_t *dict = self->globals;
pythontech 0:5868e8752d44 64 if (dict->map.is_fixed) {
pythontech 0:5868e8752d44 65 #if MICROPY_CAN_OVERRIDE_BUILTINS
pythontech 0:5868e8752d44 66 if (dict == &mp_module_builtins_globals) {
pythontech 0:5868e8752d44 67 if (MP_STATE_VM(mp_module_builtins_override_dict) == NULL) {
pythontech 0:5868e8752d44 68 MP_STATE_VM(mp_module_builtins_override_dict) = MP_OBJ_TO_PTR(mp_obj_new_dict(1));
pythontech 0:5868e8752d44 69 }
pythontech 0:5868e8752d44 70 dict = MP_STATE_VM(mp_module_builtins_override_dict);
pythontech 0:5868e8752d44 71 } else
pythontech 0:5868e8752d44 72 #endif
pythontech 0:5868e8752d44 73 {
pythontech 0:5868e8752d44 74 // can't delete or store to fixed map
pythontech 0:5868e8752d44 75 return;
pythontech 0:5868e8752d44 76 }
pythontech 0:5868e8752d44 77 }
pythontech 0:5868e8752d44 78 if (dest[1] == MP_OBJ_NULL) {
pythontech 0:5868e8752d44 79 // delete attribute
pythontech 0:5868e8752d44 80 mp_obj_dict_delete(MP_OBJ_FROM_PTR(dict), MP_OBJ_NEW_QSTR(attr));
pythontech 0:5868e8752d44 81 } else {
pythontech 0:5868e8752d44 82 // store attribute
pythontech 0:5868e8752d44 83 // TODO CPython allows STORE_ATTR to a module, but is this the correct implementation?
pythontech 0:5868e8752d44 84 mp_obj_dict_store(MP_OBJ_FROM_PTR(dict), MP_OBJ_NEW_QSTR(attr), dest[1]);
pythontech 0:5868e8752d44 85 }
pythontech 0:5868e8752d44 86 dest[0] = MP_OBJ_NULL; // indicate success
pythontech 0:5868e8752d44 87 }
pythontech 0:5868e8752d44 88 }
pythontech 0:5868e8752d44 89
pythontech 0:5868e8752d44 90 const mp_obj_type_t mp_type_module = {
pythontech 0:5868e8752d44 91 { &mp_type_type },
pythontech 0:5868e8752d44 92 .name = MP_QSTR_module,
pythontech 0:5868e8752d44 93 .print = module_print,
pythontech 0:5868e8752d44 94 .attr = module_attr,
pythontech 0:5868e8752d44 95 };
pythontech 0:5868e8752d44 96
pythontech 0:5868e8752d44 97 mp_obj_t mp_obj_new_module(qstr module_name) {
pythontech 0:5868e8752d44 98 mp_map_t *mp_loaded_modules_map = &MP_STATE_VM(mp_loaded_modules_dict).map;
pythontech 0:5868e8752d44 99 mp_map_elem_t *el = mp_map_lookup(mp_loaded_modules_map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
pythontech 0:5868e8752d44 100 // We could error out if module already exists, but let C extensions
pythontech 0:5868e8752d44 101 // add new members to existing modules.
pythontech 0:5868e8752d44 102 if (el->value != MP_OBJ_NULL) {
pythontech 0:5868e8752d44 103 return el->value;
pythontech 0:5868e8752d44 104 }
pythontech 0:5868e8752d44 105
pythontech 0:5868e8752d44 106 // create new module object
pythontech 0:5868e8752d44 107 mp_obj_module_t *o = m_new_obj(mp_obj_module_t);
pythontech 0:5868e8752d44 108 o->base.type = &mp_type_module;
pythontech 0:5868e8752d44 109 o->name = module_name;
pythontech 0:5868e8752d44 110 o->globals = MP_OBJ_TO_PTR(mp_obj_new_dict(MICROPY_MODULE_DICT_SIZE));
pythontech 0:5868e8752d44 111
pythontech 0:5868e8752d44 112 // store __name__ entry in the module
pythontech 0:5868e8752d44 113 mp_obj_dict_store(MP_OBJ_FROM_PTR(o->globals), MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(module_name));
pythontech 0:5868e8752d44 114
pythontech 0:5868e8752d44 115 // store the new module into the slot in the global dict holding all modules
pythontech 0:5868e8752d44 116 el->value = MP_OBJ_FROM_PTR(o);
pythontech 0:5868e8752d44 117
pythontech 0:5868e8752d44 118 // return the new module
pythontech 0:5868e8752d44 119 return MP_OBJ_FROM_PTR(o);
pythontech 0:5868e8752d44 120 }
pythontech 0:5868e8752d44 121
pythontech 0:5868e8752d44 122 mp_obj_dict_t *mp_obj_module_get_globals(mp_obj_t self_in) {
pythontech 0:5868e8752d44 123 assert(MP_OBJ_IS_TYPE(self_in, &mp_type_module));
pythontech 0:5868e8752d44 124 mp_obj_module_t *self = MP_OBJ_TO_PTR(self_in);
pythontech 0:5868e8752d44 125 return self->globals;
pythontech 0:5868e8752d44 126 }
pythontech 0:5868e8752d44 127
pythontech 0:5868e8752d44 128 /******************************************************************************/
pythontech 0:5868e8752d44 129 // Global module table and related functions
pythontech 0:5868e8752d44 130
pythontech 0:5868e8752d44 131 STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = {
pythontech 0:5868e8752d44 132 { MP_ROM_QSTR(MP_QSTR___main__), MP_ROM_PTR(&mp_module___main__) },
pythontech 0:5868e8752d44 133 { MP_ROM_QSTR(MP_QSTR_builtins), MP_ROM_PTR(&mp_module_builtins) },
pythontech 0:5868e8752d44 134 { MP_ROM_QSTR(MP_QSTR_micropython), MP_ROM_PTR(&mp_module_micropython) },
pythontech 0:5868e8752d44 135
pythontech 0:5868e8752d44 136 #if MICROPY_PY_ARRAY
pythontech 0:5868e8752d44 137 { MP_ROM_QSTR(MP_QSTR_array), MP_ROM_PTR(&mp_module_array) },
pythontech 0:5868e8752d44 138 #endif
pythontech 0:5868e8752d44 139 #if MICROPY_PY_IO
pythontech 0:5868e8752d44 140 { MP_ROM_QSTR(MP_QSTR__io), MP_ROM_PTR(&mp_module_io) },
pythontech 0:5868e8752d44 141 #endif
pythontech 0:5868e8752d44 142 #if MICROPY_PY_COLLECTIONS
pythontech 0:5868e8752d44 143 { MP_ROM_QSTR(MP_QSTR__collections), MP_ROM_PTR(&mp_module_collections) },
pythontech 0:5868e8752d44 144 #endif
pythontech 0:5868e8752d44 145 #if MICROPY_PY_STRUCT
pythontech 0:5868e8752d44 146 { MP_ROM_QSTR(MP_QSTR_ustruct), MP_ROM_PTR(&mp_module_ustruct) },
pythontech 0:5868e8752d44 147 #endif
pythontech 0:5868e8752d44 148
pythontech 0:5868e8752d44 149 #if MICROPY_PY_BUILTINS_FLOAT
pythontech 0:5868e8752d44 150 #if MICROPY_PY_MATH
pythontech 0:5868e8752d44 151 { MP_ROM_QSTR(MP_QSTR_math), MP_ROM_PTR(&mp_module_math) },
pythontech 0:5868e8752d44 152 #endif
pythontech 0:5868e8752d44 153 #if MICROPY_PY_BUILTINS_COMPLEX && MICROPY_PY_CMATH
pythontech 0:5868e8752d44 154 { MP_ROM_QSTR(MP_QSTR_cmath), MP_ROM_PTR(&mp_module_cmath) },
pythontech 0:5868e8752d44 155 #endif
pythontech 0:5868e8752d44 156 #endif
pythontech 0:5868e8752d44 157 #if MICROPY_PY_SYS
pythontech 0:5868e8752d44 158 { MP_ROM_QSTR(MP_QSTR_sys), MP_ROM_PTR(&mp_module_sys) },
pythontech 0:5868e8752d44 159 #endif
pythontech 0:5868e8752d44 160 #if MICROPY_PY_GC && MICROPY_ENABLE_GC
pythontech 0:5868e8752d44 161 { MP_ROM_QSTR(MP_QSTR_gc), MP_ROM_PTR(&mp_module_gc) },
pythontech 0:5868e8752d44 162 #endif
pythontech 0:5868e8752d44 163
pythontech 0:5868e8752d44 164 // extmod modules
pythontech 0:5868e8752d44 165
pythontech 0:5868e8752d44 166 #if MICROPY_PY_UCTYPES
pythontech 0:5868e8752d44 167 { MP_ROM_QSTR(MP_QSTR_uctypes), MP_ROM_PTR(&mp_module_uctypes) },
pythontech 0:5868e8752d44 168 #endif
pythontech 0:5868e8752d44 169 #if MICROPY_PY_UZLIB
pythontech 0:5868e8752d44 170 { MP_ROM_QSTR(MP_QSTR_uzlib), MP_ROM_PTR(&mp_module_uzlib) },
pythontech 0:5868e8752d44 171 #endif
pythontech 0:5868e8752d44 172 #if MICROPY_PY_UJSON
pythontech 0:5868e8752d44 173 { MP_ROM_QSTR(MP_QSTR_ujson), MP_ROM_PTR(&mp_module_ujson) },
pythontech 0:5868e8752d44 174 #endif
pythontech 0:5868e8752d44 175 #if MICROPY_PY_URE
pythontech 0:5868e8752d44 176 { MP_ROM_QSTR(MP_QSTR_ure), MP_ROM_PTR(&mp_module_ure) },
pythontech 0:5868e8752d44 177 #endif
pythontech 0:5868e8752d44 178 #if MICROPY_PY_UHEAPQ
pythontech 0:5868e8752d44 179 { MP_ROM_QSTR(MP_QSTR_uheapq), MP_ROM_PTR(&mp_module_uheapq) },
pythontech 0:5868e8752d44 180 #endif
pythontech 0:5868e8752d44 181 #if MICROPY_PY_UHASHLIB
pythontech 0:5868e8752d44 182 { MP_ROM_QSTR(MP_QSTR_uhashlib), MP_ROM_PTR(&mp_module_uhashlib) },
pythontech 0:5868e8752d44 183 #endif
pythontech 0:5868e8752d44 184 #if MICROPY_PY_UBINASCII
pythontech 0:5868e8752d44 185 { MP_ROM_QSTR(MP_QSTR_ubinascii), MP_ROM_PTR(&mp_module_ubinascii) },
pythontech 0:5868e8752d44 186 #endif
pythontech 0:5868e8752d44 187 #if MICROPY_PY_URANDOM
pythontech 0:5868e8752d44 188 { MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&mp_module_urandom) },
pythontech 0:5868e8752d44 189 #endif
pythontech 0:5868e8752d44 190 #if MICROPY_PY_USSL
pythontech 0:5868e8752d44 191 { MP_ROM_QSTR(MP_QSTR_ussl), MP_ROM_PTR(&mp_module_ussl) },
pythontech 0:5868e8752d44 192 #endif
pythontech 0:5868e8752d44 193 #if MICROPY_PY_LWIP
pythontech 0:5868e8752d44 194 { MP_ROM_QSTR(MP_QSTR_lwip), MP_ROM_PTR(&mp_module_lwip) },
pythontech 0:5868e8752d44 195 #endif
pythontech 0:5868e8752d44 196 #if MICROPY_PY_WEBSOCKET
pythontech 0:5868e8752d44 197 { MP_ROM_QSTR(MP_QSTR_websocket), MP_ROM_PTR(&mp_module_websocket) },
pythontech 0:5868e8752d44 198 #endif
pythontech 0:5868e8752d44 199
pythontech 0:5868e8752d44 200 // extra builtin modules as defined by a port
pythontech 0:5868e8752d44 201 MICROPY_PORT_BUILTIN_MODULES
pythontech 0:5868e8752d44 202 };
pythontech 0:5868e8752d44 203
pythontech 0:5868e8752d44 204 STATIC MP_DEFINE_CONST_MAP(mp_builtin_module_map, mp_builtin_module_table);
pythontech 0:5868e8752d44 205
pythontech 0:5868e8752d44 206 void mp_module_init(void) {
pythontech 0:5868e8752d44 207 mp_obj_dict_init(&MP_STATE_VM(mp_loaded_modules_dict), 3);
pythontech 0:5868e8752d44 208 }
pythontech 0:5868e8752d44 209
pythontech 0:5868e8752d44 210 void mp_module_deinit(void) {
pythontech 0:5868e8752d44 211 //mp_map_deinit(&MP_STATE_VM(mp_loaded_modules_map));
pythontech 0:5868e8752d44 212 }
pythontech 0:5868e8752d44 213
pythontech 0:5868e8752d44 214 // returns MP_OBJ_NULL if not found
pythontech 0:5868e8752d44 215 mp_obj_t mp_module_get(qstr module_name) {
pythontech 0:5868e8752d44 216 mp_map_t *mp_loaded_modules_map = &MP_STATE_VM(mp_loaded_modules_dict).map;
pythontech 0:5868e8752d44 217 // lookup module
pythontech 0:5868e8752d44 218 mp_map_elem_t *el = mp_map_lookup(mp_loaded_modules_map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP);
pythontech 0:5868e8752d44 219
pythontech 0:5868e8752d44 220 if (el == NULL) {
pythontech 0:5868e8752d44 221 // module not found, look for builtin module names
pythontech 0:5868e8752d44 222 el = mp_map_lookup((mp_map_t*)&mp_builtin_module_map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP);
pythontech 0:5868e8752d44 223 if (el == NULL) {
pythontech 0:5868e8752d44 224 return MP_OBJ_NULL;
pythontech 0:5868e8752d44 225 }
pythontech 0:5868e8752d44 226
pythontech 0:5868e8752d44 227 if (MICROPY_MODULE_BUILTIN_INIT) {
pythontech 0:5868e8752d44 228 // look for __init__ and call it if it exists
pythontech 0:5868e8752d44 229 mp_obj_t dest[2];
pythontech 0:5868e8752d44 230 mp_load_method_maybe(el->value, MP_QSTR___init__, dest);
pythontech 0:5868e8752d44 231 if (dest[0] != MP_OBJ_NULL) {
pythontech 0:5868e8752d44 232 mp_call_method_n_kw(0, 0, dest);
pythontech 0:5868e8752d44 233 // register module so __init__ is not called again
pythontech 0:5868e8752d44 234 mp_module_register(module_name, el->value);
pythontech 0:5868e8752d44 235 }
pythontech 0:5868e8752d44 236 }
pythontech 0:5868e8752d44 237 }
pythontech 0:5868e8752d44 238
pythontech 0:5868e8752d44 239 // module found, return it
pythontech 0:5868e8752d44 240 return el->value;
pythontech 0:5868e8752d44 241 }
pythontech 0:5868e8752d44 242
pythontech 0:5868e8752d44 243 void mp_module_register(qstr qst, mp_obj_t module) {
pythontech 0:5868e8752d44 244 mp_map_t *mp_loaded_modules_map = &MP_STATE_VM(mp_loaded_modules_dict).map;
pythontech 0:5868e8752d44 245 mp_map_lookup(mp_loaded_modules_map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = module;
pythontech 0:5868e8752d44 246 }