From 39968aaaff575800218b47488f85eed7081cd0cb Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Tue, 11 Oct 2016 07:10:48 +0300 Subject: extmod/uzlib: Update to upstream v2.1. Adds check that LZ offsets fall into the sliding dictionary used. This catches a case when uzlib.DecompIO with a smaller dictionary is used to decompress data which was compressed with a larger dictionary. Previously, this would lead to producing invalid data or crash, now an exception will be thrown. --- extmod/uzlib/tinf.h | 1 + extmod/uzlib/tinflate.c | 3 +++ 2 files changed, 4 insertions(+) (limited to 'extmod') diff --git a/extmod/uzlib/tinf.h b/extmod/uzlib/tinf.h index 3545bbd88..106203a09 100644 --- a/extmod/uzlib/tinf.h +++ b/extmod/uzlib/tinf.h @@ -32,6 +32,7 @@ extern "C" { #define TINF_DONE 1 #define TINF_DATA_ERROR (-3) #define TINF_CHKSUM_ERROR (-4) +#define TINF_DICT_ERROR (-5) /* checksum types */ #define TINF_CHKSUM_NONE 0 diff --git a/extmod/uzlib/tinflate.c b/extmod/uzlib/tinflate.c index 0e53f7f07..58850eb4a 100644 --- a/extmod/uzlib/tinflate.c +++ b/extmod/uzlib/tinflate.c @@ -361,6 +361,9 @@ static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt) /* possibly get more bits from distance code */ offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]); if (d->dict_ring) { + if (offs > d->dict_size) { + return TINF_DICT_ERROR; + } d->lzOff = d->dict_idx - offs; if (d->lzOff < 0) { d->lzOff += d->dict_size; -- cgit v1.2.3 From eaef6b5324fa2ff425802d4abeea45aa945bfc14 Mon Sep 17 00:00:00 2001 From: Radomir Dopieralski Date: Sat, 8 Oct 2016 17:34:46 +0200 Subject: extmod/machine_i2c: Use writes not reads in i2c.scan(). As per discussion in #2449, using write requests instead of read requests for I2C.scan() seems to support a larger number of devices, especially ones that are write-only. Even a read-only I2C device has to implement writes in order to be able to receive the address of the register to read. --- extmod/machine_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'extmod') diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c index d76e5eedd..e201b2399 100644 --- a/extmod/machine_i2c.c +++ b/extmod/machine_i2c.c @@ -272,7 +272,7 @@ STATIC mp_obj_t machine_i2c_scan(mp_obj_t self_in) { // 7-bit addresses 0b0000xxx and 0b1111xxx are reserved for (int addr = 0x08; addr < 0x78; ++addr) { mp_hal_i2c_start(self); - int ack = mp_hal_i2c_write_byte(self, (addr << 1) | 1); + int ack = mp_hal_i2c_write_byte(self, (addr << 1)); if (ack) { mp_obj_list_append(list, MP_OBJ_NEW_SMALL_INT(addr)); } -- cgit v1.2.3 From d02f3a57f47b44bf31769fb089f1f18060ea3b4d Mon Sep 17 00:00:00 2001 From: Alex March Date: Wed, 28 Sep 2016 14:51:35 +0100 Subject: extmod/vfs_fat: Add file and directory checks for remove and rmdir. --- extmod/vfs_fat.c | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) (limited to 'extmod') diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index 3a17533e4..6e827fc66 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -31,6 +31,7 @@ #include #include "py/nlr.h" #include "py/runtime.h" +#include "py/mperrno.h" #include "lib/fatfs/ff.h" #include "lib/fatfs/diskio.h" #include "extmod/vfs_fat_file.h" @@ -76,24 +77,42 @@ STATIC mp_obj_t fat_vfs_listdir_func(size_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fat_vfs_listdir_obj, 1, 2, fat_vfs_listdir_func); -STATIC mp_obj_t fat_vfs_remove(mp_obj_t vfs_in, mp_obj_t path_in) { - (void)vfs_in; +STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t path_in, mp_int_t attr) { const char *path = mp_obj_str_get_str(path_in); - // TODO check that path is actually a file before trying to unlink it - FRESULT res = f_unlink(path); - if (res == FR_OK) { + + FILINFO fno; +#if _USE_LFN + fno.lfname = NULL; + fno.lfsize = 0; +#endif + FRESULT res = f_stat(path, &fno); + + if (res != FR_OK) { + mp_raise_OSError(fresult_to_errno_table[res]); + } + + // check if path is a file or directory + if ((fno.fattrib & AM_DIR) == attr) { + res = f_unlink(path); + + if (res != FR_OK) { + mp_raise_OSError(fresult_to_errno_table[res]); + } return mp_const_none; } else { - mp_raise_OSError(fresult_to_errno_table[res]); + mp_raise_OSError(attr ? MP_ENOTDIR : MP_EISDIR); } } + +STATIC mp_obj_t fat_vfs_remove(mp_obj_t vfs_in, mp_obj_t path_in) { + (void)vfs_in; + return fat_vfs_remove_internal(path_in, 0); // 0 == file attribute +} STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_remove_obj, fat_vfs_remove); STATIC mp_obj_t fat_vfs_rmdir(mp_obj_t vfs_in, mp_obj_t path_in) { - // TODO: Currently just redirects to fat_vfs_remove(), which are - // backed by the same underlying FatFs function. Should at least - // check that path is actually a dir. - return fat_vfs_remove(vfs_in, path_in); + (void) vfs_in; + return fat_vfs_remove_internal(path_in, AM_DIR); } STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_rmdir_obj, fat_vfs_rmdir); -- cgit v1.2.3 From e93c1ca5da58df336305c9a5e50214849342f298 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 13 Oct 2016 11:43:28 +1100 Subject: extmod/modujson: Implement ujson.load() to load JSON from a stream. This refactors ujson.loads(s) to behave as ujson.load(StringIO(s)). Increase in code size is: 366 bytes for unix x86-64, 180 bytes for stmhal, 84 bytes for esp8266. --- extmod/modujson.c | 107 +++++++++++++++++++++++++++++++++++------------------- py/objstringio.c | 8 +--- py/objstringio.h | 38 +++++++++++++++++++ 3 files changed, 109 insertions(+), 44 deletions(-) create mode 100644 py/objstringio.h (limited to 'extmod') diff --git a/extmod/modujson.c b/extmod/modujson.c index 0d0781e06..193292b9e 100644 --- a/extmod/modujson.c +++ b/extmod/modujson.c @@ -1,9 +1,9 @@ /* - * This file is part of the Micro Python project, http://micropython.org/ + * This file is part of the MicroPython project, http://micropython.org/ * * The MIT License (MIT) * - * Copyright (c) 2014 Damien P. George + * Copyright (c) 2014-2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,8 +28,10 @@ #include "py/nlr.h" #include "py/objlist.h" +#include "py/objstringio.h" #include "py/parsenum.h" #include "py/runtime.h" +#include "py/stream.h" #if MICROPY_PY_UJSON @@ -42,7 +44,7 @@ STATIC mp_obj_t mod_ujson_dumps(mp_obj_t obj) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps); -// This function implements a simple non-recursive JSON parser. +// The function below implements a simple non-recursive JSON parser. // // The JSON specification is at http://www.ietf.org/rfc/rfc4627.txt // The parser here will parse any valid JSON and return the correct @@ -52,13 +54,35 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps); // input is outside it's specs. // // Most of the work is parsing the primitives (null, false, true, numbers, -// strings). It does 1 pass over the input string and so is easily extended to -// being able to parse from a non-seekable stream. It tries to be fast and +// strings). It does 1 pass over the input stream. It tries to be fast and // small in code size, while not using more RAM than necessary. -STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { - mp_uint_t len; - const char *s = mp_obj_str_get_data(obj, &len); - const char *top = s + len; + +typedef struct _ujson_stream_t { + mp_obj_t stream_obj; + mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode); + int errcode; + byte cur; +} ujson_stream_t; + +#define S_EOF (0) // null is not allowed in json stream so is ok as EOF marker +#define S_END(s) ((s).cur == S_EOF) +#define S_CUR(s) ((s).cur) +#define S_NEXT(s) (ujson_stream_next(&(s))) + +STATIC byte ujson_stream_next(ujson_stream_t *s) { + mp_uint_t ret = s->read(s->stream_obj, &s->cur, 1, &s->errcode); + if (s->errcode != 0) { + mp_raise_OSError(s->errcode); + } + if (ret == 0) { + s->cur = S_EOF; + } + return s->cur; +} + +STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) { + const mp_stream_p_t *stream_p = mp_get_stream_raise(stream_obj, MP_STREAM_OP_READ); + ujson_stream_t s = {stream_obj, stream_p->read, 0, 0}; vstr_t vstr; vstr_init(&vstr, 8); mp_obj_list_t stack; // we use a list as a simple stack for nested JSON @@ -67,41 +91,43 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { mp_obj_t stack_top = MP_OBJ_NULL; mp_obj_type_t *stack_top_type = NULL; mp_obj_t stack_key = MP_OBJ_NULL; + S_NEXT(s); for (;;) { cont: - if (s == top) { + if (S_END(s)) { break; } mp_obj_t next = MP_OBJ_NULL; bool enter = false; - switch (*s) { + byte cur = S_CUR(s); + S_NEXT(s); + switch (cur) { case ',': case ':': case ' ': case '\t': case '\n': case '\r': - s += 1; goto cont; case 'n': - if (s + 3 < top && s[1] == 'u' && s[2] == 'l' && s[3] == 'l') { - s += 4; + if (S_CUR(s) == 'u' && S_NEXT(s) == 'l' && S_NEXT(s) == 'l') { + S_NEXT(s); next = mp_const_none; } else { goto fail; } break; case 'f': - if (s + 4 < top && s[1] == 'a' && s[2] == 'l' && s[3] == 's' && s[4] == 'e') { - s += 5; + if (S_CUR(s) == 'a' && S_NEXT(s) == 'l' && S_NEXT(s) == 's' && S_NEXT(s) == 'e') { + S_NEXT(s); next = mp_const_false; } else { goto fail; } break; case 't': - if (s + 3 < top && s[1] == 'r' && s[2] == 'u' && s[3] == 'e') { - s += 4; + if (S_CUR(s) == 'r' && S_NEXT(s) == 'u' && S_NEXT(s) == 'e') { + S_NEXT(s); next = mp_const_true; } else { goto fail; @@ -109,11 +135,10 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { break; case '"': vstr_reset(&vstr); - for (s++; s < top && *s != '"';) { - byte c = *s; + for (; !S_END(s) && S_CUR(s) != '"';) { + byte c = S_CUR(s); if (c == '\\') { - s++; - c = *s; + c = S_NEXT(s); switch (c) { case 'b': c = 0x08; break; case 'f': c = 0x0c; break; @@ -121,10 +146,9 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { case 'r': c = 0x0d; break; case 't': c = 0x09; break; case 'u': { - if (s + 4 >= top) { goto fail; } mp_uint_t num = 0; for (int i = 0; i < 4; i++) { - c = (*++s | 0x20) - '0'; + c = (S_NEXT(s) | 0x20) - '0'; if (c > 9) { c -= ('a' - ('9' + 1)); } @@ -137,27 +161,29 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { } vstr_add_byte(&vstr, c); str_cont: - s++; + S_NEXT(s); } - if (s == top) { + if (S_END(s)) { goto fail; } - s++; + S_NEXT(s); next = mp_obj_new_str(vstr.buf, vstr.len, false); break; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { bool flt = false; vstr_reset(&vstr); - for (; s < top; s++) { - if (*s == '.' || *s == 'E' || *s == 'e') { + for (;;) { + vstr_add_byte(&vstr, cur); + cur = S_CUR(s); + if (cur == '.' || cur == 'E' || cur == 'e') { flt = true; - } else if (*s == '-' || unichar_isdigit(*s)) { + } else if (cur == '-' || unichar_isdigit(cur)) { // pass } else { break; } - vstr_add_byte(&vstr, *s); + S_NEXT(s); } if (flt) { next = mp_parse_num_decimal(vstr.buf, vstr.len, false, false, NULL); @@ -169,16 +195,13 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { case '[': next = mp_obj_new_list(0, NULL); enter = true; - s += 1; break; case '{': next = mp_obj_new_dict(0); enter = true; - s += 1; break; case '}': case ']': { - s += 1; if (stack_top == MP_OBJ_NULL) { // no object at all goto fail; @@ -231,10 +254,10 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { } success: // eat trailing whitespace - while (s < top && unichar_isspace(*s)) { - s++; + while (unichar_isspace(S_CUR(s))) { + S_NEXT(s); } - if (s < top) { + if (!S_END(s)) { // unexpected chars goto fail; } @@ -248,11 +271,21 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { fail: nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "syntax error in JSON")); } +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_load_obj, mod_ujson_load); + +STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { + mp_uint_t len; + const char *buf = mp_obj_str_get_data(obj, &len); + vstr_t vstr = {len, len, (char*)buf, true}; + mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0}; + return mod_ujson_load(&sio); +} STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_loads_obj, mod_ujson_loads); STATIC const mp_rom_map_elem_t mp_module_ujson_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ujson) }, { MP_ROM_QSTR(MP_QSTR_dumps), MP_ROM_PTR(&mod_ujson_dumps_obj) }, + { MP_ROM_QSTR(MP_QSTR_load), MP_ROM_PTR(&mod_ujson_load_obj) }, { MP_ROM_QSTR(MP_QSTR_loads), MP_ROM_PTR(&mod_ujson_loads_obj) }, }; diff --git a/py/objstringio.c b/py/objstringio.c index eb0cc4eb3..be1a7d89c 100644 --- a/py/objstringio.c +++ b/py/objstringio.c @@ -30,18 +30,12 @@ #include "py/nlr.h" #include "py/objstr.h" +#include "py/objstringio.h" #include "py/runtime.h" #include "py/stream.h" #if MICROPY_PY_IO -typedef struct _mp_obj_stringio_t { - mp_obj_base_t base; - vstr_t *vstr; - // StringIO has single pointer used for both reading and writing - mp_uint_t pos; -} mp_obj_stringio_t; - #if MICROPY_CPYTHON_COMPAT STATIC void check_stringio_is_open(const mp_obj_stringio_t *o) { if (o->vstr == NULL) { diff --git a/py/objstringio.h b/py/objstringio.h new file mode 100644 index 000000000..853bfb11b --- /dev/null +++ b/py/objstringio.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MICROPY_INCLUDED_PY_OBJSTRINGIO_H +#define MICROPY_INCLUDED_PY_OBJSTRINGIO_H + +#include "py/obj.h" + +typedef struct _mp_obj_stringio_t { + mp_obj_base_t base; + vstr_t *vstr; + // StringIO has single pointer used for both reading and writing + mp_uint_t pos; +} mp_obj_stringio_t; + +#endif // MICROPY_INCLUDED_PY_OBJSTRINGIO_H -- cgit v1.2.3 From f2f8ae110bfa1a17a34b81a9ac9de1378d2b3c50 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 13 Oct 2016 12:09:18 +1100 Subject: extmod/modujson: Fix nanbox build. --- extmod/modujson.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'extmod') diff --git a/extmod/modujson.c b/extmod/modujson.c index 193292b9e..ca4e6df10 100644 --- a/extmod/modujson.c +++ b/extmod/modujson.c @@ -278,7 +278,7 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { const char *buf = mp_obj_str_get_data(obj, &len); vstr_t vstr = {len, len, (char*)buf, true}; mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0}; - return mod_ujson_load(&sio); + return mod_ujson_load(MP_OBJ_FROM_PTR(&sio)); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_loads_obj, mod_ujson_loads); -- cgit v1.2.3 From a97284423eba9470c16c5f02fadea14bd8263751 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 14 Oct 2016 20:13:02 +0300 Subject: extmod/utime_mphal: Factor out implementations in terms of mp_hal_* for reuse. As long as a port implement mp_hal_sleep_ms(), mp_hal_ticks_ms(), etc. functions, it can just use standard implementations of utime.sleel_ms(), utime.ticks_ms(), etc. Python-level functions. --- esp8266/modutime.c | 62 +++++-------------------------------- esp8266/mpconfigport.h | 1 + extmod/utime_mphal.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ extmod/utime_mphal.h | 36 ++++++++++++++++++++++ py/mpconfig.h | 6 ++++ py/mphal.h | 4 +++ py/py.mk | 1 + 7 files changed, 139 insertions(+), 54 deletions(-) create mode 100644 extmod/utime_mphal.c create mode 100644 extmod/utime_mphal.h (limited to 'extmod') diff --git a/esp8266/modutime.c b/esp8266/modutime.c index 4b94ace74..abfe069cc 100644 --- a/esp8266/modutime.c +++ b/esp8266/modutime.c @@ -38,6 +38,7 @@ #include "modpybrtc.h" #include "timeutils.h" #include "user_interface.h" +#include "extmod/utime_mphal.h" /// \module time - time related functions /// @@ -99,53 +100,6 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) { } MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime); -/// \function sleep(seconds) -/// Sleep for the given number of seconds. -STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) { - #if MICROPY_PY_BUILTINS_FLOAT - mp_hal_delay_ms(1000 * mp_obj_get_float(seconds_o)); - #else - mp_hal_delay_ms(1000 * mp_obj_get_int(seconds_o)); - #endif - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep); - -STATIC mp_obj_t time_sleep_ms(mp_obj_t arg) { - mp_hal_delay_ms(mp_obj_get_int(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_ms_obj, time_sleep_ms); - -STATIC mp_obj_t time_sleep_us(mp_obj_t arg) { - mp_hal_delay_us(mp_obj_get_int(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_us_obj, time_sleep_us); - -STATIC mp_obj_t time_ticks_ms(void) { - return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & MP_SMALL_INT_POSITIVE_MASK); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_ms_obj, time_ticks_ms); - -STATIC mp_obj_t time_ticks_us(void) { - return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_us() & MP_SMALL_INT_POSITIVE_MASK); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_us_obj, time_ticks_us); - -STATIC mp_obj_t time_ticks_cpu(void) { - return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_cpu() & MP_SMALL_INT_POSITIVE_MASK); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_cpu_obj, time_ticks_cpu); - -STATIC mp_obj_t time_ticks_diff(mp_obj_t start_in, mp_obj_t end_in) { - // we assume that the arguments come from ticks_xx so are small ints - uint32_t start = MP_OBJ_SMALL_INT_VALUE(start_in); - uint32_t end = MP_OBJ_SMALL_INT_VALUE(end_in); - return MP_OBJ_NEW_SMALL_INT((end - start) & MP_SMALL_INT_POSITIVE_MASK); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(time_ticks_diff_obj, time_ticks_diff); - /// \function time() /// Returns the number of seconds, as an integer, since 1/1/2000. STATIC mp_obj_t time_time(void) { @@ -159,13 +113,13 @@ STATIC const mp_map_elem_t time_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_localtime), (mp_obj_t)&time_localtime_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_mktime), (mp_obj_t)&time_mktime_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&time_sleep_ms_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&time_sleep_us_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&time_ticks_ms_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&time_ticks_us_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_cpu), (mp_obj_t)&time_ticks_cpu_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&time_ticks_diff_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&mp_utime_sleep_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&mp_utime_sleep_ms_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&mp_utime_sleep_us_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&mp_utime_ticks_ms_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&mp_utime_ticks_us_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_cpu), (mp_obj_t)&mp_utime_ticks_cpu_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&mp_utime_ticks_diff_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_time_obj }, }; diff --git a/esp8266/mpconfigport.h b/esp8266/mpconfigport.h index 6d0deba8d..201057f12 100644 --- a/esp8266/mpconfigport.h +++ b/esp8266/mpconfigport.h @@ -62,6 +62,7 @@ #define MICROPY_PY_UJSON (1) #define MICROPY_PY_URANDOM (1) #define MICROPY_PY_URE (1) +#define MICROPY_PY_UTIME_MP_HAL (1) #define MICROPY_PY_UZLIB (1) #define MICROPY_PY_LWIP (1) #define MICROPY_PY_MACHINE (1) diff --git a/extmod/utime_mphal.c b/extmod/utime_mphal.c new file mode 100644 index 000000000..9471ad525 --- /dev/null +++ b/extmod/utime_mphal.c @@ -0,0 +1,83 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2016 Damien P. George + * Copyright (c) 2016 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/mpconfig.h" +#if MICROPY_PY_UTIME_MP_HAL + +#include + +#include "py/obj.h" +#include "py/mphal.h" +#include "py/smallint.h" +#include "extmod/utime_mphal.h" + +STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) { + #if MICROPY_PY_BUILTINS_FLOAT + mp_hal_delay_ms(1000 * mp_obj_get_float(seconds_o)); + #else + mp_hal_delay_ms(1000 * mp_obj_get_int(seconds_o)); + #endif + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_obj, time_sleep); + +STATIC mp_obj_t time_sleep_ms(mp_obj_t arg) { + mp_hal_delay_ms(mp_obj_get_int(arg)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_ms_obj, time_sleep_ms); + +STATIC mp_obj_t time_sleep_us(mp_obj_t arg) { + mp_hal_delay_us(mp_obj_get_int(arg)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_us_obj, time_sleep_us); + +STATIC mp_obj_t time_ticks_ms(void) { + return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & MP_SMALL_INT_POSITIVE_MASK); +} +MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_ticks_ms_obj, time_ticks_ms); + +STATIC mp_obj_t time_ticks_us(void) { + return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_us() & MP_SMALL_INT_POSITIVE_MASK); +} +MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_ticks_us_obj, time_ticks_us); + +STATIC mp_obj_t time_ticks_cpu(void) { + return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_cpu() & MP_SMALL_INT_POSITIVE_MASK); +} +MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_ticks_cpu_obj, time_ticks_cpu); + +STATIC mp_obj_t time_ticks_diff(mp_obj_t start_in, mp_obj_t end_in) { + // we assume that the arguments come from ticks_xx so are small ints + uint32_t start = MP_OBJ_SMALL_INT_VALUE(start_in); + uint32_t end = MP_OBJ_SMALL_INT_VALUE(end_in); + return MP_OBJ_NEW_SMALL_INT((end - start) & MP_SMALL_INT_POSITIVE_MASK); +} +MP_DEFINE_CONST_FUN_OBJ_2(mp_utime_ticks_diff_obj, time_ticks_diff); + +#endif // MICROPY_PY_UTIME_MP_HAL diff --git a/extmod/utime_mphal.h b/extmod/utime_mphal.h new file mode 100644 index 000000000..4f2395a09 --- /dev/null +++ b/extmod/utime_mphal.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2016 Damien P. George + * Copyright (c) 2016 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" + +MP_DECLARE_CONST_FUN_OBJ(mp_utime_sleep_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_utime_sleep_ms_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_utime_sleep_us_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_ms_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_us_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_cpu_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_diff_obj); diff --git a/py/mpconfig.h b/py/mpconfig.h index e33a41f7a..dcdaffe0f 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -860,6 +860,12 @@ typedef double mp_float_t; #define MICROPY_PY_UERRNO (0) #endif +// Whether to provide "utime" module functions implementation +// in terms of mp_hal_* functions. +#ifndef MICROPY_PY_UTIME_MP_HAL +#define MICROPY_PY_UTIME_MP_HAL (0) +#endif + // Whether to provide "_thread" module #ifndef MICROPY_PY_THREAD #define MICROPY_PY_THREAD (0) diff --git a/py/mphal.h b/py/mphal.h index 54a45b024..8d5654f9e 100644 --- a/py/mphal.h +++ b/py/mphal.h @@ -66,6 +66,10 @@ mp_uint_t mp_hal_ticks_ms(void); mp_uint_t mp_hal_ticks_us(void); #endif +#ifndef mp_hal_ticks_cpu +mp_uint_t mp_hal_ticks_cpu(void); +#endif + // If port HAL didn't define its own pin API, use generic // "virtual pin" API from the core. #ifndef mp_hal_pin_obj_t diff --git a/py/py.mk b/py/py.mk index 741ad52f9..8caa37f8a 100644 --- a/py/py.mk +++ b/py/py.mk @@ -229,6 +229,7 @@ PY_O_BASENAME = \ ../extmod/vfs_fat_file.o \ ../extmod/vfs_fat_lexer.o \ ../extmod/vfs_fat_misc.o \ + ../extmod/utime_mphal.o \ ../extmod/moduos_dupterm.o \ ../lib/embed/abort_.o \ ../lib/utils/printf.o \ -- cgit v1.2.3 From 36f97f19b44471f2ed1a3bd37e096ce32a852a1f Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 14 Oct 2016 22:19:45 +0300 Subject: extmod/utime_mphal: sleep_us/ms(): Don't wait on negative argument. --- extmod/utime_mphal.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'extmod') diff --git a/extmod/utime_mphal.c b/extmod/utime_mphal.c index 9471ad525..3ecdc9446 100644 --- a/extmod/utime_mphal.c +++ b/extmod/utime_mphal.c @@ -46,13 +46,19 @@ STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) { MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_obj, time_sleep); STATIC mp_obj_t time_sleep_ms(mp_obj_t arg) { - mp_hal_delay_ms(mp_obj_get_int(arg)); + mp_int_t ms = mp_obj_get_int(arg); + if (ms > 0) { + mp_hal_delay_ms(ms); + } return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_ms_obj, time_sleep_ms); STATIC mp_obj_t time_sleep_us(mp_obj_t arg) { - mp_hal_delay_us(mp_obj_get_int(arg)); + mp_int_t us = mp_obj_get_int(arg); + if (us > 0) { + mp_hal_delay_us(us); + } return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_us_obj, time_sleep_us); -- cgit v1.2.3 From 06234a6115096a80f1a20d97a56c53766a9b8239 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 15 Oct 2016 23:46:13 +0300 Subject: extmod/modussl_mbedtls: Add dummy setblocking() method. Accepts only value of True. --- extmod/modussl_mbedtls.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'extmod') diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c index ddb7ba0fe..5a7a745d8 100644 --- a/extmod/modussl_mbedtls.c +++ b/extmod/modussl_mbedtls.c @@ -215,6 +215,16 @@ STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, in return MP_STREAM_ERROR; } +STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) { + // Currently supports only blocking mode + (void)self_in; + if (!mp_obj_is_true(flag_in)) { + mp_not_implemented(""); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking); + STATIC mp_obj_t socket_close(mp_obj_t self_in) { mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in); @@ -236,6 +246,7 @@ STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) }, { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socket_close_obj) }, }; -- cgit v1.2.3 From 84679e0c065adb357af39b9efbffcf0f3991eece Mon Sep 17 00:00:00 2001 From: Alex March Date: Tue, 18 Oct 2016 14:18:15 +0100 Subject: extmod/vfs_fat_file: Check fatfs f_sync() and f_close() returns for errors. --- extmod/vfs_fat_file.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'extmod') diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c index ecc9ed70f..e269ef593 100644 --- a/extmod/vfs_fat_file.c +++ b/extmod/vfs_fat_file.c @@ -110,14 +110,20 @@ STATIC mp_uint_t file_obj_write(mp_obj_t self_in, const void *buf, mp_uint_t siz STATIC mp_obj_t file_obj_flush(mp_obj_t self_in) { pyb_file_obj_t *self = MP_OBJ_TO_PTR(self_in); - f_sync(&self->fp); + FRESULT res = f_sync(&self->fp); + if (res != FR_OK) { + mp_raise_OSError(fresult_to_errno_table[res]); + } return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(file_obj_flush_obj, file_obj_flush); STATIC mp_obj_t file_obj_close(mp_obj_t self_in) { pyb_file_obj_t *self = MP_OBJ_TO_PTR(self_in); - f_close(&self->fp); + FRESULT res = f_close(&self->fp); + if (res != FR_OK) { + mp_raise_OSError(fresult_to_errno_table[res]); + } return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(file_obj_close_obj, file_obj_close); -- cgit v1.2.3