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 <string.h>
pythontech 0:5868e8752d44 29
pythontech 0:5868e8752d44 30 #include "py/nlr.h"
pythontech 0:5868e8752d44 31 #include "py/obj.h"
pythontech 0:5868e8752d44 32 #include "py/runtime0.h"
pythontech 0:5868e8752d44 33 #include "py/runtime.h"
pythontech 0:5868e8752d44 34
pythontech 0:5868e8752d44 35 // Helpers for sequence types
pythontech 0:5868e8752d44 36
pythontech 0:5868e8752d44 37 #define SWAP(type, var1, var2) { type t = var2; var2 = var1; var1 = t; }
pythontech 0:5868e8752d44 38
pythontech 0:5868e8752d44 39 // Implements backend of sequence * integer operation. Assumes elements are
pythontech 0:5868e8752d44 40 // memory-adjacent in sequence.
pythontech 0:5868e8752d44 41 void mp_seq_multiply(const void *items, mp_uint_t item_sz, mp_uint_t len, mp_uint_t times, void *dest) {
pythontech 0:5868e8752d44 42 for (mp_uint_t i = 0; i < times; i++) {
pythontech 0:5868e8752d44 43 uint copy_sz = item_sz * len;
pythontech 0:5868e8752d44 44 memcpy(dest, items, copy_sz);
pythontech 0:5868e8752d44 45 dest = (char*)dest + copy_sz;
pythontech 0:5868e8752d44 46 }
pythontech 0:5868e8752d44 47 }
pythontech 0:5868e8752d44 48
pythontech 0:5868e8752d44 49 #if MICROPY_PY_BUILTINS_SLICE
pythontech 0:5868e8752d44 50
pythontech 0:5868e8752d44 51 bool mp_seq_get_fast_slice_indexes(mp_uint_t len, mp_obj_t slice, mp_bound_slice_t *indexes) {
pythontech 0:5868e8752d44 52 mp_obj_t ostart, ostop, ostep;
pythontech 0:5868e8752d44 53 mp_int_t start, stop;
pythontech 0:5868e8752d44 54 mp_obj_slice_get(slice, &ostart, &ostop, &ostep);
pythontech 0:5868e8752d44 55
pythontech 0:5868e8752d44 56 if (ostart == mp_const_none) {
pythontech 0:5868e8752d44 57 start = 0;
pythontech 0:5868e8752d44 58 } else {
pythontech 0:5868e8752d44 59 start = MP_OBJ_SMALL_INT_VALUE(ostart);
pythontech 0:5868e8752d44 60 }
pythontech 0:5868e8752d44 61 if (ostop == mp_const_none) {
pythontech 0:5868e8752d44 62 stop = len;
pythontech 0:5868e8752d44 63 } else {
pythontech 0:5868e8752d44 64 stop = MP_OBJ_SMALL_INT_VALUE(ostop);
pythontech 0:5868e8752d44 65 }
pythontech 0:5868e8752d44 66
pythontech 0:5868e8752d44 67 // Unlike subscription, out-of-bounds slice indexes are never error
pythontech 0:5868e8752d44 68 if (start < 0) {
pythontech 0:5868e8752d44 69 start = len + start;
pythontech 0:5868e8752d44 70 if (start < 0) {
pythontech 0:5868e8752d44 71 start = 0;
pythontech 0:5868e8752d44 72 }
pythontech 0:5868e8752d44 73 } else if ((mp_uint_t)start > len) {
pythontech 0:5868e8752d44 74 start = len;
pythontech 0:5868e8752d44 75 }
pythontech 0:5868e8752d44 76 if (stop < 0) {
pythontech 0:5868e8752d44 77 stop = len + stop;
pythontech 0:5868e8752d44 78 } else if ((mp_uint_t)stop > len) {
pythontech 0:5868e8752d44 79 stop = len;
pythontech 0:5868e8752d44 80 }
pythontech 0:5868e8752d44 81
pythontech 0:5868e8752d44 82 // CPython returns empty sequence in such case, or point for assignment is at start
pythontech 0:5868e8752d44 83 if (start > stop) {
pythontech 0:5868e8752d44 84 stop = start;
pythontech 0:5868e8752d44 85 }
pythontech 0:5868e8752d44 86
pythontech 0:5868e8752d44 87 indexes->start = start;
pythontech 0:5868e8752d44 88 indexes->stop = stop;
pythontech 0:5868e8752d44 89
pythontech 0:5868e8752d44 90 if (ostep != mp_const_none && ostep != MP_OBJ_NEW_SMALL_INT(1)) {
pythontech 0:5868e8752d44 91 indexes->step = MP_OBJ_SMALL_INT_VALUE(ostep);
pythontech 0:5868e8752d44 92 return false;
pythontech 0:5868e8752d44 93 }
pythontech 0:5868e8752d44 94 indexes->step = 1;
pythontech 0:5868e8752d44 95 return true;
pythontech 0:5868e8752d44 96 }
pythontech 0:5868e8752d44 97
pythontech 0:5868e8752d44 98 #endif
pythontech 0:5868e8752d44 99
pythontech 0:5868e8752d44 100 mp_obj_t mp_seq_extract_slice(mp_uint_t len, const mp_obj_t *seq, mp_bound_slice_t *indexes) {
pythontech 0:5868e8752d44 101 (void)len; // TODO can we remove len from the arg list?
pythontech 0:5868e8752d44 102
pythontech 0:5868e8752d44 103 mp_int_t start = indexes->start, stop = indexes->stop;
pythontech 0:5868e8752d44 104 mp_int_t step = indexes->step;
pythontech 0:5868e8752d44 105
pythontech 0:5868e8752d44 106 mp_obj_t res = mp_obj_new_list(0, NULL);
pythontech 0:5868e8752d44 107
pythontech 0:5868e8752d44 108 if (step < 0) {
pythontech 0:5868e8752d44 109 stop--;
pythontech 0:5868e8752d44 110 while (start <= stop) {
pythontech 0:5868e8752d44 111 mp_obj_list_append(res, seq[stop]);
pythontech 0:5868e8752d44 112 stop += step;
pythontech 0:5868e8752d44 113 }
pythontech 0:5868e8752d44 114 } else {
pythontech 0:5868e8752d44 115 while (start < stop) {
pythontech 0:5868e8752d44 116 mp_obj_list_append(res, seq[start]);
pythontech 0:5868e8752d44 117 start += step;
pythontech 0:5868e8752d44 118 }
pythontech 0:5868e8752d44 119 }
pythontech 0:5868e8752d44 120 return res;
pythontech 0:5868e8752d44 121 }
pythontech 0:5868e8752d44 122
pythontech 0:5868e8752d44 123 // Special-case comparison function for sequences of bytes
pythontech 0:5868e8752d44 124 // Don't pass MP_BINARY_OP_NOT_EQUAL here
pythontech 0:5868e8752d44 125 bool mp_seq_cmp_bytes(mp_uint_t op, const byte *data1, mp_uint_t len1, const byte *data2, mp_uint_t len2) {
pythontech 0:5868e8752d44 126 if (op == MP_BINARY_OP_EQUAL && len1 != len2) {
pythontech 0:5868e8752d44 127 return false;
pythontech 0:5868e8752d44 128 }
pythontech 0:5868e8752d44 129
pythontech 0:5868e8752d44 130 // Let's deal only with > & >=
pythontech 0:5868e8752d44 131 if (op == MP_BINARY_OP_LESS || op == MP_BINARY_OP_LESS_EQUAL) {
pythontech 0:5868e8752d44 132 SWAP(const byte*, data1, data2);
pythontech 0:5868e8752d44 133 SWAP(uint, len1, len2);
pythontech 0:5868e8752d44 134 if (op == MP_BINARY_OP_LESS) {
pythontech 0:5868e8752d44 135 op = MP_BINARY_OP_MORE;
pythontech 0:5868e8752d44 136 } else {
pythontech 0:5868e8752d44 137 op = MP_BINARY_OP_MORE_EQUAL;
pythontech 0:5868e8752d44 138 }
pythontech 0:5868e8752d44 139 }
pythontech 0:5868e8752d44 140 uint min_len = len1 < len2 ? len1 : len2;
pythontech 0:5868e8752d44 141 int res = memcmp(data1, data2, min_len);
pythontech 0:5868e8752d44 142 if (op == MP_BINARY_OP_EQUAL) {
pythontech 0:5868e8752d44 143 // If we are checking for equality, here're the answer
pythontech 0:5868e8752d44 144 return res == 0;
pythontech 0:5868e8752d44 145 }
pythontech 0:5868e8752d44 146 if (res < 0) {
pythontech 0:5868e8752d44 147 return false;
pythontech 0:5868e8752d44 148 }
pythontech 0:5868e8752d44 149 if (res > 0) {
pythontech 0:5868e8752d44 150 return true;
pythontech 0:5868e8752d44 151 }
pythontech 0:5868e8752d44 152
pythontech 0:5868e8752d44 153 // If we had tie in the last element...
pythontech 0:5868e8752d44 154 // ... and we have lists of different lengths...
pythontech 0:5868e8752d44 155 if (len1 != len2) {
pythontech 0:5868e8752d44 156 if (len1 < len2) {
pythontech 0:5868e8752d44 157 // ... then longer list length wins (we deal only with >)
pythontech 0:5868e8752d44 158 return false;
pythontech 0:5868e8752d44 159 }
pythontech 0:5868e8752d44 160 } else if (op == MP_BINARY_OP_MORE) {
pythontech 0:5868e8752d44 161 // Otherwise, if we have strict relation, equality means failure
pythontech 0:5868e8752d44 162 return false;
pythontech 0:5868e8752d44 163 }
pythontech 0:5868e8752d44 164 return true;
pythontech 0:5868e8752d44 165 }
pythontech 0:5868e8752d44 166
pythontech 0:5868e8752d44 167 // Special-case comparison function for sequences of mp_obj_t
pythontech 0:5868e8752d44 168 // Don't pass MP_BINARY_OP_NOT_EQUAL here
pythontech 0:5868e8752d44 169 bool mp_seq_cmp_objs(mp_uint_t op, const mp_obj_t *items1, mp_uint_t len1, const mp_obj_t *items2, mp_uint_t len2) {
pythontech 0:5868e8752d44 170 if (op == MP_BINARY_OP_EQUAL && len1 != len2) {
pythontech 0:5868e8752d44 171 return false;
pythontech 0:5868e8752d44 172 }
pythontech 0:5868e8752d44 173
pythontech 0:5868e8752d44 174 // Let's deal only with > & >=
pythontech 0:5868e8752d44 175 if (op == MP_BINARY_OP_LESS || op == MP_BINARY_OP_LESS_EQUAL) {
pythontech 0:5868e8752d44 176 SWAP(const mp_obj_t *, items1, items2);
pythontech 0:5868e8752d44 177 SWAP(uint, len1, len2);
pythontech 0:5868e8752d44 178 if (op == MP_BINARY_OP_LESS) {
pythontech 0:5868e8752d44 179 op = MP_BINARY_OP_MORE;
pythontech 0:5868e8752d44 180 } else {
pythontech 0:5868e8752d44 181 op = MP_BINARY_OP_MORE_EQUAL;
pythontech 0:5868e8752d44 182 }
pythontech 0:5868e8752d44 183 }
pythontech 0:5868e8752d44 184
pythontech 0:5868e8752d44 185 mp_uint_t len = len1 < len2 ? len1 : len2;
pythontech 0:5868e8752d44 186 for (mp_uint_t i = 0; i < len; i++) {
pythontech 0:5868e8752d44 187 // If current elements equal, can't decide anything - go on
pythontech 0:5868e8752d44 188 if (mp_obj_equal(items1[i], items2[i])) {
pythontech 0:5868e8752d44 189 continue;
pythontech 0:5868e8752d44 190 }
pythontech 0:5868e8752d44 191
pythontech 0:5868e8752d44 192 // Othewise, if they are not equal, we can have final decision based on them
pythontech 0:5868e8752d44 193 if (op == MP_BINARY_OP_EQUAL) {
pythontech 0:5868e8752d44 194 // In particular, if we are checking for equality, here're the answer
pythontech 0:5868e8752d44 195 return false;
pythontech 0:5868e8752d44 196 }
pythontech 0:5868e8752d44 197
pythontech 0:5868e8752d44 198 // Otherwise, application of relation op gives the answer
pythontech 0:5868e8752d44 199 return (mp_binary_op(op, items1[i], items2[i]) == mp_const_true);
pythontech 0:5868e8752d44 200 }
pythontech 0:5868e8752d44 201
pythontech 0:5868e8752d44 202 // If we had tie in the last element...
pythontech 0:5868e8752d44 203 // ... and we have lists of different lengths...
pythontech 0:5868e8752d44 204 if (len1 != len2) {
pythontech 0:5868e8752d44 205 if (len1 < len2) {
pythontech 0:5868e8752d44 206 // ... then longer list length wins (we deal only with >)
pythontech 0:5868e8752d44 207 return false;
pythontech 0:5868e8752d44 208 }
pythontech 0:5868e8752d44 209 } else if (op == MP_BINARY_OP_MORE) {
pythontech 0:5868e8752d44 210 // Otherwise, if we have strict relation, sequence equality means failure
pythontech 0:5868e8752d44 211 return false;
pythontech 0:5868e8752d44 212 }
pythontech 0:5868e8752d44 213
pythontech 0:5868e8752d44 214 return true;
pythontech 0:5868e8752d44 215 }
pythontech 0:5868e8752d44 216
pythontech 0:5868e8752d44 217 // Special-case of index() which searches for mp_obj_t
pythontech 0:5868e8752d44 218 mp_obj_t mp_seq_index_obj(const mp_obj_t *items, mp_uint_t len, mp_uint_t n_args, const mp_obj_t *args) {
pythontech 0:5868e8752d44 219 mp_obj_type_t *type = mp_obj_get_type(args[0]);
pythontech 0:5868e8752d44 220 mp_obj_t value = args[1];
pythontech 0:5868e8752d44 221 uint start = 0;
pythontech 0:5868e8752d44 222 uint stop = len;
pythontech 0:5868e8752d44 223
pythontech 0:5868e8752d44 224 if (n_args >= 3) {
pythontech 0:5868e8752d44 225 start = mp_get_index(type, len, args[2], true);
pythontech 0:5868e8752d44 226 if (n_args >= 4) {
pythontech 0:5868e8752d44 227 stop = mp_get_index(type, len, args[3], true);
pythontech 0:5868e8752d44 228 }
pythontech 0:5868e8752d44 229 }
pythontech 0:5868e8752d44 230
pythontech 0:5868e8752d44 231 for (mp_uint_t i = start; i < stop; i++) {
pythontech 0:5868e8752d44 232 if (mp_obj_equal(items[i], value)) {
pythontech 0:5868e8752d44 233 // Common sense says this cannot overflow small int
pythontech 0:5868e8752d44 234 return MP_OBJ_NEW_SMALL_INT(i);
pythontech 0:5868e8752d44 235 }
pythontech 0:5868e8752d44 236 }
pythontech 0:5868e8752d44 237
pythontech 0:5868e8752d44 238 nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "object not in sequence"));
pythontech 0:5868e8752d44 239 }
pythontech 0:5868e8752d44 240
pythontech 0:5868e8752d44 241 mp_obj_t mp_seq_count_obj(const mp_obj_t *items, mp_uint_t len, mp_obj_t value) {
pythontech 0:5868e8752d44 242 mp_uint_t count = 0;
pythontech 0:5868e8752d44 243 for (uint i = 0; i < len; i++) {
pythontech 0:5868e8752d44 244 if (mp_obj_equal(items[i], value)) {
pythontech 0:5868e8752d44 245 count++;
pythontech 0:5868e8752d44 246 }
pythontech 0:5868e8752d44 247 }
pythontech 0:5868e8752d44 248
pythontech 0:5868e8752d44 249 // Common sense says this cannot overflow small int
pythontech 0:5868e8752d44 250 return MP_OBJ_NEW_SMALL_INT(count);
pythontech 0:5868e8752d44 251 }