Esempio n. 1
0
DRESULT disk_ioctl (
    BYTE pdrv,        /* Physical drive nmuber (0..) */
    BYTE cmd,        /* Control code */
    void *buff        /* Buffer to send/receive control data */
)
{
    switch (pdrv) {
        case PD_FLASH:
            switch (cmd) {
                case CTRL_SYNC:
                    storage_flush();
                    return RES_OK;

                case GET_BLOCK_SIZE:
                    *((DWORD*)buff) = 1; // high-level sector erase size in units of the small (512) block size
                    return RES_OK;
            }
            break;

#if MICROPY_HW_HAS_SDCARD
        case PD_SDCARD:
            switch (cmd) {
                case CTRL_SYNC:
                    return RES_OK;

                case GET_BLOCK_SIZE:
                    *((DWORD*)buff) = 1; // high-level sector erase size in units of the small (512) block size
                    return RES_OK;
            }
            break;
#endif

        case PD_USER:
            if (MP_STATE_PORT(fs_user_mount) == NULL) {
                // nothing mounted
                return RES_ERROR;
            }
            switch (cmd) {
                case CTRL_SYNC:
                    if (MP_STATE_PORT(fs_user_mount)->sync[0] != MP_OBJ_NULL) {
                        mp_call_method_n_kw(0, 0, MP_STATE_PORT(fs_user_mount)->sync);
                    }
                    return RES_OK;

                case GET_BLOCK_SIZE:
                    *((DWORD*)buff) = 1; // high-level sector erase size in units of the small (512) bl
                    return RES_OK;

                case GET_SECTOR_COUNT: {
                    mp_obj_t ret = mp_call_method_n_kw(0, 0, MP_STATE_PORT(fs_user_mount)->count);
                    *((DWORD*)buff) = mp_obj_get_int(ret);
                    return RES_OK;
                }
            }
            break;
    }

    return RES_PARERR;
}
Esempio n. 2
0
static int call_dupterm_read(void) {
    if (MP_STATE_PORT(term_obj) == NULL) {
        return -1;
    }

    nlr_buf_t nlr;
    if (nlr_push(&nlr) == 0) {
        mp_obj_t read_m[3];
        mp_load_method(MP_STATE_PORT(term_obj), MP_QSTR_read, read_m);
        read_m[2] = MP_OBJ_NEW_SMALL_INT(1);
        mp_obj_t res = mp_call_method_n_kw(1, 0, read_m);
        if (res == mp_const_none) {
            return -2;
        }
        mp_buffer_info_t bufinfo;
        mp_get_buffer_raise(res, &bufinfo, MP_BUFFER_READ);
        if (bufinfo.len == 0) {
            mp_uos_deactivate("dupterm: EOF received, deactivating\n", MP_OBJ_NULL);
            return -1;
        }
        nlr_pop();
        return *(byte*)bufinfo.buf;
    } else {
        mp_uos_deactivate("dupterm: Exception in read() method, deactivating: ", nlr.ret_val);
    }

    return -1;
}
Esempio n. 3
0
// returns MP_OBJ_NULL if not found
mp_obj_t mp_module_get(qstr module_name) {
    mp_map_t *mp_loaded_modules_map = &MP_STATE_VM(mp_loaded_modules_dict).map;
    // lookup module
    mp_map_elem_t *el = mp_map_lookup(mp_loaded_modules_map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP);

    if (el == NULL) {
        // module not found, look for builtin module names
        el = mp_map_lookup((mp_map_t*)&mp_builtin_module_map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP);
        if (el == NULL) {
            return MP_OBJ_NULL;
        }

        if (MICROPY_MODULE_BUILTIN_INIT) {
            // look for __init__ and call it if it exists
            mp_obj_t dest[2];
            mp_load_method_maybe(el->value, MP_QSTR___init__, dest);
            if (dest[0] != MP_OBJ_NULL) {
                mp_call_method_n_kw(0, 0, dest);
                // register module so __init__ is not called again
                mp_module_register(module_name, el->value);
            }
        }
    }

    // module found, return it
    return el->value;
}
Esempio n. 4
0
DRESULT disk_write (
    bdev_t pdrv,          /* Physical drive nmuber (0..) */
    const BYTE *buff,    /* Data to be written */
    DWORD sector,        /* Sector address (LBA) */
    UINT count            /* Number of sectors to write (1..128) */
)
{
    fs_user_mount_t *vfs = disk_get_device(pdrv);
    if (vfs == NULL) {
        return RES_PARERR;
    }

    if (vfs->writeblocks[0] == MP_OBJ_NULL) {
        // read-only block device
        return RES_WRPRT;
    }

    if (vfs->flags & FSUSER_NATIVE) {
        mp_uint_t (*f)(const uint8_t*, uint32_t, uint32_t) = (void*)(uintptr_t)vfs->writeblocks[2];
        if (f(buff, sector, count) != 0) {
            return RES_ERROR;
        }
    } else {
        mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, count * SECSIZE(&vfs->fatfs), (void*)buff};
        vfs->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
        vfs->writeblocks[3] = MP_OBJ_FROM_PTR(&ar);
        mp_call_method_n_kw(2, 0, vfs->writeblocks);
        // TODO handle error return
    }

    return RES_OK;
}
Esempio n. 5
0
static int call_dupterm_read(void) {
    if (MP_STATE_PORT(term_obj) == NULL) {
        return -1;
    }

    nlr_buf_t nlr;
    if (nlr_push(&nlr) == 0) {
        mp_obj_t read_m[3];
        mp_load_method(MP_STATE_PORT(term_obj), MP_QSTR_read, read_m);
        read_m[2] = MP_OBJ_NEW_SMALL_INT(1);
        mp_obj_t res = mp_call_method_n_kw(1, 0, read_m);
        if (res == mp_const_none) {
            return -2;
        }
        mp_buffer_info_t bufinfo;
        mp_get_buffer_raise(res, &bufinfo, MP_BUFFER_READ);
        if (bufinfo.len == 0) {
            mp_printf(&mp_plat_print, "dupterm: EOF received, deactivating\n");
            MP_STATE_PORT(term_obj) = NULL;
            return -1;
        }
        nlr_pop();
        return *(byte*)bufinfo.buf;
    } else {
        // Temporarily disable dupterm to avoid infinite recursion
        mp_obj_t save_term = MP_STATE_PORT(term_obj);
        MP_STATE_PORT(term_obj) = NULL;
        mp_printf(&mp_plat_print, "dupterm: ");
        mp_obj_print_exception(&mp_plat_print, nlr.ret_val);
        MP_STATE_PORT(term_obj) = save_term;
    }

    return -1;
}
Esempio n. 6
0
DRESULT disk_ioctl (
    bdev_t pdrv,      /* Physical drive nmuber (0..) */
    BYTE cmd,        /* Control code */
    void *buff        /* Buffer to send/receive control data */
)
{
    fs_user_mount_t *vfs = disk_get_device(pdrv);
    if (vfs == NULL) {
        return RES_PARERR;
    }

    // First part: call the relevant method of the underlying block device
    mp_obj_t ret = mp_const_none;
    if (vfs->flags & FSUSER_HAVE_IOCTL) {
        // new protocol with ioctl
        static const uint8_t op_map[8] = {
            [CTRL_SYNC] = BP_IOCTL_SYNC,
            [GET_SECTOR_COUNT] = BP_IOCTL_SEC_COUNT,
            [GET_SECTOR_SIZE] = BP_IOCTL_SEC_SIZE,
            [IOCTL_INIT] = BP_IOCTL_INIT,
        };
        uint8_t bp_op = op_map[cmd & 7];
        if (bp_op != 0) {
            vfs->u.ioctl[2] = MP_OBJ_NEW_SMALL_INT(bp_op);
            vfs->u.ioctl[3] = MP_OBJ_NEW_SMALL_INT(0); // unused
            ret = mp_call_method_n_kw(2, 0, vfs->u.ioctl);
        }
    } else {
Esempio n. 7
0
STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) {
    mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(self_in);
    mp_obj_t sock = o->sock;
    mp_obj_t dest[3];
    mp_load_method(sock, MP_QSTR_setblocking, dest);
    dest[2] = flag_in;
    return mp_call_method_n_kw(1, 0, dest);
}
Esempio n. 8
0
STATIC mp_obj_t socket_close(mp_obj_t self_in) {
    mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in);
    ssl_free(self->ssl_sock);
    ssl_ctx_free(self->ssl_ctx);

    mp_obj_t dest[2];
    mp_load_method(self->sock, MP_QSTR_close, dest);
    return mp_call_method_n_kw(0, 0, dest);
}
Esempio n. 9
0
mp_obj_t vfs_proxy_call(qstr method_name, mp_uint_t n_args, const mp_obj_t *args) {
    if (MP_STATE_PORT(fs_user_mount)[0] == NULL) {
        nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(MP_ENODEV)));
    }

    mp_obj_t meth[n_args + 2];
    mp_load_method(MP_STATE_PORT(fs_user_mount)[0], method_name, meth);
    if (args != NULL) {
        memcpy(meth + 2, args, n_args * sizeof(*args));
    }
    return mp_call_method_n_kw(n_args, 0, meth);
}
Esempio n. 10
0
STATIC mp_uint_t websocket_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
    mp_obj_websocket_t *self = self_in;
    assert(size < 0x10000);
    byte header[4] = {0x80 | (self->opts & FRAME_OPCODE_MASK)};
    int hdr_sz;
    if (size < 126) {
        header[1] = size;
        hdr_sz = 2;
    } else {
        header[1] = 126;
        header[2] = size >> 8;
        header[3] = size & 0xff;
        hdr_sz = 4;
    }

    mp_obj_t dest[3];
    if (self->opts & BLOCKING_WRITE) {
        mp_load_method(self->sock, MP_QSTR_setblocking, dest);
        dest[2] = mp_const_true;
        mp_call_method_n_kw(1, 0, dest);
    }

    mp_uint_t out_sz = mp_stream_write_exactly(self->sock, header, hdr_sz, errcode);
    if (*errcode == 0) {
        out_sz = mp_stream_write_exactly(self->sock, buf, size, errcode);
    }

    if (self->opts & BLOCKING_WRITE) {
        dest[2] = mp_const_false;
        mp_call_method_n_kw(1, 0, dest);
    }

    if (*errcode != 0) {
        return MP_STREAM_ERROR;
    }
    return out_sz;
}
Esempio n. 11
0
STATIC void gc_sweep(void) {
    mp_uint_t block;
    #if MICROPY_PY_GC_COLLECT_RETVAL
    gc_collected = 0;
    #endif
    // free unmarked heads and their tails
    int free_tail = 0;
    for (block = 0; block < gc_alloc_table_byte_len * BLOCKS_PER_ATB; block++) {
        switch (ATB_GET_KIND(block)) {
            case AT_HEAD:
#if MICROPY_ENABLE_FINALISER
                if (FTB_GET(block)) {
                    mp_obj_t obj = (mp_obj_t)PTR_FROM_BLOCK(block);
                    if (((mp_obj_base_t*)obj)->type != MP_OBJ_NULL) {
                        // if the object has a type then see if it has a __del__ method
                        mp_obj_t dest[2];
                        mp_load_method_maybe(obj, MP_QSTR___del__, dest);
                        if (dest[0] != MP_OBJ_NULL) {
                            // load_method returned a method
                            mp_call_method_n_kw(0, 0, dest);
                        }
                    }
                    // clear finaliser flag
                    FTB_CLEAR(block);
                }
#endif
                free_tail = 1;
                #if MICROPY_PY_GC_COLLECT_RETVAL
                gc_collected++;
                #endif
                // fall through to free the head
                // no break - disable eclipse static analyzer warning - intentional fall through

            case AT_TAIL:
                if (free_tail) {
                    DEBUG_printf("gc_sweep(%p)\n",PTR_FROM_BLOCK(block));
                    ATB_ANY_TO_FREE(block);
                }
                break;

            case AT_MARK:
                ATB_MARK_TO_HEAD(block);
                free_tail = 0;
                break;
        }
    }
}
Esempio n. 12
0
STATIC mp_obj_t reversed_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
    mp_arg_check_num(n_args, n_kw, 1, 1, false);

    // check if __reversed__ exists, and if so delegate to it
    mp_obj_t dest[2];
    mp_load_method_maybe(args[0], MP_QSTR___reversed__, dest);
    if (dest[0] != MP_OBJ_NULL) {
        return mp_call_method_n_kw(0, 0, dest);
    }

    mp_obj_reversed_t *o = m_new_obj(mp_obj_reversed_t);
    o->base.type = type;
    o->seq = args[0];
    o->cur_index = mp_obj_get_int(mp_obj_len(args[0])); // start at the end of the sequence

    return MP_OBJ_FROM_PTR(o);
}
Esempio n. 13
0
STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_args, const mp_obj_t *args) {
    assert(n_args <= PROXY_MAX_ARGS);
    if (vfs == MP_VFS_NONE) {
        // mount point not found
        mp_raise_OSError(MP_ENODEV);
    }
    if (vfs == MP_VFS_ROOT) {
        // can't do operation on root dir
        mp_raise_OSError(MP_EPERM);
    }
    mp_obj_t meth[2 + PROXY_MAX_ARGS];
    mp_load_method(vfs->obj, meth_name, meth);
    if (args != NULL) {
        memcpy(meth + 2, args, n_args * sizeof(*args));
    }
    return mp_call_method_n_kw(n_args, 0, meth);
}
Esempio n. 14
0
STATIC void gc_sweep(void) {
    #if MICROPY_PY_GC_COLLECT_RETVAL
    MP_STATE_MEM(gc_collected) = 0;
    #endif
    // free unmarked heads and their tails
    int free_tail = 0;
    for (size_t block = 0; block < MP_STATE_MEM(gc_alloc_table_byte_len) * BLOCKS_PER_ATB; block++) {
        switch (ATB_GET_KIND(block)) {
            case AT_HEAD:
#if MICROPY_ENABLE_FINALISER
                if (FTB_GET(block)) {
                    mp_obj_base_t *obj = (mp_obj_base_t*)PTR_FROM_BLOCK(block);
                    if (obj->type != NULL) {
                        // if the object has a type then see if it has a __del__ method
                        mp_obj_t dest[2];
                        mp_load_method_maybe(MP_OBJ_FROM_PTR(obj), MP_QSTR___del__, dest);
                        if (dest[0] != MP_OBJ_NULL) {
                            // load_method returned a method
                            mp_call_method_n_kw(0, 0, dest);
                        }
                    }
                    // clear finaliser flag
                    FTB_CLEAR(block);
                }
#endif
                free_tail = 1;
                DEBUG_printf("gc_sweep(%x)\n", PTR_FROM_BLOCK(block));
                #if MICROPY_PY_GC_COLLECT_RETVAL
                MP_STATE_MEM(gc_collected)++;
                #endif
                // fall through to free the head

            case AT_TAIL:
                if (free_tail) {
                    ATB_ANY_TO_FREE(block);
                }
                break;

            case AT_MARK:
                ATB_MARK_TO_HEAD(block);
                free_tail = 0;
                break;
        }
    }
}
Esempio n. 15
0
void mp_uos_dupterm_tx_strn(const char *str, size_t len) {
    if (MP_STATE_PORT(term_obj) != MP_OBJ_NULL) {
        nlr_buf_t nlr;
        if (nlr_push(&nlr) == 0) {
            mp_obj_t write_m[3];
            mp_load_method(MP_STATE_PORT(term_obj), MP_QSTR_write, write_m);
            write_m[2] = mp_obj_new_bytearray_by_ref(len, (char*)str);
            mp_call_method_n_kw(1, 0, write_m);
            nlr_pop();
        } else {
            // Temporarily disable dupterm to avoid infinite recursion
            mp_obj_t save_term = MP_STATE_PORT(term_obj);
            MP_STATE_PORT(term_obj) = NULL;
            mp_printf(&mp_plat_print, "dupterm: ");
            mp_obj_print_exception(&mp_plat_print, nlr.ret_val);
            MP_STATE_PORT(term_obj) = save_term;
        }
    }
}
Esempio n. 16
0
DRESULT disk_write (
    BYTE pdrv,            /* Physical drive nmuber (0..) */
    const BYTE *buff,    /* Data to be written */
    DWORD sector,        /* Sector address (LBA) */
    UINT count            /* Number of sectors to write (1..128) */
)
{
    switch (pdrv) {
        case PD_FLASH:
            for (int i = 0; i < count; i++) {
                if (!storage_write_block(buff + i * FLASH_BLOCK_SIZE, sector + i)) {
                    return RES_ERROR;
                }
            }
            return RES_OK;

#if MICROPY_HW_HAS_SDCARD
        case PD_SDCARD:
            if (sdcard_write_blocks(buff, sector, count) != 0) {
                return RES_ERROR;
            }
            return RES_OK;
#endif

        case PD_USER:
            if (MP_STATE_PORT(fs_user_mount) == NULL) {
                // nothing mounted
                return RES_ERROR;
            }
            if (MP_STATE_PORT(fs_user_mount)->writeblocks[0] == MP_OBJ_NULL) {
                // read-only block device
                return RES_ERROR;
            }
            MP_STATE_PORT(fs_user_mount)->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
            MP_STATE_PORT(fs_user_mount)->writeblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, (void*)buff);
            mp_call_method_n_kw(2, 0, MP_STATE_PORT(fs_user_mount)->writeblocks);
            return RES_OK;
    }

    return RES_PARERR;
}
Esempio n. 17
0
mp_int_t mp_obj_hash(mp_obj_t o_in) {
    if (o_in == mp_const_false) {
        return 0; // needs to hash to same as the integer 0, since False==0
    } else if (o_in == mp_const_true) {
        return 1; // needs to hash to same as the integer 1, since True==1
    } else if (MP_OBJ_IS_SMALL_INT(o_in)) {
        return MP_OBJ_SMALL_INT_VALUE(o_in);
    } else if (MP_OBJ_IS_TYPE(o_in, &mp_type_int)) {
        return mp_obj_int_hash(o_in);
    } else if (MP_OBJ_IS_STR(o_in) || MP_OBJ_IS_TYPE(o_in, &mp_type_bytes)) {
        return mp_obj_str_get_hash(o_in);
    } else if (MP_OBJ_IS_TYPE(o_in, &mp_type_NoneType)) {
        return (mp_int_t)o_in;
    } else if (MP_OBJ_IS_FUN(o_in)) {
        return (mp_int_t)o_in;
    } else if (MP_OBJ_IS_TYPE(o_in, &mp_type_tuple)) {
        return mp_obj_tuple_hash(o_in);
    } else if (MP_OBJ_IS_TYPE(o_in, &mp_type_type)) {
        return (mp_int_t)o_in;
    } else if (MP_OBJ_IS_OBJ(o_in)) {
        // if a valid __hash__ method exists, use it
        mp_obj_t hash_method[2];
        mp_load_method_maybe(o_in, MP_QSTR___hash__, hash_method);
        if (hash_method[0] != MP_OBJ_NULL) {
            mp_obj_t hash_val = mp_call_method_n_kw(0, 0, hash_method);
            if (MP_OBJ_IS_INT(hash_val)) {
                return mp_obj_int_get_truncated(hash_val);
            }
        }
    }

    // TODO hash class and instances - in CPython by default user created classes' __hash__ resolves to their id

    if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
        nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "unhashable type"));
    } else {
        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
            "unhashable type: '%s'", mp_obj_get_type_str(o_in)));
    }
}
Esempio n. 18
0
void mp_uos_dupterm_tx_strn(const char *str, size_t len) {
    if (MP_STATE_PORT(term_obj) != MP_OBJ_NULL) {
        nlr_buf_t nlr;
        if (nlr_push(&nlr) == 0) {
            mp_obj_t write_m[3];
            mp_load_method(MP_STATE_PORT(term_obj), MP_QSTR_write, write_m);

            mp_obj_array_t *arr = MP_OBJ_TO_PTR(MP_STATE_PORT(dupterm_arr_obj));
            void *org_items = arr->items;
            arr->items = (void*)str;
            arr->len = len;
            write_m[2] = MP_STATE_PORT(dupterm_arr_obj);
            mp_call_method_n_kw(1, 0, write_m);
            arr = MP_OBJ_TO_PTR(MP_STATE_PORT(dupterm_arr_obj));
            arr->items = org_items;
            arr->len = 1;
            nlr_pop();
        } else {
            mp_uos_deactivate("dupterm: Exception in write() method, deactivating: ", nlr.ret_val);
        }
    }
}
Esempio n. 19
0
STATIC void gc_sweep(void) {
    // free unmarked heads and their tails
    int free_tail = 0;
    for (machine_uint_t block = 0; block < gc_alloc_table_byte_len * BLOCKS_PER_ATB; block++) {
        switch (ATB_GET_KIND(block)) {
            case AT_HEAD:
#if MICROPY_ENABLE_FINALISER
                if (FTB_GET(block)) {
                    mp_obj_t obj = (mp_obj_t)PTR_FROM_BLOCK(block);
                    if (((mp_obj_base_t*)obj)->type != MP_OBJ_NULL) {
                        // if the object has a type then see if it has a __del__ method
                        mp_obj_t dest[2];
                        mp_load_method_maybe(obj, MP_QSTR___del__, dest);
                        if (dest[0] != MP_OBJ_NULL) {
                            // load_method returned a method
                            mp_call_method_n_kw(0, 0, dest);
                        }
                    }
                    // clear finaliser flag
                    FTB_CLEAR(block);
                }
#endif
                free_tail = 1;
                // fall through to free the head

            case AT_TAIL:
                if (free_tail) {
                    ATB_ANY_TO_FREE(block);
                }
                break;

            case AT_MARK:
                ATB_MARK_TO_HEAD(block);
                free_tail = 0;
                break;
        }
    }
}
Esempio n. 20
0
mp_obj_t mp_stream_close(mp_obj_t stream) {
    // TODO: Still consider using ioctl for close
    mp_obj_t dest[2];
    mp_load_method(stream, MP_QSTR_close, dest);
    return mp_call_method_n_kw(0, 0, dest);
}
Esempio n. 21
0
static inline void close_meth(mp_obj_t stream) {
    mp_obj_t dest[2];
    mp_load_method(stream, MP_QSTR_close, dest);
    mp_call_method_n_kw(0, 0, dest);
}