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:
Colin Hogben
Date:
Wed Apr 27 22:11:29 2016 +0100
Revision:
10:33521d742af1
Parent:
0:5868e8752d44
Update README and version

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 * Copyright (c) 2014 Paul Sokolovsky
pythontech 0:5868e8752d44 8 *
pythontech 0:5868e8752d44 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
pythontech 0:5868e8752d44 10 * of this software and associated documentation files (the "Software"), to deal
pythontech 0:5868e8752d44 11 * in the Software without restriction, including without limitation the rights
pythontech 0:5868e8752d44 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
pythontech 0:5868e8752d44 13 * copies of the Software, and to permit persons to whom the Software is
pythontech 0:5868e8752d44 14 * furnished to do so, subject to the following conditions:
pythontech 0:5868e8752d44 15 *
pythontech 0:5868e8752d44 16 * The above copyright notice and this permission notice shall be included in
pythontech 0:5868e8752d44 17 * all copies or substantial portions of the Software.
pythontech 0:5868e8752d44 18 *
pythontech 0:5868e8752d44 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
pythontech 0:5868e8752d44 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
pythontech 0:5868e8752d44 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
pythontech 0:5868e8752d44 22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
pythontech 0:5868e8752d44 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
pythontech 0:5868e8752d44 24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
pythontech 0:5868e8752d44 25 * THE SOFTWARE.
pythontech 0:5868e8752d44 26 */
pythontech 0:5868e8752d44 27
pythontech 0:5868e8752d44 28 #include <assert.h>
pythontech 0:5868e8752d44 29 #include <string.h>
pythontech 0:5868e8752d44 30
pythontech 0:5868e8752d44 31 #include "py/runtime.h"
pythontech 0:5868e8752d44 32 #include "py/builtin.h"
pythontech 0:5868e8752d44 33 #include "py/objtuple.h"
pythontech 0:5868e8752d44 34 #include "py/binary.h"
pythontech 0:5868e8752d44 35 #include "py/parsenum.h"
pythontech 0:5868e8752d44 36
pythontech 0:5868e8752d44 37 #if MICROPY_PY_STRUCT
pythontech 0:5868e8752d44 38
pythontech 0:5868e8752d44 39 /*
pythontech 0:5868e8752d44 40 This module implements most of character typecodes from CPython, with
pythontech 0:5868e8752d44 41 some extensions:
pythontech 0:5868e8752d44 42
pythontech 0:5868e8752d44 43 O - (Pointer to) an arbitrary Python object. This is useful for callback
pythontech 0:5868e8752d44 44 data, etc. Note that you must keep reference to passed object in
pythontech 0:5868e8752d44 45 your Python application, otherwise it may be garbage-collected,
pythontech 0:5868e8752d44 46 and then when you get back this value from callback it may be
pythontech 0:5868e8752d44 47 invalid (and lead to crash).
pythontech 0:5868e8752d44 48 S - Pointer to a string (returned as a Python string). Note the
pythontech 0:5868e8752d44 49 difference from "Ns", - the latter says "in this place of structure
pythontech 0:5868e8752d44 50 is character data of up to N bytes length", while "S" means
pythontech 0:5868e8752d44 51 "in this place of a structure is a pointer to zero-terminated
pythontech 0:5868e8752d44 52 character data".
pythontech 0:5868e8752d44 53 */
pythontech 0:5868e8752d44 54
pythontech 0:5868e8752d44 55 STATIC char get_fmt_type(const char **fmt) {
pythontech 0:5868e8752d44 56 char t = **fmt;
pythontech 0:5868e8752d44 57 switch (t) {
pythontech 0:5868e8752d44 58 case '!':
pythontech 0:5868e8752d44 59 t = '>';
pythontech 0:5868e8752d44 60 break;
pythontech 0:5868e8752d44 61 case '@':
pythontech 0:5868e8752d44 62 case '=':
pythontech 0:5868e8752d44 63 case '<':
pythontech 0:5868e8752d44 64 case '>':
pythontech 0:5868e8752d44 65 break;
pythontech 0:5868e8752d44 66 default:
pythontech 0:5868e8752d44 67 return '@';
pythontech 0:5868e8752d44 68 }
pythontech 0:5868e8752d44 69 // Skip type char
pythontech 0:5868e8752d44 70 (*fmt)++;
pythontech 0:5868e8752d44 71 return t;
pythontech 0:5868e8752d44 72 }
pythontech 0:5868e8752d44 73
pythontech 0:5868e8752d44 74 STATIC mp_uint_t get_fmt_num(const char **p) {
pythontech 0:5868e8752d44 75 const char *num = *p;
pythontech 0:5868e8752d44 76 uint len = 1;
pythontech 0:5868e8752d44 77 while (unichar_isdigit(*++num)) {
pythontech 0:5868e8752d44 78 len++;
pythontech 0:5868e8752d44 79 }
pythontech 0:5868e8752d44 80 mp_uint_t val = (mp_uint_t)MP_OBJ_SMALL_INT_VALUE(mp_parse_num_integer(*p, len, 10, NULL));
pythontech 0:5868e8752d44 81 *p = num;
pythontech 0:5868e8752d44 82 return val;
pythontech 0:5868e8752d44 83 }
pythontech 0:5868e8752d44 84
pythontech 0:5868e8752d44 85 STATIC uint calcsize_items(const char *fmt) {
pythontech 0:5868e8752d44 86 uint cnt = 0;
pythontech 0:5868e8752d44 87 while (*fmt) {
pythontech 0:5868e8752d44 88 int num = 1;
pythontech 0:5868e8752d44 89 if (unichar_isdigit(*fmt)) {
pythontech 0:5868e8752d44 90 num = get_fmt_num(&fmt);
pythontech 0:5868e8752d44 91 if (*fmt == 's') {
pythontech 0:5868e8752d44 92 num = 1;
pythontech 0:5868e8752d44 93 }
pythontech 0:5868e8752d44 94 }
pythontech 0:5868e8752d44 95 cnt += num;
pythontech 0:5868e8752d44 96 fmt++;
pythontech 0:5868e8752d44 97 }
pythontech 0:5868e8752d44 98 return cnt;
pythontech 0:5868e8752d44 99 }
pythontech 0:5868e8752d44 100
pythontech 0:5868e8752d44 101 STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {
pythontech 0:5868e8752d44 102 const char *fmt = mp_obj_str_get_str(fmt_in);
pythontech 0:5868e8752d44 103 char fmt_type = get_fmt_type(&fmt);
pythontech 0:5868e8752d44 104 mp_uint_t size;
pythontech 0:5868e8752d44 105 for (size = 0; *fmt; fmt++) {
pythontech 0:5868e8752d44 106 mp_uint_t align = 1;
pythontech 0:5868e8752d44 107 mp_uint_t cnt = 1;
pythontech 0:5868e8752d44 108 if (unichar_isdigit(*fmt)) {
pythontech 0:5868e8752d44 109 cnt = get_fmt_num(&fmt);
pythontech 0:5868e8752d44 110 }
pythontech 0:5868e8752d44 111
pythontech 0:5868e8752d44 112 mp_uint_t sz = 0;
pythontech 0:5868e8752d44 113 if (*fmt == 's') {
pythontech 0:5868e8752d44 114 sz = cnt;
pythontech 0:5868e8752d44 115 cnt = 1;
pythontech 0:5868e8752d44 116 }
pythontech 0:5868e8752d44 117
pythontech 0:5868e8752d44 118 while (cnt--) {
pythontech 0:5868e8752d44 119 // If we already have size for 's' case, don't set it again
pythontech 0:5868e8752d44 120 if (sz == 0) {
pythontech 0:5868e8752d44 121 sz = (mp_uint_t)mp_binary_get_size(fmt_type, *fmt, &align);
pythontech 0:5868e8752d44 122 }
pythontech 0:5868e8752d44 123 // TODO
pythontech 0:5868e8752d44 124 assert(sz != (mp_uint_t)-1);
pythontech 0:5868e8752d44 125 // Apply alignment
pythontech 0:5868e8752d44 126 size = (size + align - 1) & ~(align - 1);
pythontech 0:5868e8752d44 127 size += sz;
pythontech 0:5868e8752d44 128 sz = 0;
pythontech 0:5868e8752d44 129 }
pythontech 0:5868e8752d44 130 }
pythontech 0:5868e8752d44 131 return MP_OBJ_NEW_SMALL_INT(size);
pythontech 0:5868e8752d44 132 }
pythontech 0:5868e8752d44 133 MP_DEFINE_CONST_FUN_OBJ_1(struct_calcsize_obj, struct_calcsize);
pythontech 0:5868e8752d44 134
pythontech 0:5868e8752d44 135 STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) {
pythontech 0:5868e8752d44 136 // unpack requires that the buffer be exactly the right size.
pythontech 0:5868e8752d44 137 // unpack_from requires that the buffer be "big enough".
pythontech 0:5868e8752d44 138 // Since we implement unpack and unpack_from using the same function
pythontech 0:5868e8752d44 139 // we relax the "exact" requirement, and only implement "big enough".
pythontech 0:5868e8752d44 140 const char *fmt = mp_obj_str_get_str(args[0]);
pythontech 0:5868e8752d44 141 char fmt_type = get_fmt_type(&fmt);
pythontech 0:5868e8752d44 142 uint num_items = calcsize_items(fmt);
pythontech 0:5868e8752d44 143 mp_obj_tuple_t *res = MP_OBJ_TO_PTR(mp_obj_new_tuple(num_items, NULL));
pythontech 0:5868e8752d44 144 mp_buffer_info_t bufinfo;
pythontech 0:5868e8752d44 145 mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
pythontech 0:5868e8752d44 146 byte *p = bufinfo.buf;
pythontech 0:5868e8752d44 147 byte *end_p = &p[bufinfo.len];
pythontech 0:5868e8752d44 148 mp_int_t offset = 0;
pythontech 0:5868e8752d44 149
pythontech 0:5868e8752d44 150 if (n_args > 2) {
pythontech 0:5868e8752d44 151 // offset arg provided
pythontech 0:5868e8752d44 152 offset = mp_obj_get_int(args[2]);
pythontech 0:5868e8752d44 153 if (offset < 0) {
pythontech 0:5868e8752d44 154 // negative offsets are relative to the end of the buffer
pythontech 0:5868e8752d44 155 offset = bufinfo.len + offset;
pythontech 0:5868e8752d44 156 if (offset < 0) {
pythontech 0:5868e8752d44 157 nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "buffer too small"));
pythontech 0:5868e8752d44 158 }
pythontech 0:5868e8752d44 159 }
pythontech 0:5868e8752d44 160 p += offset;
pythontech 0:5868e8752d44 161 }
pythontech 0:5868e8752d44 162
pythontech 0:5868e8752d44 163 for (uint i = 0; i < num_items;) {
pythontech 0:5868e8752d44 164 if (*fmt == '\0') {
pythontech 0:5868e8752d44 165 break;
pythontech 0:5868e8752d44 166 }
pythontech 0:5868e8752d44 167 mp_uint_t sz = 1;
pythontech 0:5868e8752d44 168 if (unichar_isdigit(*fmt)) {
pythontech 0:5868e8752d44 169 sz = get_fmt_num(&fmt);
pythontech 0:5868e8752d44 170 }
pythontech 0:5868e8752d44 171 if (p + sz > end_p) {
pythontech 0:5868e8752d44 172 nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "buffer too small"));
pythontech 0:5868e8752d44 173 }
pythontech 0:5868e8752d44 174 mp_obj_t item;
pythontech 0:5868e8752d44 175 if (*fmt == 's') {
pythontech 0:5868e8752d44 176 item = mp_obj_new_bytes(p, sz);
pythontech 0:5868e8752d44 177 p += sz;
pythontech 0:5868e8752d44 178 res->items[i++] = item;
pythontech 0:5868e8752d44 179 } else {
pythontech 0:5868e8752d44 180 while (sz--) {
pythontech 0:5868e8752d44 181 item = mp_binary_get_val(fmt_type, *fmt, &p);
pythontech 0:5868e8752d44 182 res->items[i++] = item;
pythontech 0:5868e8752d44 183 }
pythontech 0:5868e8752d44 184 }
pythontech 0:5868e8752d44 185 fmt++;
pythontech 0:5868e8752d44 186 }
pythontech 0:5868e8752d44 187 return MP_OBJ_FROM_PTR(res);
pythontech 0:5868e8752d44 188 }
pythontech 0:5868e8752d44 189 MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_unpack_from_obj, 2, 3, struct_unpack_from);
pythontech 0:5868e8752d44 190
pythontech 0:5868e8752d44 191 STATIC void struct_pack_into_internal(mp_obj_t fmt_in, byte *p, byte* end_p, size_t n_args, const mp_obj_t *args) {
pythontech 0:5868e8752d44 192 const char *fmt = mp_obj_str_get_str(fmt_in);
pythontech 0:5868e8752d44 193 char fmt_type = get_fmt_type(&fmt);
pythontech 0:5868e8752d44 194
pythontech 0:5868e8752d44 195 size_t i;
pythontech 0:5868e8752d44 196 for (i = 0; i < n_args;) {
pythontech 0:5868e8752d44 197 mp_uint_t sz = 1;
pythontech 0:5868e8752d44 198 if (*fmt == '\0') {
pythontech 0:5868e8752d44 199 break;
pythontech 0:5868e8752d44 200 }
pythontech 0:5868e8752d44 201 if (unichar_isdigit(*fmt)) {
pythontech 0:5868e8752d44 202 sz = get_fmt_num(&fmt);
pythontech 0:5868e8752d44 203 }
pythontech 0:5868e8752d44 204 if (p + sz > end_p) {
pythontech 0:5868e8752d44 205 nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "buffer too small"));
pythontech 0:5868e8752d44 206 }
pythontech 0:5868e8752d44 207
pythontech 0:5868e8752d44 208 if (*fmt == 's') {
pythontech 0:5868e8752d44 209 mp_buffer_info_t bufinfo;
pythontech 0:5868e8752d44 210 mp_get_buffer_raise(args[i++], &bufinfo, MP_BUFFER_READ);
pythontech 0:5868e8752d44 211 mp_uint_t to_copy = sz;
pythontech 0:5868e8752d44 212 if (bufinfo.len < to_copy) {
pythontech 0:5868e8752d44 213 to_copy = bufinfo.len;
pythontech 0:5868e8752d44 214 }
pythontech 0:5868e8752d44 215 memcpy(p, bufinfo.buf, to_copy);
pythontech 0:5868e8752d44 216 memset(p + to_copy, 0, sz - to_copy);
pythontech 0:5868e8752d44 217 p += sz;
pythontech 0:5868e8752d44 218 } else {
pythontech 0:5868e8752d44 219 while (sz--) {
pythontech 0:5868e8752d44 220 mp_binary_set_val(fmt_type, *fmt, args[i++], &p);
pythontech 0:5868e8752d44 221 }
pythontech 0:5868e8752d44 222 }
pythontech 0:5868e8752d44 223 fmt++;
pythontech 0:5868e8752d44 224 }
pythontech 0:5868e8752d44 225 }
pythontech 0:5868e8752d44 226
pythontech 0:5868e8752d44 227 STATIC mp_obj_t struct_pack(size_t n_args, const mp_obj_t *args) {
pythontech 0:5868e8752d44 228 // TODO: "The arguments must match the values required by the format exactly."
pythontech 0:5868e8752d44 229 mp_int_t size = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0]));
pythontech 0:5868e8752d44 230 vstr_t vstr;
pythontech 0:5868e8752d44 231 vstr_init_len(&vstr, size);
pythontech 0:5868e8752d44 232 byte *p = (byte*)vstr.buf;
pythontech 0:5868e8752d44 233 memset(p, 0, size);
pythontech 0:5868e8752d44 234 byte *end_p = &p[size];
pythontech 0:5868e8752d44 235 struct_pack_into_internal(args[0], p, end_p, n_args - 1, &args[1]);
pythontech 0:5868e8752d44 236 return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
pythontech 0:5868e8752d44 237 }
pythontech 0:5868e8752d44 238 MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, MP_OBJ_FUN_ARGS_MAX, struct_pack);
pythontech 0:5868e8752d44 239
pythontech 0:5868e8752d44 240 STATIC mp_obj_t struct_pack_into(size_t n_args, const mp_obj_t *args) {
pythontech 0:5868e8752d44 241 mp_buffer_info_t bufinfo;
pythontech 0:5868e8752d44 242 mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
pythontech 0:5868e8752d44 243 mp_int_t offset = mp_obj_get_int(args[2]);
pythontech 0:5868e8752d44 244 if (offset < 0) {
pythontech 0:5868e8752d44 245 // negative offsets are relative to the end of the buffer
pythontech 0:5868e8752d44 246 offset = (mp_int_t)bufinfo.len + offset;
pythontech 0:5868e8752d44 247 if (offset < 0) {
pythontech 0:5868e8752d44 248 nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "buffer too small"));
pythontech 0:5868e8752d44 249 }
pythontech 0:5868e8752d44 250 }
pythontech 0:5868e8752d44 251 byte *p = (byte *)bufinfo.buf;
pythontech 0:5868e8752d44 252 byte *end_p = &p[bufinfo.len];
pythontech 0:5868e8752d44 253 p += offset;
pythontech 0:5868e8752d44 254
pythontech 0:5868e8752d44 255 struct_pack_into_internal(args[0], p, end_p, n_args - 3, &args[3]);
pythontech 0:5868e8752d44 256 return mp_const_none;
pythontech 0:5868e8752d44 257 }
pythontech 0:5868e8752d44 258 MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_into_obj, 3, MP_OBJ_FUN_ARGS_MAX, struct_pack_into);
pythontech 0:5868e8752d44 259
pythontech 0:5868e8752d44 260 STATIC const mp_rom_map_elem_t mp_module_struct_globals_table[] = {
pythontech 0:5868e8752d44 261 { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ustruct) },
pythontech 0:5868e8752d44 262 { MP_ROM_QSTR(MP_QSTR_calcsize), MP_ROM_PTR(&struct_calcsize_obj) },
pythontech 0:5868e8752d44 263 { MP_ROM_QSTR(MP_QSTR_pack), MP_ROM_PTR(&struct_pack_obj) },
pythontech 0:5868e8752d44 264 { MP_ROM_QSTR(MP_QSTR_pack_into), MP_ROM_PTR(&struct_pack_into_obj) },
pythontech 0:5868e8752d44 265 { MP_ROM_QSTR(MP_QSTR_unpack), MP_ROM_PTR(&struct_unpack_from_obj) },
pythontech 0:5868e8752d44 266 { MP_ROM_QSTR(MP_QSTR_unpack_from), MP_ROM_PTR(&struct_unpack_from_obj) },
pythontech 0:5868e8752d44 267 };
pythontech 0:5868e8752d44 268
pythontech 0:5868e8752d44 269 STATIC MP_DEFINE_CONST_DICT(mp_module_struct_globals, mp_module_struct_globals_table);
pythontech 0:5868e8752d44 270
pythontech 0:5868e8752d44 271 const mp_obj_module_t mp_module_ustruct = {
pythontech 0:5868e8752d44 272 .base = { &mp_type_module },
pythontech 0:5868e8752d44 273 .name = MP_QSTR_ustruct,
pythontech 0:5868e8752d44 274 .globals = (mp_obj_dict_t*)&mp_module_struct_globals,
pythontech 0:5868e8752d44 275 };
pythontech 0:5868e8752d44 276
pythontech 0:5868e8752d44 277 #endif