mirror of
https://github.com/micropython/micropython.git
synced 2025-12-24 22:00:12 +01:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f6424efda | ||
|
|
40fc01f406 | ||
|
|
2801e6fad8 | ||
|
|
7f59b4b2ca | ||
|
|
acf6aec71c | ||
|
|
620058cc57 | ||
|
|
ac2f7a7f6a | ||
|
|
82f37bf0d1 | ||
|
|
fa5950eb00 | ||
|
|
99957384ea | ||
|
|
4cd9ced8dc | ||
|
|
2cc5473021 | ||
|
|
c0dcf6e878 | ||
|
|
43ea73faa6 | ||
|
|
12ab9eda8d | ||
|
|
3f327cc4c6 | ||
|
|
567184e21e | ||
|
|
12a5e17afb | ||
|
|
dbc0191d5f | ||
|
|
7f1c98177b | ||
|
|
f0a8f21190 | ||
|
|
e6c6fe3275 | ||
|
|
390e92688c | ||
|
|
332a909d44 | ||
|
|
2039757b85 | ||
|
|
f88eec0de2 | ||
|
|
2686f9b3e8 | ||
|
|
d460a30711 | ||
|
|
3f42f32648 | ||
|
|
344057ac50 | ||
|
|
9d2c0c231c | ||
|
|
1bc534247c | ||
|
|
fdaac1dbf8 | ||
|
|
e178ef2520 | ||
|
|
47098efbda | ||
|
|
7b19e99edd |
@@ -44,6 +44,7 @@ Additional components:
|
||||
mostly to control code size.
|
||||
- teensy/ -- a version of Micro Python that runs on the Teensy 3.1
|
||||
(preliminary but functional).
|
||||
- pic16bit/ -- a version of Micro Python for 16-bit PIC microcontrollers.
|
||||
- unix-cpy/ -- a version of Micro Python that outputs bytecode (for testing).
|
||||
- tests/ -- test framework and test scripts.
|
||||
- tools/ -- various tools, including the pyboard.py module.
|
||||
|
||||
@@ -25,9 +25,12 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#define LAUNCHXL
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "LaunchPad"
|
||||
#define BOARD_NAME "LaunchPad "
|
||||
#define MICROPY_HW_BOARD_NAME VERSION_E(BOARD_NAME, VERSION_NUMBER)
|
||||
#define MICROPY_HW_MCU_NAME "CC3200"
|
||||
|
||||
#define MICROPY_HW_HAS_SDCARD (0)
|
||||
|
||||
@@ -25,9 +25,12 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define LAUNCHXL
|
||||
#include "version.h"
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "WiPy-SD"
|
||||
#define WIPY-SD
|
||||
|
||||
#define BOARD_NAME "WiPy-SD "
|
||||
#define MICROPY_HW_BOARD_NAME VERSION_E(BOARD_NAME, VERSION_NUMBER)
|
||||
#define MICROPY_HW_MCU_NAME "CC3200"
|
||||
|
||||
#define MICROPY_HW_HAS_SDCARD (1)
|
||||
|
||||
@@ -25,9 +25,12 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define LAUNCHXL
|
||||
#include "version.h"
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "WiPy"
|
||||
#define WIPY
|
||||
|
||||
#define BOARD_NAME "WiPy "
|
||||
#define MICROPY_HW_BOARD_NAME VERSION_E(BOARD_NAME, VERSION_NUMBER)
|
||||
#define MICROPY_HW_MCU_NAME "CC3200"
|
||||
|
||||
#define MICROPY_HW_HAS_SDCARD (0)
|
||||
|
||||
@@ -1,6 +1,35 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file R0.10c (C)ChaN, 2014
|
||||
/---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* Original file from:
|
||||
* FatFs - FAT file system module configuration file R0.10c (C)ChaN, 2014
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* 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 _FFCONF
|
||||
#define _FFCONF 32020 /* Revision ID */
|
||||
|
||||
#include <stdint.h>
|
||||
#include "py/mpconfig.h"
|
||||
@@ -8,8 +37,6 @@
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
#define _FFCONF 80376 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Functions and Buffer Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
@@ -24,9 +51,9 @@
|
||||
|
||||
#define _FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes basic writing API functions, f_write(),
|
||||
/ f_sync(), f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(),
|
||||
/ f_getfree() and optional writing functions as well. */
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0
|
||||
@@ -48,9 +75,13 @@
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define _USE_FIND 0
|
||||
/* This option switches filtered directory read feature and related functions,
|
||||
/ f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_MKFS 1
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable)
|
||||
/ To enable it, also _FS_READONLY need to be set to 0. */
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 0
|
||||
@@ -63,8 +94,8 @@
|
||||
|
||||
|
||||
#define _USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
/* To enable it, also _FS_TINY need to be set to 1. */
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable)
|
||||
/ To enable it, also _FS_TINY need to be set to 1. */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
@@ -75,32 +106,24 @@
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/
|
||||
/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows)
|
||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
||||
/ 949 - Korean (DBCS, OEM, Windows)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
||||
/ 1250 - Central Europe (Windows)
|
||||
/ 1251 - Cyrillic (Windows)
|
||||
/ 1252 - Latin 1 (Windows)
|
||||
/ 1253 - Greek (Windows)
|
||||
/ 1254 - Turkish (Windows)
|
||||
/ 1255 - Hebrew (Windows)
|
||||
/ 1256 - Arabic (Windows)
|
||||
/ 1257 - Baltic (Windows)
|
||||
/ 1258 - Vietnam (OEM, Windows)
|
||||
/ 437 - U.S. (OEM)
|
||||
/ 720 - Arabic (OEM)
|
||||
/ 737 - Greek (OEM)
|
||||
/ 775 - Baltic (OEM)
|
||||
/ 850 - Multilingual Latin 1 (OEM)
|
||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
||||
/ 852 - Latin 2 (OEM)
|
||||
/ 855 - Cyrillic (OEM)
|
||||
/ 866 - Russian (OEM)
|
||||
/ 857 - Turkish (OEM)
|
||||
/ 862 - Hebrew (OEM)
|
||||
/ 874 - Thai (OEM, Windows)
|
||||
/ 1 - ASCII (No extended character. Valid for only non-LFN configuration.) */
|
||||
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 775 - Baltic
|
||||
/ 850 - Multilingual Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 858 - Multilingual Latin 1 + Euro
|
||||
/ 862 - Hebrew
|
||||
/ 866 - Russian
|
||||
/ 874 - Thai
|
||||
/ 932 - Japanese Shift_JIS (DBCS)
|
||||
/ 936 - Simplified Chinese GBK (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS)
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN (MICROPY_ENABLE_LFN)
|
||||
@@ -155,8 +178,8 @@
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _STR_VOLUME_ID 0
|
||||
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
|
||||
#define _STR_VOLUME_ID 0
|
||||
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
|
||||
/* _STR_VOLUME_ID option switches string volume ID feature.
|
||||
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
|
||||
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
|
||||
@@ -169,7 +192,7 @@
|
||||
/ number is bound to the same physical drive number and only an FAT volume found on
|
||||
/ the physical drive will be mounted. When multi-partition feature is enabled (1),
|
||||
/ each logical drive number is bound to arbitrary physical drive and partition
|
||||
/ listed in the VolToPart[]. Also f_fdisk() funciton will be enabled. */
|
||||
/ listed in the VolToPart[]. Also f_fdisk() funciton will be available. */
|
||||
|
||||
|
||||
#define _MIN_SS 512
|
||||
@@ -206,9 +229,9 @@
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_NORTC 0
|
||||
#define _NORTC_MON 11
|
||||
#define _NORTC_MDAY 9
|
||||
#define _NORTC_YEAR 2014
|
||||
#define _NORTC_MON 2
|
||||
#define _NORTC_MDAY 1
|
||||
#define _NORTC_YEAR 2015
|
||||
/* The _FS_NORTC option switches timestamp feature. If the system does not have
|
||||
/ an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable
|
||||
/ the timestamp feature. All objects modified by FatFs will have a fixed timestamp
|
||||
@@ -274,3 +297,4 @@
|
||||
/ PIC32 0 H8/300H 0 8051 0/1
|
||||
*/
|
||||
|
||||
#endif // _FFCONF
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MODNETWORK_H_
|
||||
#define MODNETWORK_H_
|
||||
|
||||
#define MOD_NETWORK_IPV4ADDR_BUF_SIZE (4)
|
||||
|
||||
// Forward declaration
|
||||
@@ -79,3 +82,5 @@ void mod_network_parse_ipv4_addr(mp_obj_t addr_in, uint8_t *out_ip);
|
||||
mp_uint_t mod_network_parse_inet_addr(mp_obj_t addr_in, uint8_t *out_ip);
|
||||
mp_obj_t mod_network_format_ipv4_addr(uint8_t *ip);
|
||||
mp_obj_t mod_network_format_inet_addr(uint8_t *ip, mp_uint_t port);
|
||||
|
||||
#endif // MODNETWORK_H_
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include "utils.h"
|
||||
#include "gccollect.h"
|
||||
#include "mperror.h"
|
||||
#include "genhdr/py-version.h"
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -233,16 +234,14 @@ STATIC mp_obj_t pyb_repl_uart(uint n_args, const mp_obj_t *args) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_repl_uart_obj, 0, 1, pyb_repl_uart);
|
||||
|
||||
/// \function mkdisk('path')
|
||||
/// Formats the selected drive, useful when the filesystem has been damaged beyond repair
|
||||
STATIC mp_obj_t pyb_mkdisk(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
if (FR_OK != f_mkfs(path, 1, 0)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
return mp_const_none;
|
||||
/// \function version()
|
||||
/// Prints the software version (MicroPython + Port)
|
||||
STATIC mp_obj_t pyb_version(void) {
|
||||
char version[128];
|
||||
snprintf(version, sizeof(version), "Micro Python " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; " MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME);
|
||||
return mp_obj_new_str(version, strlen(version), false);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_mkdisk_obj, pyb_mkdisk);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_version_obj, pyb_version);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_main_obj); // defined in main.c
|
||||
|
||||
@@ -268,8 +267,7 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_elapsed_micros), (mp_obj_t)&pyb_elapsed_micros_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&pyb_delay_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_udelay), (mp_obj_t)&pyb_udelay_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdisk), (mp_obj_t)&pyb_mkdisk_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_version), (mp_obj_t)&pyb_version_obj },
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rng), (mp_obj_t)&pyb_rng_get_obj },
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "modutime.h"
|
||||
#include "random.h"
|
||||
#include "sd_diskio.h"
|
||||
#include "mpexception.h"
|
||||
|
||||
/// \module os - basic "operating system" services
|
||||
///
|
||||
@@ -54,6 +55,9 @@
|
||||
/// On boot up, the current directory is `/SFLASH` if no SD card is inserted,
|
||||
/// otherwise it is `/SD`.
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC bool sd_in_root(void) {
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
return sd_disk_ready();
|
||||
@@ -62,6 +66,10 @@ STATIC bool sd_in_root(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
//
|
||||
|
||||
/// \function chdir(path)
|
||||
/// Change current directory.
|
||||
STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
|
||||
@@ -73,10 +81,9 @@ STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
|
||||
if (res == FR_OK) {
|
||||
res = f_chdir(path);
|
||||
}
|
||||
// TODO: Warn if too many open files...
|
||||
|
||||
if (res != FR_OK) {
|
||||
// TODO should be mp_type_FileNotFoundError
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
@@ -127,8 +134,7 @@ STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
|
||||
res = f_opendir(&dir, path); /* Open the directory */
|
||||
if (res != FR_OK) {
|
||||
// TODO should be mp_type_FileNotFoundError
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
|
||||
@@ -168,44 +174,28 @@ STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
case FR_EXIST:
|
||||
// TODO should be FileExistsError
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "File exists: '%s'", path));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error creating directory '%s'", path));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir);
|
||||
|
||||
/// \function remove(path)
|
||||
/// Remove a file.
|
||||
/// Remove a file or a directory
|
||||
STATIC mp_obj_t os_remove(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
// TODO check that path is actually a file before trying to unlink it
|
||||
FRESULT res = f_unlink(path);
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing file '%s'", path));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove);
|
||||
|
||||
/// \function rmdir(path)
|
||||
/// Remove a directory.
|
||||
STATIC mp_obj_t os_rmdir(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
// TODO check that path is actually a directory before trying to unlink it
|
||||
FRESULT res = f_unlink(path);
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing directory '%s'", path));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir);
|
||||
|
||||
// Checks for path equality, ignoring trailing slashes:
|
||||
// path_equal(/, /) -> true
|
||||
// path_equal(/flash//, /flash) -> true
|
||||
@@ -282,11 +272,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
|
||||
|
||||
/// \function sync()
|
||||
/// Sync all filesystems.
|
||||
mp_obj_t os_sync(void) {
|
||||
STATIC mp_obj_t os_sync(void) {
|
||||
sflash_disk_flush();
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync);
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
/// \function urandom(n)
|
||||
@@ -304,26 +294,36 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
|
||||
#endif
|
||||
|
||||
/// \function mkdisk('path')
|
||||
/// Formats the selected drive, useful when the filesystem has been damaged beyond repair
|
||||
STATIC mp_obj_t os_mkdisk(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
if (FR_OK != f_mkfs(path, 1, 0)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdisk_obj, os_mkdisk);
|
||||
|
||||
STATIC const mp_map_elem_t os_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_uos) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_uos) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_chdir), (mp_obj_t)&os_chdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getcwd), (mp_obj_t)&os_getcwd_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&os_listdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_rmdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&os_stat_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_chdir), (mp_obj_t)&os_chdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getcwd), (mp_obj_t)&os_getcwd_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&os_listdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_remove_obj }, // rmdir aliases to remove
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&os_stat_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj },
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdisk), (mp_obj_t)&os_mkdisk_obj },
|
||||
|
||||
/// \constant sep - separation character used in paths
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sep), MP_OBJ_NEW_QSTR(MP_QSTR__slash_) },
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj },
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sep), MP_OBJ_NEW_QSTR(MP_QSTR__slash_) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table);
|
||||
|
||||
@@ -25,9 +25,8 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MODUTIME_H_
|
||||
#define MODUTIME_H_
|
||||
#ifndef MODUOS_H_
|
||||
#define MODUOS_H_
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(os_sync_obj);
|
||||
|
||||
#endif // MODUTIME_H_
|
||||
#endif // MODUOS_H_
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MODUOS_H_
|
||||
#define MODUOS_H_
|
||||
#ifndef MODUTIME_H_
|
||||
#define MODUTIME_H_
|
||||
|
||||
typedef struct {
|
||||
uint16_t tm_year; // i.e. 2014
|
||||
@@ -45,4 +45,4 @@ extern mp_uint_t mod_time_seconds_since_2000(mp_uint_t year, mp_uint_t month, mp
|
||||
|
||||
extern void mod_time_seconds_since_2000_to_struct_time(mp_uint_t t, mod_struct_time *tm);
|
||||
|
||||
#endif // MODUOS_H_
|
||||
#endif // MODUTIME_H_
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PYBPIN_H_
|
||||
#define PYBPIN_H_
|
||||
|
||||
// This file requires pin_defs_xxx.h (which has port specific enums and
|
||||
// defines, so we include it here. It should never be included directly
|
||||
|
||||
@@ -73,3 +76,4 @@ uint32_t pin_get_mode(const pin_obj_t *self);
|
||||
uint32_t pin_get_type(const pin_obj_t *self);
|
||||
uint32_t pin_get_strenght(const pin_obj_t *self);
|
||||
|
||||
#endif // PYBPIN_H_
|
||||
|
||||
@@ -73,7 +73,7 @@ STATIC mp_obj_t pybsd_disable (mp_obj_t self_in);
|
||||
STATIC mp_obj_t pybsd_enable (mp_obj_t self_in);
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
__attribute__ ((section (".boot")))
|
||||
void pybsd_init0 (void) {
|
||||
@@ -86,7 +86,7 @@ void pybsd_deinit (void) {
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
/// Initalizes the sd card driver
|
||||
STATIC void pybsd_init (pybsd_obj_t *self) {
|
||||
|
||||
@@ -241,7 +241,7 @@ soft_reset_exit:
|
||||
// soft reset
|
||||
pybsleep_signal_soft_reset();
|
||||
|
||||
printf("WiPy: soft reset\n");
|
||||
printf("PYB: soft reboot\n");
|
||||
|
||||
sflash_disk_flush();
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ Q(micros)
|
||||
Q(elapsed_millis)
|
||||
Q(elapsed_micros)
|
||||
Q(udelay)
|
||||
Q(version)
|
||||
Q(flush)
|
||||
Q(FileIO)
|
||||
Q(mkdisk)
|
||||
|
||||
35
cc3200/version.h
Normal file
35
cc3200/version.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* 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 VERSION_H_
|
||||
#define VERSION_H_
|
||||
|
||||
#define VERSION_NUMBER v0.9.0
|
||||
|
||||
#define VERSION_PASTE(name, number) name # number
|
||||
#define VERSION_E(name, number) VERSION_PASTE(name, number)
|
||||
|
||||
#endif /* VERSION_H_ */
|
||||
@@ -60,7 +60,7 @@ copyright = '2014, Damien P. George'
|
||||
# The short X.Y version.
|
||||
version = '1.4'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.4'
|
||||
release = '1.4.1'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
Micro Python libraries
|
||||
======================
|
||||
|
||||
Functionality specific to the Micro Python implementation is available in
|
||||
the following library.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
micropython.rst
|
||||
|
||||
Python standard libraries
|
||||
-------------------------
|
||||
|
||||
|
||||
37
docs/library/micropython.rst
Normal file
37
docs/library/micropython.rst
Normal file
@@ -0,0 +1,37 @@
|
||||
:mod:`micropython` -- access and control Micro Python internals
|
||||
===============================================================
|
||||
|
||||
.. module:: micropython
|
||||
:synopsis: access and control Micro Python internals
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: mem_info([verbose])
|
||||
|
||||
Print information about currently used memory. If the ``verbose`` argument
|
||||
is given then extra information is printed.
|
||||
|
||||
The information that is printed is implementation dependent, but currently
|
||||
includes the amount of stack and heap used. In verbose mode it prints out
|
||||
the entire heap indicating which blocks are used and which are free.
|
||||
|
||||
.. function:: qstr_info([verbose])
|
||||
|
||||
Print information about currently interned strings. If the ``verbose``
|
||||
argument is given then extra information is printed.
|
||||
|
||||
The information that is printed is implementation dependent, but currently
|
||||
includes the number of interned strings and the amount of RAM they use. In
|
||||
verbose mode it prints out the names of all RAM-interned strings.
|
||||
|
||||
.. function:: alloc_emergency_exception_buf(size)
|
||||
|
||||
Allocate ``size`` bytes of RAM for the emergency exception buffer (a good
|
||||
size is around 100 bytes). The buffer is used to create exceptions in cases
|
||||
when normal RAM allocation would fail (eg within an interrupt handler) and
|
||||
therefore give useful traceback information in these situations.
|
||||
|
||||
A good way to use this function is to put it at the start of your main script
|
||||
(eg boot.py or main.py) and then the emergency exception buffer will be active
|
||||
for all the code following it.
|
||||
@@ -18,6 +18,13 @@ Example usage to toggle an LED at a fixed frequency::
|
||||
tim.init(freq=2) # trigger at 2Hz
|
||||
tim.callback(lambda t:pyb.LED(1).toggle())
|
||||
|
||||
Example using named function for the callback::
|
||||
|
||||
def tick(timer): # we will receive the timer object when being called
|
||||
print(timer.counter()) # show current timer's counter value
|
||||
tim = pyb.Timer(4, freq=1) # create a timer object using timer 4 - trigger at 1Hz
|
||||
tim.callback(tick) # set the callback to our tick function
|
||||
|
||||
Further examples::
|
||||
|
||||
tim = pyb.Timer(4, freq=100) # freq in Hz
|
||||
@@ -32,6 +39,10 @@ Further examples::
|
||||
the servo driver, and Timer 6 is used for timed ADC/DAC reading/writing.
|
||||
It is recommended to use the other timers in your programs.
|
||||
|
||||
*Note:* Memory can't be allocated during a callback (an interrupt) and so
|
||||
exceptions raised within a callback don't give much information. See
|
||||
:func:`micropython.alloc_emergency_exception_buf` for how to get around this
|
||||
limitation.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
@@ -98,8 +98,8 @@ Module contents
|
||||
|
||||
.. class:: struct(descriptor, layout_type)
|
||||
|
||||
Create a "foreign data structure" object based on its descriptor (encoded
|
||||
as a dictionary) and layout type.
|
||||
Create a "foreign data structure" class based on its descriptor (encoded
|
||||
as a dictionary) and layout type (see below).
|
||||
|
||||
.. data:: LITTLE_ENDIAN
|
||||
|
||||
@@ -140,6 +140,22 @@ Module contents
|
||||
so it can be both written too, and you will access current value
|
||||
at the given memory address.
|
||||
|
||||
Structure classes and instantiating structure objects
|
||||
-----------------------------------------------------
|
||||
|
||||
Given structure descriptor and layout type, you can instantiate a
|
||||
"structure class" using uctypes.struct() factory function. From it,
|
||||
you can instantiate a specific structure instance at a given
|
||||
memory address. Memory address usually comes from following sources:
|
||||
|
||||
* Predefined address, when accessing hardware registers on a baremetal
|
||||
port. Lookup these addresses in datasheet for a particular MCU/SoC.
|
||||
* As return value from a call to some FFI (Foreign Function Interface)
|
||||
function.
|
||||
* From uctypes.addressof(), when you want to pass arguments to FFI
|
||||
function, or alternatively, to access some data for I/O (for example,
|
||||
data read from file or network socket).
|
||||
|
||||
Structure objects
|
||||
-----------------
|
||||
|
||||
|
||||
@@ -1,163 +1,21 @@
|
||||
FatFs Module Source Files R0.10c (C)ChaN, 2014
|
||||
FatFs Module Source Files R0.11
|
||||
|
||||
|
||||
FILES
|
||||
|
||||
ffconf.h Configuration file for FatFs module.
|
||||
ff.h Common include file for FatFs and application module.
|
||||
ff.c FatFs module.
|
||||
diskio.h Common include file for FatFs and disk I/O module.
|
||||
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||
integer.h Integer type definitions for FatFs.
|
||||
option Optional external functions.
|
||||
00readme.txt This file.
|
||||
history.txt Revision history.
|
||||
ffconf.h Configuration file for FatFs module.
|
||||
ff.h Common include file for FatFs and application module.
|
||||
ff.c FatFs module.
|
||||
diskio.h Common include file for FatFs and disk I/O module.
|
||||
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||
integer.h Integer type definitions for FatFs.
|
||||
option Optional external functions.
|
||||
|
||||
|
||||
Low level disk I/O module is not included in this archive because the FatFs
|
||||
module is only a generic file system layer and not depend on any specific
|
||||
storage device. You have to provide a low level disk I/O module that written
|
||||
to control your storage device.
|
||||
to control the target storage device.
|
||||
|
||||
|
||||
|
||||
AGREEMENTS
|
||||
|
||||
FatFs module is an open source software to implement FAT file system to
|
||||
small embedded systems. This is a free software and is opened for education,
|
||||
research and commercial developments under license policy of following trems.
|
||||
|
||||
Copyright (C) 2014, ChaN, all right reserved.
|
||||
|
||||
* The FatFs module is a free software and there is NO WARRANTY.
|
||||
* No restriction on use. You can use, modify and redistribute it for
|
||||
personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
|
||||
* Redistributions of source code must retain the above copyright notice.
|
||||
|
||||
|
||||
|
||||
REVISION HISTORY
|
||||
|
||||
Feb 26, 2006 R0.00 Prototype
|
||||
|
||||
Apr 29, 2006 R0.01 First release.
|
||||
|
||||
Jun 01, 2006 R0.02 Added FAT12.
|
||||
Removed unbuffered mode.
|
||||
Fixed a problem on small (<32M) patition.
|
||||
|
||||
Jun 10, 2006 R0.02a Added a configuration option _FS_MINIMUM.
|
||||
|
||||
Sep 22, 2006 R0.03 Added f_rename.
|
||||
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||
|
||||
Dec 11, 2006 R0.03a Improved cluster scan algolithm to write files fast.
|
||||
Fixed f_mkdir creates incorrect directory on FAT32.
|
||||
|
||||
Feb 04, 2007 R0.04 Supported multiple drive system. (FatFs)
|
||||
Changed some APIs for multiple drive system.
|
||||
Added f_mkfs. (FatFs)
|
||||
Added _USE_FAT32 option. (Tiny-FatFs)
|
||||
|
||||
Apr 01, 2007 R0.04a Supported multiple partitions on a plysical drive. (FatFs)
|
||||
Fixed an endian sensitive code in f_mkfs. (FatFs)
|
||||
Added a capability of extending the file size to f_lseek.
|
||||
Added minimization level 3.
|
||||
Fixed a problem that can collapse a sector when recreate an
|
||||
existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs)
|
||||
|
||||
May 05, 2007 R0.04b Added _USE_NTFLAG option.
|
||||
Added FSInfo support.
|
||||
Fixed some problems corresponds to FAT32. (Tiny-FatFs)
|
||||
Fixed DBCS name can result FR_INVALID_NAME.
|
||||
Fixed short seek (0 < ofs <= csize) collapses the file object.
|
||||
|
||||
Aug 25, 2007 R0.05 Changed arguments of f_read, f_write.
|
||||
Changed arguments of f_mkfs. (FatFs)
|
||||
Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs)
|
||||
Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs)
|
||||
|
||||
Feb 03, 2008 R0.05a Added f_truncate().
|
||||
Added f_utime().
|
||||
Fixed off by one error at FAT sub-type determination.
|
||||
Fixed btr in f_read() can be mistruncated.
|
||||
Fixed cached sector is not flushed when create and close without write.
|
||||
|
||||
Apr 01, 2008 R0.06 Added f_forward(). (Tiny-FatFs)
|
||||
Added string functions: fputc(), fputs(), fprintf() and fgets().
|
||||
Improved performance of f_lseek() on move to the same or following cluster.
|
||||
|
||||
Apr 01, 2009, R0.07 Merged Tiny-FatFs as a buffer configuration option.
|
||||
Added long file name support.
|
||||
Added multiple code page support.
|
||||
Added re-entrancy for multitask operation.
|
||||
Added auto cluster size selection to f_mkfs().
|
||||
Added rewind option to f_readdir().
|
||||
Changed result code of critical errors.
|
||||
Renamed string functions to avoid name collision.
|
||||
|
||||
Apr 14, 2009, R0.07a Separated out OS dependent code on reentrant cfg.
|
||||
Added multiple sector size support.
|
||||
|
||||
Jun 21, 2009, R0.07c Fixed f_unlink() may return FR_OK on error.
|
||||
Fixed wrong cache control in f_lseek().
|
||||
Added relative path feature.
|
||||
Added f_chdir().
|
||||
Added f_chdrive().
|
||||
Added proper case conversion for extended characters.
|
||||
|
||||
Nov 03, 2009 R0.07e Separated out configuration options from ff.h to ffconf.h.
|
||||
Added a configuration option, _LFN_UNICODE.
|
||||
Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH.
|
||||
Fixed name matching error on the 13 char boundary.
|
||||
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||
|
||||
May 15, 2010, R0.08 Added a memory configuration option. (_USE_LFN)
|
||||
Added file lock feature. (_FS_SHARE)
|
||||
Added fast seek feature. (_USE_FASTSEEK)
|
||||
Changed some types on the API, XCHAR->TCHAR.
|
||||
Changed fname member in the FILINFO structure on Unicode cfg.
|
||||
String functions support UTF-8 encoding files on Unicode cfg.
|
||||
|
||||
Aug 16,'10 R0.08a Added f_getcwd(). (_FS_RPATH = 2)
|
||||
Added sector erase feature. (_USE_ERASE)
|
||||
Moved file lock semaphore table from fs object to the bss.
|
||||
Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'.
|
||||
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||
|
||||
Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write().
|
||||
f_lseek() reports required table size on creating CLMP.
|
||||
Extended format syntax of f_printf function.
|
||||
Ignores duplicated directory separators in given path names.
|
||||
|
||||
Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature.
|
||||
Added f_fdisk(). (_MULTI_PARTITION = 2)
|
||||
|
||||
Aug 27,'12 R0.09a Fixed assertion failure due to OS/2 EA on FAT12/16.
|
||||
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||
Changed option name _FS_SHARE to _FS_LOCK.
|
||||
|
||||
Jan 23,'13 R0.09b Added f_getlabel() and f_setlabel(). (_USE_LABEL)
|
||||
|
||||
Oct 02,'13 R0.10 Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||
Added f_closedir().
|
||||
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||
Added forced mount feature with changes of f_mount().
|
||||
Improved behavior of volume auto detection.
|
||||
Improved write throughput of f_puts() and f_printf().
|
||||
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code.
|
||||
|
||||
Jan 15,'14 R0.10a Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||
Fixed f_mount() with forced mount fails when drive number is >= 1.
|
||||
Fixed f_close() invalidates the file object without volume lock.
|
||||
Fixed f_closedir() returns but the volume lock is left acquired.
|
||||
Fixed creation of an entry with LFN fails on too many SFN collisions.
|
||||
|
||||
Mar 19,'14 R0.10b Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||
Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN.
|
||||
|
||||
Nov 09,'14 R0.10c Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel().
|
||||
Fixed a potential problem of FAT access that can appear on disk error.
|
||||
Fixed null pointer dereference on attempting to delete the root direcotry.
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#include "diskio.h" /* FatFs lower layer API */
|
||||
#include "usbdisk.h" /* Example: USB drive control */
|
||||
#include "atadrive.h" /* Example: ATA drive control */
|
||||
#include "sdcard.h" /* Example: MMC/SDC contorl */
|
||||
#include "usbdisk.h" /* Example: Header file of existing USB MSD control module */
|
||||
#include "atadrive.h" /* Example: Header file of existing ATA harddisk control module */
|
||||
#include "sdcard.h" /* Example: Header file of existing MMC/SDC contorl module */
|
||||
|
||||
/* Definitions of physical drive number for each drive */
|
||||
#define ATA 0 /* Example: Map ATA drive to drive number 0 */
|
||||
#define MMC 1 /* Example: Map MMC/SD card to drive number 1 */
|
||||
#define USB 2 /* Example: Map USB drive to drive number 2 */
|
||||
#define ATA 0 /* Example: Map ATA harddisk to physical drive 0 */
|
||||
#define MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
|
||||
#define USB 2 /* Example: Map USB MSD to physical drive 2 */
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
750
lib/fatfs/ff.c
750
lib/fatfs/ff.c
File diff suppressed because it is too large
Load Diff
@@ -1,21 +1,23 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.10c (C)ChaN, 2014
|
||||
/ FatFs - FAT file system module include R0.11 (C)ChaN, 2015
|
||||
/----------------------------------------------------------------------------/
|
||||
/ FatFs module is a generic FAT file system module for small embedded systems.
|
||||
/ This is a free software that opened for education, research and commercial
|
||||
/ developments under license policy of following terms.
|
||||
/ FatFs module is a free software that opened under license policy of
|
||||
/ following conditions.
|
||||
/
|
||||
/ Copyright (C) 2014, ChaN, all right reserved.
|
||||
/ Copyright (C) 2015, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef _FATFS
|
||||
#define _FATFS 80376 /* Revision ID */
|
||||
#define _FATFS 32020 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -36,6 +38,7 @@ typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
// dpgeorge: make the partition config table const
|
||||
extern const PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */
|
||||
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */
|
||||
@@ -154,11 +157,14 @@ typedef struct {
|
||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
|
||||
#endif
|
||||
#if _USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File status structure (FILINFO) */
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
DWORD fsize; /* File size */
|
||||
@@ -215,11 +221,13 @@ FRESULT f_sync (FIL* fp); /* Flush cached data of a writing file */
|
||||
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE value, BYTE mask); /* Change attribute of the file/dir */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of the file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change times-tamp of the file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
@@ -239,6 +247,8 @@ TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the fil
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->fsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file R0.10c (C)ChaN, 2014
|
||||
/ FatFs - FAT file system module configuration file R0.11 (C)ChaN, 2015
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FFCONF 80376 /* Revision ID */
|
||||
#define _FFCONF 32020 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Functions and Buffer Configurations
|
||||
@@ -18,13 +18,13 @@
|
||||
|
||||
#define _FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes basic writing API functions, f_write(),
|
||||
/ f_sync(), f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(),
|
||||
/ f_getfree() and optional writing functions as well. */
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some API functions.
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: All basic functions are enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(),
|
||||
@@ -42,9 +42,13 @@
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define _USE_FIND 0
|
||||
/* This option switches filtered directory read feature and related functions,
|
||||
/ f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_MKFS 0
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable)
|
||||
/ To enable it, also _FS_READONLY need to be set to 0. */
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 0
|
||||
@@ -57,8 +61,8 @@
|
||||
|
||||
|
||||
#define _USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
/* To enable it, also _FS_TINY need to be set to 1. */
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable)
|
||||
/ To enable it, also _FS_TINY need to be set to 1. */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
@@ -69,32 +73,24 @@
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/
|
||||
/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows)
|
||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
||||
/ 949 - Korean (DBCS, OEM, Windows)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
||||
/ 1250 - Central Europe (Windows)
|
||||
/ 1251 - Cyrillic (Windows)
|
||||
/ 1252 - Latin 1 (Windows)
|
||||
/ 1253 - Greek (Windows)
|
||||
/ 1254 - Turkish (Windows)
|
||||
/ 1255 - Hebrew (Windows)
|
||||
/ 1256 - Arabic (Windows)
|
||||
/ 1257 - Baltic (Windows)
|
||||
/ 1258 - Vietnam (OEM, Windows)
|
||||
/ 437 - U.S. (OEM)
|
||||
/ 720 - Arabic (OEM)
|
||||
/ 737 - Greek (OEM)
|
||||
/ 775 - Baltic (OEM)
|
||||
/ 850 - Multilingual Latin 1 (OEM)
|
||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
||||
/ 852 - Latin 2 (OEM)
|
||||
/ 855 - Cyrillic (OEM)
|
||||
/ 866 - Russian (OEM)
|
||||
/ 857 - Turkish (OEM)
|
||||
/ 862 - Hebrew (OEM)
|
||||
/ 874 - Thai (OEM, Windows)
|
||||
/ 1 - ASCII (No extended character. Valid for only non-LFN configuration.) */
|
||||
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 775 - Baltic
|
||||
/ 850 - Multilingual Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 858 - Multilingual Latin 1 + Euro
|
||||
/ 862 - Hebrew
|
||||
/ 866 - Russian
|
||||
/ 874 - Thai
|
||||
/ 932 - Japanese Shift_JIS (DBCS)
|
||||
/ 936 - Simplified Chinese GBK (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS)
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN 0
|
||||
@@ -163,7 +159,7 @@
|
||||
/ number is bound to the same physical drive number and only an FAT volume found on
|
||||
/ the physical drive will be mounted. When multi-partition feature is enabled (1),
|
||||
/ each logical drive number is bound to arbitrary physical drive and partition
|
||||
/ listed in the VolToPart[]. Also f_fdisk() funciton will be enabled. */
|
||||
/ listed in the VolToPart[]. Also f_fdisk() funciton will be available. */
|
||||
|
||||
|
||||
#define _MIN_SS 512
|
||||
@@ -200,9 +196,9 @@
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_NORTC 0
|
||||
#define _NORTC_MON 11
|
||||
#define _NORTC_MDAY 9
|
||||
#define _NORTC_YEAR 2014
|
||||
#define _NORTC_MON 2
|
||||
#define _NORTC_MDAY 1
|
||||
#define _NORTC_YEAR 2015
|
||||
/* The _FS_NORTC option switches timestamp feature. If the system does not have
|
||||
/ an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable
|
||||
/ the timestamp feature. All objects modified by FatFs will have a fixed timestamp
|
||||
|
||||
180
lib/fatfs/history.txt
Normal file
180
lib/fatfs/history.txt
Normal file
@@ -0,0 +1,180 @@
|
||||
----------------------------------------------------------------------------
|
||||
Revision history of FatFs module
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
R0.00 (February 26, 2006)
|
||||
Prototype.
|
||||
|
||||
|
||||
R0.01 (April 29, 2006)
|
||||
First stable version.
|
||||
|
||||
|
||||
R0.02 (June 01, 2006)
|
||||
Added FAT12 support.
|
||||
Removed unbuffered mode.
|
||||
Fixed a problem on small (<32M) partition.
|
||||
|
||||
|
||||
R0.02a (June 10, 2006)
|
||||
Added a configuration option (_FS_MINIMUM).
|
||||
|
||||
|
||||
R0.03 (September 22, 2006)
|
||||
Added f_rename().
|
||||
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||
|
||||
|
||||
R0.03a (December 11, 2006)
|
||||
Improved cluster scan algorithm to write files fast.
|
||||
Fixed f_mkdir() creates incorrect directory on FAT32.
|
||||
|
||||
|
||||
R0.04 (February 04, 2007)
|
||||
Added f_mkfs().
|
||||
Supported multiple drive system.
|
||||
Changed some interfaces for multiple drive system.
|
||||
Changed f_mountdrv() to f_mount().
|
||||
|
||||
|
||||
R0.04a (April 01, 2007)
|
||||
Supported multiple partitions on a physical drive.
|
||||
Added a capability of extending file size to f_lseek().
|
||||
Added minimization level 3.
|
||||
Fixed an endian sensitive code in f_mkfs().
|
||||
|
||||
|
||||
R0.04b (May 05, 2007)
|
||||
Added a configuration option _USE_NTFLAG.
|
||||
Added FSINFO support.
|
||||
Fixed DBCS name can result FR_INVALID_NAME.
|
||||
Fixed short seek (<= csize) collapses the file object.
|
||||
|
||||
|
||||
R0.05 (August 25, 2007)
|
||||
Changed arguments of f_read(), f_write() and f_mkfs().
|
||||
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
|
||||
Fixed f_mkdir() on FAT32 creates incorrect directory.
|
||||
|
||||
|
||||
R0.05a (February 03, 2008)
|
||||
Added f_truncate() and f_utime().
|
||||
Fixed off by one error at FAT sub-type determination.
|
||||
Fixed btr in f_read() can be mistruncated.
|
||||
Fixed cached sector is not flushed when create and close without write.
|
||||
|
||||
|
||||
R0.06 (April 01, 2008)
|
||||
Added fputc(), fputs(), fprintf() and fgets().
|
||||
Improved performance of f_lseek() on moving to the same or following cluster.
|
||||
|
||||
|
||||
R0.07 (April 01, 2009)
|
||||
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
|
||||
Added long file name feature. (_USE_LFN)
|
||||
Added multiple code page feature. (_CODE_PAGE)
|
||||
Added re-entrancy for multitask operation. (_FS_REENTRANT)
|
||||
Added auto cluster size selection to f_mkfs().
|
||||
Added rewind option to f_readdir().
|
||||
Changed result code of critical errors.
|
||||
Renamed string functions to avoid name collision.
|
||||
|
||||
|
||||
R0.07a (April 14, 2009)
|
||||
Septemberarated out OS dependent code on reentrant cfg.
|
||||
Added multiple sector size feature.
|
||||
|
||||
|
||||
R0.07c (June 21, 2009)
|
||||
Fixed f_unlink() can return FR_OK on error.
|
||||
Fixed wrong cache control in f_lseek().
|
||||
Added relative path feature.
|
||||
Added f_chdir() and f_chdrive().
|
||||
Added proper case conversion to extended character.
|
||||
|
||||
|
||||
R0.07e (November 03, 2009)
|
||||
Septemberarated out configuration options from ff.h to ffconf.h.
|
||||
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
|
||||
Fixed name matching error on the 13 character boundary.
|
||||
Added a configuration option, _LFN_UNICODE.
|
||||
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||
|
||||
|
||||
R0.08 (May 15, 2010)
|
||||
Added a memory configuration option. (_USE_LFN = 3)
|
||||
Added file lock feature. (_FS_SHARE)
|
||||
Added fast seek feature. (_USE_FASTSEEK)
|
||||
Changed some types on the API, XCHAR->TCHAR.
|
||||
Changed .fname in the FILINFO structure on Unicode cfg.
|
||||
String functions support UTF-8 encoding files on Unicode cfg.
|
||||
|
||||
|
||||
R0.08a (August 16, 2010)
|
||||
Added f_getcwd(). (_FS_RPATH = 2)
|
||||
Added sector erase feature. (_USE_ERASE)
|
||||
Moved file lock semaphore table from fs object to the bss.
|
||||
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||
|
||||
|
||||
R0.08b (January 15, 2011)
|
||||
Fast seek feature is also applied to f_read() and f_write().
|
||||
f_lseek() reports required table size on creating CLMP.
|
||||
Extended format syntax of f_printf().
|
||||
Ignores duplicated directory separators in given path name.
|
||||
|
||||
|
||||
R0.09 (September 06, 2011)
|
||||
f_mkfs() supports multiple partition to complete the multiple partition feature.
|
||||
Added f_fdisk().
|
||||
|
||||
|
||||
R0.09a (August 27, 2012)
|
||||
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||
Changed option name _FS_SHARE to _FS_LOCK.
|
||||
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
|
||||
|
||||
|
||||
R0.09b (January 24, 2013)
|
||||
Added f_setlabel() and f_getlabel().
|
||||
|
||||
|
||||
R0.10 (October 02, 2013)
|
||||
Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||
Added f_closedir().
|
||||
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||
Added forced mount feature with changes of f_mount().
|
||||
Improved behavior of volume auto detection.
|
||||
Improved write throughput of f_puts() and f_printf().
|
||||
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code.
|
||||
|
||||
|
||||
R0.10a (January 15, 2014)
|
||||
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
|
||||
Fixed f_close() invalidates the file object without volume lock.
|
||||
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
|
||||
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
|
||||
|
||||
|
||||
R0.10b (May 19, 2014)
|
||||
Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||
Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN. (appeared at R0.07)
|
||||
|
||||
|
||||
R0.10c (November 09, 2014)
|
||||
Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||
Changed option name _USE_ERASE to _USE_TRIM.
|
||||
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
|
||||
Fixed a potential problem of FAT access that can appear on disk error.
|
||||
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
|
||||
|
||||
|
||||
R0.11 (February 09, 2015)
|
||||
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
|
||||
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
|
||||
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "cc949.c"
|
||||
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
|
||||
#include "cc950.c"
|
||||
#else /* Small character-set */
|
||||
#else /* Single Byte Character-Set */
|
||||
#include "ccsbcs.c"
|
||||
#endif
|
||||
|
||||
|
||||
66
pic16bit/Makefile
Normal file
66
pic16bit/Makefile
Normal file
@@ -0,0 +1,66 @@
|
||||
include ../py/mkenv.mk
|
||||
|
||||
# qstr definitions (must come before including py.mk)
|
||||
QSTR_DEFS = qstrdefsport.h
|
||||
|
||||
# include py core make definitions
|
||||
include ../py/py.mk
|
||||
|
||||
XC16 = /opt/microchip/xc16/v1.24
|
||||
CROSS_COMPILE = $(XC16)/bin/xc16-
|
||||
|
||||
PARTFAMILY = dsPIC33F
|
||||
PART = 33FJ256GP506
|
||||
|
||||
INC = -I.
|
||||
INC += -I..
|
||||
INC += -I../lib/mp-readline
|
||||
INC += -I../stmhal
|
||||
INC += -I$(BUILD)
|
||||
INC += -I$(XC16)/include
|
||||
INC += -I$(XC16)/support/$(PARTFAMILY)/h
|
||||
|
||||
CFLAGS_PIC16BIT = -mcpu=$(PART) -mlarge-code
|
||||
CFLAGS = $(INC) -Wall -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_PIC16BIT) $(COPT)
|
||||
|
||||
#Debugging/Optimization
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -O0 -ggdb
|
||||
else
|
||||
CFLAGS += -O1 -DNDEBUG
|
||||
endif
|
||||
|
||||
LDFLAGS = --heap=0 -nostdlib -T $(XC16)/support/$(PARTFAMILY)/gld/p$(PART).gld -Map=$@.map --cref -p$(PART)
|
||||
LIBS = -L$(XC16)/lib -L$(XC16)/lib/$(PARTFAMILY) -lc -lm -lpic30 -lp$(PART)
|
||||
|
||||
SRC_C = \
|
||||
main.c \
|
||||
board.c \
|
||||
pic16bit_mphal.c \
|
||||
modpyb.c \
|
||||
modpybled.c \
|
||||
modpybswitch.c \
|
||||
stmhal/pybstdio.c \
|
||||
stmhal/pyexec.c \
|
||||
lib/mp-readline/readline.c \
|
||||
|
||||
SRC_S = \
|
||||
# gchelper.s \
|
||||
|
||||
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o))
|
||||
|
||||
all: $(BUILD)/firmware.hex
|
||||
|
||||
$(BUILD)/firmware.hex: $(BUILD)/firmware.elf
|
||||
$(ECHO) "Create $@"
|
||||
$(Q)$(CROSS_COMPILE)bin2hex $<
|
||||
|
||||
$(BUILD)/firmware.elf: $(OBJ)
|
||||
$(ECHO) "LINK $@"
|
||||
$(Q)$(LD) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
|
||||
$(Q)size $@
|
||||
|
||||
$(PY_BUILD)/gc.o: CFLAGS += -O1
|
||||
$(PY_BUILD)/vm.o: CFLAGS += -O1
|
||||
|
||||
include ../py/mkrules.mk
|
||||
153
pic16bit/board.c
Normal file
153
pic16bit/board.c
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include <p33Fxxxx.h>
|
||||
#include "board.h"
|
||||
|
||||
/********************************************************************/
|
||||
// CPU
|
||||
|
||||
void cpu_init(void) {
|
||||
// set oscillator to operate at 40MHz
|
||||
// Fosc = Fin*M/(N1*N2), Fcy = Fosc/2
|
||||
// Fosc = 7.37M*40/(2*2) = 80Mhz for 7.37M input clock
|
||||
PLLFBD = 41; // M=39
|
||||
CLKDIVbits.PLLPOST = 0; // N1=2
|
||||
CLKDIVbits.PLLPRE = 0; // N2=2
|
||||
OSCTUN = 0;
|
||||
|
||||
// initiate clock switch to FRC with PLL
|
||||
__builtin_write_OSCCONH(0x01);
|
||||
__builtin_write_OSCCONL(0x01);
|
||||
|
||||
// wait for clock switch to occur
|
||||
while (OSCCONbits.COSC != 0x01) {
|
||||
}
|
||||
while (!OSCCONbits.LOCK) {
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
// LEDs
|
||||
|
||||
#define RED_LED_TRIS _TRISC15
|
||||
#define YELLOW_LED_TRIS _TRISC13
|
||||
#define GREEN_LED_TRIS _TRISC14
|
||||
|
||||
#define RED_LED _LATC15
|
||||
#define YELLOW_LED _LATC13
|
||||
#define GREEN_LED _LATC14
|
||||
|
||||
#define LED_ON (0)
|
||||
#define LED_OFF (1)
|
||||
|
||||
void led_init(void) {
|
||||
// set led GPIO as outputs
|
||||
RED_LED_TRIS = 0;
|
||||
YELLOW_LED_TRIS = 0;
|
||||
GREEN_LED_TRIS = 0;
|
||||
|
||||
// turn off the LEDs
|
||||
RED_LED = LED_OFF;
|
||||
YELLOW_LED = LED_OFF;
|
||||
GREEN_LED = LED_OFF;
|
||||
}
|
||||
|
||||
void led_state(int led, int state) {
|
||||
int val = state ? LED_ON : LED_OFF;
|
||||
switch (led) {
|
||||
case 1: RED_LED = val; break;
|
||||
case 2: YELLOW_LED = val; break;
|
||||
case 3: GREEN_LED = val; break;
|
||||
}
|
||||
}
|
||||
|
||||
void led_toggle(int led) {
|
||||
switch (led) {
|
||||
case 1: RED_LED ^= 1; break;
|
||||
case 2: YELLOW_LED ^= 1; break;
|
||||
case 3: GREEN_LED ^= 1; break;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
// switches
|
||||
|
||||
#define SWITCH_S1_TRIS _TRISD8
|
||||
#define SWITCH_S2_TRIS _TRISD9
|
||||
|
||||
#define SWITCH_S1 _RD8
|
||||
#define SWITCH_S2 _RD9
|
||||
|
||||
void switch_init(void) {
|
||||
// set switch GPIO as inputs
|
||||
SWITCH_S1_TRIS = 1;
|
||||
SWITCH_S2_TRIS = 1;
|
||||
}
|
||||
|
||||
int switch_get(int sw) {
|
||||
int val = 1;
|
||||
switch (sw) {
|
||||
case 1: val = SWITCH_S1; break;
|
||||
case 2: val = SWITCH_S2; break;
|
||||
}
|
||||
return val == 0;
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
// UART
|
||||
|
||||
/*
|
||||
// TODO need an irq
|
||||
void uart_rx_irq(void) {
|
||||
if (c == interrupt_char) {
|
||||
MP_STATE_VM(mp_pending_exception) = MP_STATE_PORT(keyboard_interrupt_obj);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void uart_init(void) {
|
||||
// baudrate = F_CY / 16 (uxbrg + 1)
|
||||
// F_CY = 40MHz for us
|
||||
UART1.uxbrg = 64; // 38400 baud
|
||||
UART1.uxmode = 1 << 15; // UARTEN
|
||||
UART1.uxsta = 1 << 10; // UTXEN
|
||||
}
|
||||
|
||||
int uart_rx_any(void) {
|
||||
return UART1.uxsta & 1; // URXDA
|
||||
}
|
||||
|
||||
int uart_rx_char(void) {
|
||||
return UART1.uxrxreg;
|
||||
}
|
||||
|
||||
void uart_tx_char(int chr) {
|
||||
while (UART1.uxsta & (1 << 9)) {
|
||||
// tx fifo is full
|
||||
}
|
||||
UART1.uxtxreg = chr;
|
||||
}
|
||||
43
pic16bit/board.h
Normal file
43
pic16bit/board.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 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_PIC16BIT_BOARD_H__
|
||||
#define __MICROPY_INCLUDED_PIC16BIT_BOARD_H__
|
||||
|
||||
void cpu_init(void);
|
||||
|
||||
void led_init(void);
|
||||
void led_state(int led, int state);
|
||||
void led_toggle(int led);
|
||||
|
||||
void switch_init(void);
|
||||
int switch_get(int sw);
|
||||
|
||||
void uart_init(void);
|
||||
int uart_rx_any(void);
|
||||
int uart_rx_char(void);
|
||||
void uart_tx_char(int chr);
|
||||
|
||||
#endif // __MICROPY_INCLUDED_PIC16BIT_BOARD_H__
|
||||
125
pic16bit/main.c
Normal file
125
pic16bit/main.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <p33Fxxxx.h>
|
||||
|
||||
#include "py/compile.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "pyexec.h"
|
||||
#include "readline.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "board.h"
|
||||
#include "modpyb.h"
|
||||
|
||||
_FGS(GWRP_OFF & GCP_OFF);
|
||||
_FOSCSEL(FNOSC_FRC);
|
||||
_FOSC(FCKSM_CSECMD & OSCIOFNC_ON & POSCMD_NONE);
|
||||
_FWDT(FWDTEN_OFF);
|
||||
|
||||
// maximum heap for device with 8k RAM
|
||||
static char heap[4600];
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// init the CPU and the peripherals
|
||||
cpu_init();
|
||||
led_init();
|
||||
switch_init();
|
||||
uart_init();
|
||||
|
||||
soft_reset:
|
||||
|
||||
// flash green led for 150ms to indicate boot
|
||||
led_state(1, 0);
|
||||
led_state(2, 0);
|
||||
led_state(3, 1);
|
||||
mp_hal_milli_delay(150);
|
||||
led_state(3, 0);
|
||||
|
||||
// init MicroPython runtime
|
||||
int stack_dummy;
|
||||
MP_STATE_VM(stack_top) = (char*)&stack_dummy;
|
||||
gc_init(heap, heap + sizeof(heap));
|
||||
mp_init();
|
||||
mp_hal_init();
|
||||
readline_init0();
|
||||
|
||||
// REPL loop
|
||||
for (;;) {
|
||||
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
|
||||
if (pyexec_raw_repl() != 0) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (pyexec_friendly_repl() != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("PYB: soft reboot\n");
|
||||
mp_deinit();
|
||||
goto soft_reset;
|
||||
}
|
||||
|
||||
void gc_collect(void) {
|
||||
// TODO possibly need to trace registers
|
||||
void *dummy;
|
||||
gc_collect_start();
|
||||
// Node: stack is ascending
|
||||
gc_collect_root(&dummy, ((mp_uint_t)&dummy - (mp_uint_t)MP_STATE_VM(stack_top)) / sizeof(mp_uint_t));
|
||||
gc_collect_end();
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
return MP_IMPORT_STAT_NO_EXIST;
|
||||
}
|
||||
|
||||
mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
||||
|
||||
void nlr_jump_fail(void *val) {
|
||||
}
|
||||
|
||||
void NORETURN __fatal_error(const char *msg) {
|
||||
while (1);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) {
|
||||
printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
|
||||
__fatal_error("Assertion failed");
|
||||
}
|
||||
#endif
|
||||
71
pic16bit/modpyb.c
Normal file
71
pic16bit/modpyb.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "py/obj.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "modpyb.h"
|
||||
|
||||
STATIC mp_obj_t pyb_millis(void) {
|
||||
return MP_OBJ_NEW_SMALL_INT(mp_hal_get_milliseconds());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_millis_obj, pyb_millis);
|
||||
|
||||
STATIC mp_obj_t pyb_elapsed_millis(mp_obj_t start) {
|
||||
uint32_t startMillis = mp_obj_get_int(start);
|
||||
uint32_t currMillis = mp_hal_get_milliseconds();
|
||||
return MP_OBJ_NEW_SMALL_INT((currMillis - startMillis) & 0x1fff);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_elapsed_millis_obj, pyb_elapsed_millis);
|
||||
|
||||
STATIC mp_obj_t pyb_delay(mp_obj_t ms_in) {
|
||||
mp_int_t ms = mp_obj_get_int(ms_in);
|
||||
if (ms >= 0) {
|
||||
mp_hal_milli_delay(ms);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_delay_obj, pyb_delay);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pyb) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_millis), (mp_obj_t)&pyb_millis_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_elapsed_millis), (mp_obj_t)&pyb_elapsed_millis_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&pyb_delay_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_LED), (mp_obj_t)&pyb_led_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Switch), (mp_obj_t)&pyb_switch_type },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_module_globals, pyb_module_globals_table);
|
||||
|
||||
const mp_obj_module_t pyb_module = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_pyb,
|
||||
.globals = (mp_obj_dict_t*)&pyb_module_globals,
|
||||
};
|
||||
33
pic16bit/modpyb.h
Normal file
33
pic16bit/modpyb.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 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_PIC16BIT_MODPYB_H__
|
||||
#define __MICROPY_INCLUDED_PIC16BIT_MODPYB_H__
|
||||
|
||||
extern const mp_obj_type_t pyb_led_type;
|
||||
extern const mp_obj_type_t pyb_switch_type;
|
||||
extern const mp_obj_module_t pyb_module;
|
||||
|
||||
#endif // __MICROPY_INCLUDED_PIC16BIT_MODPYB_H__
|
||||
93
pic16bit/modpybled.c
Normal file
93
pic16bit/modpybled.c
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "board.h"
|
||||
#include "modpyb.h"
|
||||
|
||||
typedef struct _pyb_led_obj_t {
|
||||
mp_obj_base_t base;
|
||||
} pyb_led_obj_t;
|
||||
|
||||
STATIC const pyb_led_obj_t pyb_led_obj[] = {
|
||||
{{&pyb_led_type}},
|
||||
{{&pyb_led_type}},
|
||||
{{&pyb_led_type}},
|
||||
};
|
||||
|
||||
#define NUM_LED MP_ARRAY_SIZE(pyb_led_obj)
|
||||
#define LED_ID(obj) ((obj) - &pyb_led_obj[0] + 1)
|
||||
|
||||
void pyb_led_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_led_obj_t *self = self_in;
|
||||
print(env, "LED(%u)", LED_ID(self));
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_led_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
||||
mp_int_t led_id = mp_obj_get_int(args[0]);
|
||||
if (!(1 <= led_id && led_id <= NUM_LED)) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "LED %d does not exist", led_id));
|
||||
}
|
||||
return (mp_obj_t)&pyb_led_obj[led_id - 1];
|
||||
}
|
||||
|
||||
mp_obj_t pyb_led_on(mp_obj_t self_in) {
|
||||
pyb_led_obj_t *self = self_in;
|
||||
led_state(LED_ID(self), 1);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_led_on_obj, pyb_led_on);
|
||||
|
||||
mp_obj_t pyb_led_off(mp_obj_t self_in) {
|
||||
pyb_led_obj_t *self = self_in;
|
||||
led_state(LED_ID(self), 0);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_led_off_obj, pyb_led_off);
|
||||
|
||||
mp_obj_t pyb_led_toggle(mp_obj_t self_in) {
|
||||
pyb_led_obj_t *self = self_in;
|
||||
led_toggle(LED_ID(self));
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_led_toggle_obj, pyb_led_toggle);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_led_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_on), (mp_obj_t)&pyb_led_on_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_off), (mp_obj_t)&pyb_led_off_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_toggle), (mp_obj_t)&pyb_led_toggle_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_led_locals_dict, pyb_led_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_led_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_LED,
|
||||
.print = pyb_led_print,
|
||||
.make_new = pyb_led_make_new,
|
||||
.locals_dict = (mp_obj_t)&pyb_led_locals_dict,
|
||||
};
|
||||
81
pic16bit/modpybswitch.c
Normal file
81
pic16bit/modpybswitch.c
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "board.h"
|
||||
#include "modpyb.h"
|
||||
|
||||
typedef struct _pyb_switch_obj_t {
|
||||
mp_obj_base_t base;
|
||||
} pyb_switch_obj_t;
|
||||
|
||||
STATIC const pyb_switch_obj_t pyb_switch_obj[] = {
|
||||
{{&pyb_switch_type}},
|
||||
{{&pyb_switch_type}},
|
||||
};
|
||||
|
||||
#define NUM_SWITCH MP_ARRAY_SIZE(pyb_switch_obj)
|
||||
#define SWITCH_ID(obj) ((obj) - &pyb_switch_obj[0] + 1)
|
||||
|
||||
void pyb_switch_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_switch_obj_t *self = self_in;
|
||||
print(env, "Switch(%u)", SWITCH_ID(self));
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_switch_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
||||
mp_int_t sw_id = mp_obj_get_int(args[0]);
|
||||
if (!(1 <= sw_id && sw_id <= NUM_SWITCH)) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Switch %d does not exist", sw_id));
|
||||
}
|
||||
return (mp_obj_t)&pyb_switch_obj[sw_id - 1];
|
||||
}
|
||||
|
||||
mp_obj_t pyb_switch_value(mp_obj_t self_in) {
|
||||
pyb_switch_obj_t *self = self_in;
|
||||
return switch_get(SWITCH_ID(self)) ? mp_const_true : mp_const_false;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_switch_value_obj, pyb_switch_value);
|
||||
|
||||
mp_obj_t pyb_switch_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||
return pyb_switch_value(self_in);
|
||||
}
|
||||
|
||||
STATIC const mp_map_elem_t pyb_switch_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&pyb_switch_value_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_switch_locals_dict, pyb_switch_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_switch_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_Switch,
|
||||
.print = pyb_switch_print,
|
||||
.make_new = pyb_switch_make_new,
|
||||
.call = pyb_switch_call,
|
||||
.locals_dict = (mp_obj_t)&pyb_switch_locals_dict,
|
||||
};
|
||||
110
pic16bit/mpconfigport.h
Normal file
110
pic16bit/mpconfigport.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// options to control how MicroPython is built
|
||||
#define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_B)
|
||||
#define MICROPY_ALLOC_PATH_MAX (64)
|
||||
#define MICROPY_EMIT_X64 (0)
|
||||
#define MICROPY_EMIT_THUMB (0)
|
||||
#define MICROPY_EMIT_INLINE_THUMB (0)
|
||||
#define MICROPY_COMP_MODULE_CONST (0)
|
||||
#define MICROPY_COMP_CONST (0)
|
||||
#define MICROPY_MEM_STATS (0)
|
||||
#define MICROPY_DEBUG_PRINTERS (0)
|
||||
#define MICROPY_ENABLE_GC (1)
|
||||
#define MICROPY_REPL_EVENT_DRIVEN (0)
|
||||
#define MICROPY_HELPER_REPL (1)
|
||||
#define MICROPY_HELPER_LEXER_UNIX (0)
|
||||
#define MICROPY_ENABLE_SOURCE_LINE (0)
|
||||
#define MICROPY_ENABLE_DOC_STRING (0)
|
||||
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
|
||||
#define MICROPY_PY_BUILTINS_BYTEARRAY (0)
|
||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW (0)
|
||||
#define MICROPY_PY_BUILTINS_FROZENSET (0)
|
||||
#define MICROPY_PY_BUILTINS_SET (0)
|
||||
#define MICROPY_PY_BUILTINS_SLICE (0)
|
||||
#define MICROPY_PY_BUILTINS_PROPERTY (0)
|
||||
#define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
|
||||
#define MICROPY_PY___FILE__ (0)
|
||||
#define MICROPY_PY_GC (1)
|
||||
#define MICROPY_PY_ARRAY (0)
|
||||
#define MICROPY_PY_COLLECTIONS (0)
|
||||
#define MICROPY_PY_MATH (0)
|
||||
#define MICROPY_PY_CMATH (0)
|
||||
#define MICROPY_PY_IO (0)
|
||||
#define MICROPY_PY_STRUCT (0)
|
||||
#define MICROPY_PY_SYS (0)
|
||||
#define MICROPY_MODULE_FROZEN (0)
|
||||
#define MICROPY_CPYTHON_COMPAT (0)
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
|
||||
|
||||
// type definitions for the specific machine
|
||||
|
||||
#define MP_ENDIANNESS_LITTLE (1)
|
||||
#define BYTES_PER_WORD (2)
|
||||
#define MPZ_DIG_SIZE (8)
|
||||
|
||||
// The xc16 compiler doesn't seem to respect alignment (!!) so we
|
||||
// need to use instead an object representation that allows for
|
||||
// 2-byte aligned pointers (see config setting above).
|
||||
//#define MICROPY_OBJ_BASE_ALIGNMENT __attribute__((aligned(4)))
|
||||
|
||||
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p)))
|
||||
|
||||
#define UINT_FMT "%u"
|
||||
#define INT_FMT "%d"
|
||||
typedef int mp_int_t; // must be pointer size
|
||||
typedef unsigned int mp_uint_t; // must be pointer size
|
||||
|
||||
typedef void *machine_ptr_t; // must be pointer size
|
||||
typedef const void *machine_const_ptr_t; // must be pointer size
|
||||
typedef int mp_off_t;
|
||||
|
||||
// extra builtin names to add to the global namespace
|
||||
extern const struct _mp_obj_fun_builtin_t mp_builtin_open_obj;
|
||||
#define MICROPY_PORT_BUILTINS \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
|
||||
|
||||
// extra builtin modules to add to the list of known ones
|
||||
extern const struct _mp_obj_module_t pyb_module;
|
||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pyb), (mp_obj_t)&pyb_module }, \
|
||||
|
||||
// We need to provide a declaration/definition of alloca()
|
||||
#define alloca(x) (void*)m_new(byte, (x))
|
||||
|
||||
#define MP_STATE_PORT MP_STATE_VM
|
||||
|
||||
#define MICROPY_PORT_ROOT_POINTERS \
|
||||
char *readline_hist[8]; \
|
||||
mp_obj_t keyboard_interrupt_obj; \
|
||||
|
||||
#define MICROPY_HAL_H "pic16bit_mphal.h"
|
||||
#define MICROPY_HW_BOARD_NAME "dsPICSK"
|
||||
#define MICROPY_HW_MCU_NAME "dsPIC33"
|
||||
79
pic16bit/pic16bit_mphal.c
Normal file
79
pic16bit/pic16bit_mphal.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "pic16bit_mphal.h"
|
||||
#include "board.h"
|
||||
|
||||
static int interrupt_char;
|
||||
|
||||
void mp_hal_init(void) {
|
||||
MP_STATE_PORT(keyboard_interrupt_obj) = mp_obj_new_exception(&mp_type_KeyboardInterrupt);
|
||||
}
|
||||
|
||||
mp_uint_t mp_hal_get_milliseconds(void) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mp_hal_milli_delay(mp_uint_t ms) {
|
||||
// tuned for fixed CPU frequency
|
||||
for (int i = ms; i > 0; i--) {
|
||||
for (volatile int j = 0; j < 5000; j++) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mp_hal_set_interrupt_char(int c) {
|
||||
interrupt_char = c;
|
||||
}
|
||||
|
||||
int mp_hal_stdin_rx_chr(void) {
|
||||
for (;;) {
|
||||
if (uart_rx_any()) {
|
||||
return uart_rx_char();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mp_hal_stdout_tx_str(const char *str) {
|
||||
mp_hal_stdout_tx_strn(str, strlen(str));
|
||||
}
|
||||
|
||||
void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
|
||||
for (; len > 0; --len) {
|
||||
uart_tx_char(*str++);
|
||||
}
|
||||
}
|
||||
|
||||
void mp_hal_stdout_tx_strn_cooked(const char *str, mp_uint_t len) {
|
||||
for (; len > 0; --len) {
|
||||
if (*str == '\n') {
|
||||
uart_tx_char('\r');
|
||||
}
|
||||
uart_tx_char(*str++);
|
||||
}
|
||||
}
|
||||
44
pic16bit/pic16bit_mphal.h
Normal file
44
pic16bit/pic16bit_mphal.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 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_PIC16BIT_PIC16BIT_MPHAL_H__
|
||||
#define __MICROPY_INCLUDED_PIC16BIT_PIC16BIT_MPHAL_H__
|
||||
|
||||
#define HAL_GetTick mp_hal_get_milliseconds
|
||||
|
||||
#include "py/mpstate.h"
|
||||
|
||||
void mp_hal_init(void);
|
||||
|
||||
mp_uint_t mp_hal_get_milliseconds(void);
|
||||
void mp_hal_milli_delay(mp_uint_t ms);
|
||||
|
||||
void mp_hal_set_interrupt_char(int c);
|
||||
int mp_hal_stdin_rx_chr(void);
|
||||
void mp_hal_stdout_tx_str(const char *str);
|
||||
void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len);
|
||||
void mp_hal_stdout_tx_strn_cooked(const char *str, mp_uint_t len);
|
||||
|
||||
#endif // __MICROPY_INCLUDED_PIC16BIT_PIC16BIT_MPHAL_H__
|
||||
15
pic16bit/qstrdefsport.h
Normal file
15
pic16bit/qstrdefsport.h
Normal file
@@ -0,0 +1,15 @@
|
||||
// qstrs specific to this port
|
||||
|
||||
Q(pyb)
|
||||
Q(millis)
|
||||
Q(elapsed_millis)
|
||||
Q(delay)
|
||||
Q(LED)
|
||||
Q(on)
|
||||
Q(off)
|
||||
Q(toggle)
|
||||
Q(Switch)
|
||||
Q(value)
|
||||
Q(readall)
|
||||
Q(readline)
|
||||
Q(FileIO)
|
||||
14
py/asmx64.c
14
py/asmx64.c
@@ -235,9 +235,15 @@ STATIC void asm_x64_write_word32_to(asm_x64_t *as, int offset, int w32) {
|
||||
*/
|
||||
|
||||
STATIC void asm_x64_write_r64_disp(asm_x64_t *as, int r64, int disp_r64, int disp_offset) {
|
||||
assert(disp_r64 < 8);
|
||||
assert(disp_r64 != ASM_X64_REG_RSP);
|
||||
|
||||
if (disp_r64 == ASM_X64_REG_R12) {
|
||||
// special case for r12; not fully implemented
|
||||
assert(SIGNED_FIT8(disp_offset));
|
||||
asm_x64_write_byte_3(as, MODRM_R64(r64) | MODRM_RM_DISP8 | MODRM_RM_R64(disp_r64), 0x24, IMM32_L0(disp_offset));
|
||||
return;
|
||||
}
|
||||
|
||||
if (disp_offset == 0 && disp_r64 != ASM_X64_REG_RBP) {
|
||||
asm_x64_write_byte_1(as, MODRM_R64(r64) | MODRM_RM_DISP0 | MODRM_RM_R64(disp_r64));
|
||||
} else if (SIGNED_FIT8(disp_offset)) {
|
||||
@@ -317,8 +323,7 @@ void asm_x64_mov_r16_to_mem16(asm_x64_t *as, int src_r64, int dest_r64, int dest
|
||||
|
||||
void asm_x64_mov_r64_to_mem64(asm_x64_t *as, int src_r64, int dest_r64, int dest_disp) {
|
||||
// use REX prefix for 64 bit operation
|
||||
assert(dest_r64 < 8);
|
||||
asm_x64_write_byte_2(as, REX_PREFIX | REX_W | (src_r64 < 8 ? 0 : REX_R), OPCODE_MOV_R64_TO_RM64);
|
||||
asm_x64_write_byte_2(as, REX_PREFIX | REX_W | (src_r64 < 8 ? 0 : REX_R) | (dest_r64 < 8 ? 0 : REX_B), OPCODE_MOV_R64_TO_RM64);
|
||||
asm_x64_write_r64_disp(as, src_r64, dest_r64, dest_disp);
|
||||
}
|
||||
|
||||
@@ -344,8 +349,7 @@ void asm_x64_mov_mem16_to_r64zx(asm_x64_t *as, int src_r64, int src_disp, int de
|
||||
|
||||
void asm_x64_mov_mem64_to_r64(asm_x64_t *as, int src_r64, int src_disp, int dest_r64) {
|
||||
// use REX prefix for 64 bit operation
|
||||
assert(src_r64 < 8);
|
||||
asm_x64_write_byte_2(as, REX_PREFIX | REX_W | (dest_r64 < 8 ? 0 : REX_R), OPCODE_MOV_RM64_TO_R64);
|
||||
asm_x64_write_byte_2(as, REX_PREFIX | REX_W | (dest_r64 < 8 ? 0 : REX_R) | (src_r64 < 8 ? 0 : REX_B), OPCODE_MOV_RM64_TO_R64);
|
||||
asm_x64_write_r64_disp(as, dest_r64, src_r64, src_disp);
|
||||
}
|
||||
|
||||
|
||||
3
py/bc.c
3
py/bc.c
@@ -86,6 +86,9 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t
|
||||
mp_obj_fun_bc_t *self = self_in;
|
||||
mp_uint_t n_state = code_state->n_state;
|
||||
|
||||
#if MICROPY_STACKLESS
|
||||
code_state->prev = NULL;
|
||||
#endif
|
||||
code_state->code_info = self->bytecode;
|
||||
code_state->sp = &code_state->state[0] - 1;
|
||||
code_state->exc_sp = (mp_exc_stack_t*)(code_state->state + n_state) - 1;
|
||||
|
||||
4
py/bc.h
4
py/bc.h
@@ -46,6 +46,9 @@ typedef struct _mp_code_state {
|
||||
// bit 0 is saved currently_in_except_block value
|
||||
mp_exc_stack_t *exc_sp;
|
||||
mp_obj_dict_t *old_globals;
|
||||
#if MICROPY_STACKLESS
|
||||
struct _mp_code_state *prev;
|
||||
#endif
|
||||
mp_uint_t n_state;
|
||||
// Variable-length
|
||||
mp_obj_t state[0];
|
||||
@@ -56,6 +59,7 @@ typedef struct _mp_code_state {
|
||||
mp_uint_t mp_decode_uint(const byte **ptr);
|
||||
|
||||
mp_vm_return_kind_t mp_execute_bytecode(mp_code_state *code_state, volatile mp_obj_t inject_exc);
|
||||
mp_code_state *mp_obj_fun_bc_prepare_codestate(mp_obj_t func, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args);
|
||||
void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args);
|
||||
void mp_bytecode_print(const void *descr, mp_uint_t n_total_args, const byte *code, mp_uint_t len);
|
||||
void mp_bytecode_print2(const byte *code, mp_uint_t len);
|
||||
|
||||
@@ -140,10 +140,12 @@
|
||||
#define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_x64_sub_r64_r64((as), (reg_dest), (reg_src))
|
||||
|
||||
#define ASM_LOAD_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem64_to_r64((as), (reg_base), 0, (reg_dest))
|
||||
#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_x64_mov_mem64_to_r64((as), (reg_base), 8 * (word_offset), (reg_dest))
|
||||
#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem8_to_r64zx((as), (reg_base), 0, (reg_dest))
|
||||
#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem16_to_r64zx((as), (reg_base), 0, (reg_dest))
|
||||
|
||||
#define ASM_STORE_REG_REG(as, reg_src, reg_base) asm_x64_mov_r64_to_mem64((as), (reg_src), (reg_base), 0)
|
||||
#define ASM_STORE_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) asm_x64_mov_r64_to_mem64((as), (reg_src), (reg_base), 8 * (word_offset))
|
||||
#define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_x64_mov_r8_to_mem8((as), (reg_src), (reg_base), 0)
|
||||
#define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_x64_mov_r16_to_mem16((as), (reg_src), (reg_base), 0)
|
||||
|
||||
@@ -197,6 +199,8 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = {
|
||||
[MP_F_UNPACK_EX] = 3,
|
||||
[MP_F_DELETE_NAME] = 1,
|
||||
[MP_F_DELETE_GLOBAL] = 1,
|
||||
[MP_F_NEW_CELL] = 1,
|
||||
[MP_F_MAKE_CLOSURE_FROM_RAW_CODE] = 3,
|
||||
};
|
||||
|
||||
#define EXPORT_FUN(name) emit_native_x86_##name
|
||||
@@ -270,10 +274,12 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = {
|
||||
#define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_x86_sub_r32_r32((as), (reg_dest), (reg_src))
|
||||
|
||||
#define ASM_LOAD_REG_REG(as, reg_dest, reg_base) asm_x86_mov_mem32_to_r32((as), (reg_base), 0, (reg_dest))
|
||||
#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_x86_mov_mem32_to_r32((as), (reg_base), 4 * (word_offset), (reg_dest))
|
||||
#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_x86_mov_mem8_to_r32zx((as), (reg_base), 0, (reg_dest))
|
||||
#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_x86_mov_mem16_to_r32zx((as), (reg_base), 0, (reg_dest))
|
||||
|
||||
#define ASM_STORE_REG_REG(as, reg_src, reg_base) asm_x86_mov_r32_to_mem32((as), (reg_src), (reg_base), 0)
|
||||
#define ASM_STORE_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) asm_x86_mov_r32_to_mem32((as), (reg_src), (reg_base), 4 * (word_offset))
|
||||
#define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_x86_mov_r8_to_mem8((as), (reg_src), (reg_base), 0)
|
||||
#define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_x86_mov_r16_to_mem16((as), (reg_src), (reg_base), 0)
|
||||
|
||||
@@ -353,10 +359,12 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = {
|
||||
#define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_thumb_sub_rlo_rlo_rlo((as), (reg_dest), (reg_dest), (reg_src))
|
||||
|
||||
#define ASM_LOAD_REG_REG(as, reg_dest, reg_base) asm_thumb_ldr_rlo_rlo_i5((as), (reg_dest), (reg_base), 0)
|
||||
#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_thumb_ldr_rlo_rlo_i5((as), (reg_dest), (reg_base), (word_offset))
|
||||
#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_thumb_ldrb_rlo_rlo_i5((as), (reg_dest), (reg_base), 0)
|
||||
#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_thumb_ldrh_rlo_rlo_i5((as), (reg_dest), (reg_base), 0)
|
||||
|
||||
#define ASM_STORE_REG_REG(as, reg_src, reg_base) asm_thumb_str_rlo_rlo_i5((as), (reg_src), (reg_base), 0)
|
||||
#define ASM_STORE_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) asm_thumb_str_rlo_rlo_i5((as), (reg_src), (reg_base), (word_offset))
|
||||
#define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_thumb_strb_rlo_rlo_i5((as), (reg_src), (reg_base), 0)
|
||||
#define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_thumb_strh_rlo_rlo_i5((as), (reg_src), (reg_base), 0)
|
||||
|
||||
@@ -547,6 +555,11 @@ STATIC void emit_native_set_native_type(emit_t *emit, mp_uint_t op, mp_uint_t ar
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void emit_pre_pop_reg(emit_t *emit, vtype_kind_t *vtype, int reg_dest);
|
||||
STATIC void emit_post_push_reg(emit_t *emit, vtype_kind_t vtype, int reg);
|
||||
STATIC void emit_native_load_fast(emit_t *emit, qstr qst, mp_uint_t local_num);
|
||||
STATIC void emit_native_store_fast(emit_t *emit, qstr qst, mp_uint_t local_num);
|
||||
|
||||
STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
|
||||
DEBUG_printf("start_pass(pass=%u, scope=%p)\n", pass, scope);
|
||||
|
||||
@@ -669,6 +682,21 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
|
||||
#else
|
||||
#error not implemented
|
||||
#endif
|
||||
|
||||
// initialise closed over variables
|
||||
for (int i = 0; i < scope->id_info_len; i++) {
|
||||
id_info_t *id = &scope->id_info[i];
|
||||
if (id->kind == ID_INFO_KIND_CELL) {
|
||||
if (emit->local_vtype[id->local_num] != VTYPE_UNBOUND) {
|
||||
emit_native_load_fast(emit, id->qst, id->local_num);
|
||||
vtype_kind_t vtype;
|
||||
emit_pre_pop_reg(emit, &vtype, REG_ARG_1);
|
||||
}
|
||||
ASM_CALL_IND(emit->as, mp_fun_table[MP_F_NEW_CELL], MP_F_NEW_CELL);
|
||||
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
|
||||
emit_native_store_fast(emit, id->qst, id->local_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void emit_native_end_pass(emit_t *emit) {
|
||||
@@ -1125,7 +1153,7 @@ STATIC void emit_native_load_const_small_int(emit_t *emit, mp_int_t arg) {
|
||||
if (emit->do_viper_types) {
|
||||
emit_post_push_imm(emit, VTYPE_INT, arg);
|
||||
} else {
|
||||
emit_post_push_imm(emit, VTYPE_PYOBJ, (arg << 1) | 1);
|
||||
emit_post_push_imm(emit, VTYPE_PYOBJ, (mp_uint_t)MP_OBJ_NEW_SMALL_INT(arg));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1224,12 +1252,15 @@ STATIC void emit_native_load_fast(emit_t *emit, qstr qst, mp_uint_t local_num) {
|
||||
}
|
||||
|
||||
STATIC void emit_native_load_deref(emit_t *emit, qstr qst, mp_uint_t local_num) {
|
||||
// not implemented
|
||||
// in principle could support this quite easily (ldr r0, [r0, #0]) and then get closed over variables!
|
||||
(void)emit;
|
||||
(void)qst;
|
||||
(void)local_num;
|
||||
assert(0);
|
||||
DEBUG_printf("load_deref(%s, " UINT_FMT ")\n", qstr_str(qst), local_num);
|
||||
need_reg_single(emit, REG_RET, 0);
|
||||
emit_native_load_fast(emit, qst, local_num);
|
||||
vtype_kind_t vtype;
|
||||
int reg_base = REG_RET;
|
||||
emit_pre_pop_reg_flexible(emit, &vtype, ®_base, -1, -1);
|
||||
ASM_LOAD_REG_REG_OFFSET(emit->as, REG_RET, reg_base, 1);
|
||||
// closed over vars are always Python objects
|
||||
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
|
||||
}
|
||||
|
||||
STATIC void emit_native_load_name(emit_t *emit, qstr qst) {
|
||||
@@ -1446,11 +1477,17 @@ STATIC void emit_native_store_fast(emit_t *emit, qstr qst, mp_uint_t local_num)
|
||||
}
|
||||
|
||||
STATIC void emit_native_store_deref(emit_t *emit, qstr qst, mp_uint_t local_num) {
|
||||
// not implemented
|
||||
(void)emit;
|
||||
(void)qst;
|
||||
(void)local_num;
|
||||
assert(0);
|
||||
DEBUG_printf("store_deref(%s, " UINT_FMT ")\n", qstr_str(qst), local_num);
|
||||
need_reg_single(emit, REG_TEMP0, 0);
|
||||
need_reg_single(emit, REG_TEMP1, 0);
|
||||
emit_native_load_fast(emit, qst, local_num);
|
||||
vtype_kind_t vtype;
|
||||
int reg_base = REG_TEMP0;
|
||||
emit_pre_pop_reg_flexible(emit, &vtype, ®_base, -1, -1);
|
||||
int reg_src = REG_TEMP1;
|
||||
emit_pre_pop_reg_flexible(emit, &vtype, ®_src, reg_base, reg_base);
|
||||
ASM_STORE_REG_REG_OFFSET(emit->as, reg_src, reg_base, 1);
|
||||
emit_post(emit);
|
||||
}
|
||||
|
||||
STATIC void emit_native_store_name(emit_t *emit, qstr qst) {
|
||||
@@ -1614,14 +1651,11 @@ STATIC void emit_native_store_subscr(emit_t *emit) {
|
||||
}
|
||||
|
||||
STATIC void emit_native_delete_fast(emit_t *emit, qstr qst, mp_uint_t local_num) {
|
||||
// TODO implement me!
|
||||
// could support for Python types, just set to None (so GC can reclaim it)
|
||||
// local is automatically deleted for exception block "as" var, and the message
|
||||
// breaks tests.
|
||||
//mp_emitter_warning(emit->pass, "Native codegeneration doesn't support deleting local");
|
||||
(void)emit;
|
||||
(void)qst;
|
||||
(void)local_num;
|
||||
// TODO: This is not compliant implementation. We could use MP_OBJ_SENTINEL
|
||||
// to mark deleted vars but then every var would need to be checked on
|
||||
// each access. Very inefficient, so just set value to None to enable GC.
|
||||
emit_native_load_const_tok(emit, MP_TOKEN_KW_NONE);
|
||||
emit_native_store_fast(emit, qst, local_num);
|
||||
}
|
||||
|
||||
STATIC void emit_native_delete_deref(emit_t *emit, qstr qst, mp_uint_t local_num) {
|
||||
@@ -2136,12 +2170,17 @@ STATIC void emit_native_make_function(emit_t *emit, scope_t *scope, mp_uint_t n_
|
||||
}
|
||||
|
||||
STATIC void emit_native_make_closure(emit_t *emit, scope_t *scope, mp_uint_t n_closed_over, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults) {
|
||||
(void)emit;
|
||||
(void)scope;
|
||||
(void)n_closed_over;
|
||||
(void)n_pos_defaults;
|
||||
(void)n_kw_defaults;
|
||||
assert(0);
|
||||
emit_native_pre(emit);
|
||||
if (n_pos_defaults == 0 && n_kw_defaults == 0) {
|
||||
emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_closed_over);
|
||||
ASM_MOV_IMM_TO_REG(emit->as, n_closed_over, REG_ARG_2);
|
||||
} else {
|
||||
emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_closed_over + 2);
|
||||
ASM_MOV_IMM_TO_REG(emit->as, 0x100 | n_closed_over, REG_ARG_2);
|
||||
}
|
||||
ASM_MOV_ALIGNED_IMM_TO_REG(emit->as, (mp_uint_t)scope->raw_code, REG_ARG_1);
|
||||
ASM_CALL_IND(emit->as, mp_fun_table[MP_F_MAKE_CLOSURE_FROM_RAW_CODE], MP_F_MAKE_CLOSURE_FROM_RAW_CODE);
|
||||
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
|
||||
}
|
||||
|
||||
STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
|
||||
|
||||
5
py/gc.c
5
py/gc.c
@@ -680,10 +680,11 @@ void gc_dump_alloc_table(void) {
|
||||
}
|
||||
}
|
||||
// print header for new line of blocks
|
||||
// (the cast to uint32_t is for 16-bit ports)
|
||||
#if EXTENSIVE_HEAP_PROFILING
|
||||
printf("\n%05x: ", (uint)(bl * BYTES_PER_BLOCK) & 0xfffff);
|
||||
printf("\n%05x: ", (uint)((bl * BYTES_PER_BLOCK) & (uint32_t)0xfffff));
|
||||
#else
|
||||
printf("\n%05x: ", (uint)PTR_FROM_BLOCK(bl) & 0xfffff);
|
||||
printf("\n%05x: ", (uint)(PTR_FROM_BLOCK(bl) & (uint32_t)0xfffff));
|
||||
#endif
|
||||
}
|
||||
int c = ' ';
|
||||
|
||||
@@ -29,6 +29,7 @@ codepoint2name[ord('{')] = 'brace_open'
|
||||
codepoint2name[ord('}')] = 'brace_close'
|
||||
codepoint2name[ord('*')] = 'star'
|
||||
codepoint2name[ord('!')] = 'bang'
|
||||
codepoint2name[ord('\\')] = 'backslash'
|
||||
|
||||
# this must match the equivalent function in qstr.c
|
||||
def compute_hash(qstr):
|
||||
@@ -87,7 +88,8 @@ def do_work(infiles):
|
||||
# go through each qstr and print it out
|
||||
for order, ident, qstr in sorted(qstrs.values(), key=lambda x: x[0]):
|
||||
qhash = compute_hash(qstr)
|
||||
qlen = len(qstr)
|
||||
# Calculate len of str, taking escapes into account
|
||||
qlen = len(qstr.replace("\\\\", "-").replace("\\", ""))
|
||||
qdata = qstr.replace('"', '\\"')
|
||||
if qlen >= cfg_max_len:
|
||||
print('qstr is too long:', qstr)
|
||||
|
||||
2
py/map.c
2
py/map.c
@@ -136,7 +136,7 @@ STATIC void mp_map_rehash(mp_map_t *map) {
|
||||
// - returns slot, with key non-null and value=MP_OBJ_NULL if it was added
|
||||
// MP_MAP_LOOKUP_REMOVE_IF_FOUND behaviour:
|
||||
// - returns NULL if not found, else the slot if was found in with key null and value non-null
|
||||
mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind) {
|
||||
mp_map_elem_t *mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind) {
|
||||
|
||||
// Work out if we can compare just pointers
|
||||
bool compare_only_ptrs = map->all_keys_are_qstrs;
|
||||
|
||||
@@ -465,12 +465,20 @@ STATIC mp_obj_t mp_builtin_repr(mp_obj_t o_in) {
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_repr_obj, mp_builtin_repr);
|
||||
|
||||
STATIC mp_obj_t mp_builtin_round(mp_obj_t o_in) {
|
||||
// TODO support second arg
|
||||
STATIC mp_obj_t mp_builtin_round(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
// TODO really support second arg
|
||||
mp_obj_t o_in = args[0];
|
||||
if (MP_OBJ_IS_INT(o_in)) {
|
||||
return o_in;
|
||||
}
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
mp_int_t num_dig = 0;
|
||||
if (n_args > 1) {
|
||||
num_dig = mp_obj_get_int(args[1]);
|
||||
if (num_dig > 0) {
|
||||
mp_not_implemented("round(..., N>0)");
|
||||
}
|
||||
}
|
||||
mp_float_t val = mp_obj_get_float(o_in);
|
||||
mp_float_t rounded = MICROPY_FLOAT_C_FUN(round)(val);
|
||||
mp_int_t r = rounded;
|
||||
@@ -480,12 +488,15 @@ STATIC mp_obj_t mp_builtin_round(mp_obj_t o_in) {
|
||||
} else if (val - rounded == -0.5) {
|
||||
r &= ~1;
|
||||
}
|
||||
if (n_args > 1) {
|
||||
return mp_obj_new_float(r);
|
||||
}
|
||||
#else
|
||||
mp_int_t r = mp_obj_get_int(o_in);
|
||||
#endif
|
||||
return mp_obj_new_int(r);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_round_obj, mp_builtin_round);
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_round_obj, 1, 2, mp_builtin_round);
|
||||
|
||||
STATIC mp_obj_t mp_builtin_sum(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
assert(1 <= n_args && n_args <= 2);
|
||||
|
||||
@@ -48,6 +48,25 @@
|
||||
// Any options not explicitly set in mpconfigport.h will get default
|
||||
// values below.
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Object representation */
|
||||
|
||||
// A Micro Python object is a machine word having the following form:
|
||||
// - xxxx...xxx1 : a small int, bits 1 and above are the value
|
||||
// - xxxx...xx10 : a qstr, bits 2 and above are the value
|
||||
// - xxxx...xx00 : a pointer to an mp_obj_base_t (unless a fake object)
|
||||
#define MICROPY_OBJ_REPR_A (0)
|
||||
|
||||
// A Micro Python object is a machine word having the following form:
|
||||
// - xxxx...xx01 : a small int, bits 2 and above are the value
|
||||
// - xxxx...xx11 : a qstr, bits 2 and above are the value
|
||||
// - xxxx...xxx0 : a pointer to an mp_obj_base_t (unless a fake object)
|
||||
#define MICROPY_OBJ_REPR_B (1)
|
||||
|
||||
#ifndef MICROPY_OBJ_REPR
|
||||
#define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_A)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Memory allocation policy */
|
||||
|
||||
@@ -125,6 +144,19 @@
|
||||
#define MICROPY_QSTR_BYTES_IN_LEN (1)
|
||||
#endif
|
||||
|
||||
// Avoid using C stack when making Python function calls. C stack still
|
||||
// may be used if there's no free heap.
|
||||
#ifndef MICROPY_STACKLESS
|
||||
#define MICROPY_STACKLESS (0)
|
||||
#endif
|
||||
|
||||
// Never use C stack when making Python function calls. This may break
|
||||
// testsuite as will subtly change which exception is thrown in case
|
||||
// of too deep recursion and other similar cases.
|
||||
#ifndef MICROPY_STACKLESS_STRICT
|
||||
#define MICROPY_STACKLESS_STRICT (0)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Micro Python emitters */
|
||||
|
||||
@@ -375,6 +407,11 @@ typedef double mp_float_t;
|
||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (0)
|
||||
#endif
|
||||
|
||||
// Whether str.splitlines() method provided
|
||||
#ifndef MICROPY_PY_BUILTINS_STR_SPLITLINES
|
||||
#define MICROPY_PY_BUILTINS_STR_SPLITLINES (0)
|
||||
#endif
|
||||
|
||||
// Whether to support bytearray object
|
||||
#ifndef MICROPY_PY_BUILTINS_BYTEARRAY
|
||||
#define MICROPY_PY_BUILTINS_BYTEARRAY (1)
|
||||
|
||||
33
py/mpz.h
33
py/mpz.h
@@ -39,22 +39,37 @@
|
||||
// unsigned versions.
|
||||
//
|
||||
// MPZ_DIG_SIZE can be between 4 and 8*sizeof(mpz_dig_t), but it makes most
|
||||
// sense to have it as large as possible. Below, the type is auto-detected
|
||||
// depending on the machine, but it (and MPZ_DIG_SIZE) can be freely changed so
|
||||
// long as the constraints mentioned above are met.
|
||||
// sense to have it as large as possible. If MPZ_DIG_SIZE is not already
|
||||
// defined then it is auto-detected below, depending on the machine. The types
|
||||
// are then set based on the value of MPZ_DIG_SIZE (although they can be freely
|
||||
// changed so long as the constraints mentioned above are met).
|
||||
|
||||
#if defined(__x86_64__) || defined(_WIN64)
|
||||
// 64-bit machine, using 32-bit storage for digits
|
||||
#ifndef MPZ_DIG_SIZE
|
||||
#if defined(__x86_64__) || defined(_WIN64)
|
||||
// 64-bit machine, using 32-bit storage for digits
|
||||
#define MPZ_DIG_SIZE (32)
|
||||
#else
|
||||
// default: 32-bit machine, using 16-bit storage for digits
|
||||
#define MPZ_DIG_SIZE (16)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if MPZ_DIG_SIZE > 16
|
||||
typedef uint32_t mpz_dig_t;
|
||||
typedef uint64_t mpz_dbl_dig_t;
|
||||
typedef int64_t mpz_dbl_dig_signed_t;
|
||||
#define MPZ_DIG_SIZE (32)
|
||||
#else
|
||||
// 32-bit machine, using 16-bit storage for digits
|
||||
#elif MPZ_DIG_SIZE > 8
|
||||
typedef uint16_t mpz_dig_t;
|
||||
typedef uint32_t mpz_dbl_dig_t;
|
||||
typedef int32_t mpz_dbl_dig_signed_t;
|
||||
#define MPZ_DIG_SIZE (16)
|
||||
#elif MPZ_DIG_SIZE > 4
|
||||
typedef uint8_t mpz_dig_t;
|
||||
typedef uint16_t mpz_dbl_dig_t;
|
||||
typedef int16_t mpz_dbl_dig_signed_t;
|
||||
#else
|
||||
typedef uint8_t mpz_dig_t;
|
||||
typedef uint8_t mpz_dbl_dig_t;
|
||||
typedef int8_t mpz_dbl_dig_signed_t;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
@@ -132,6 +132,8 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = {
|
||||
mp_unpack_ex,
|
||||
mp_delete_name,
|
||||
mp_delete_global,
|
||||
mp_obj_new_cell,
|
||||
mp_make_closure_from_raw_code,
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
77
py/obj.h
77
py/obj.h
@@ -30,11 +30,6 @@
|
||||
#include "py/misc.h"
|
||||
#include "py/qstr.h"
|
||||
|
||||
// A Micro Python object is a machine word having the following form:
|
||||
// - xxxx...xxx1 : a small int, bits 1 and above are the value
|
||||
// - xxxx...xx10 : a qstr, bits 2 and above are the value
|
||||
// - xxxx...xx00 : a pointer to an mp_obj_base_t (unless a fake object)
|
||||
|
||||
// All Micro Python objects are at least this type
|
||||
// It must be of pointer size
|
||||
|
||||
@@ -71,24 +66,42 @@ typedef struct _mp_obj_base_t mp_obj_base_t;
|
||||
#define MP_OBJ_SENTINEL ((mp_obj_t)8)
|
||||
#endif
|
||||
|
||||
// These macros check for small int, qstr or object, and access small int and qstr values
|
||||
// These macros/inline functions operate on objects and depend on the
|
||||
// particular object representation. They are used to query, pack and
|
||||
// unpack small ints, qstrs and full object pointers.
|
||||
|
||||
// these macros have now become inline functions; see below
|
||||
//#define MP_OBJ_IS_SMALL_INT(o) ((((mp_int_t)(o)) & 1) != 0)
|
||||
//#define MP_OBJ_IS_QSTR(o) ((((mp_int_t)(o)) & 3) == 2)
|
||||
//#define MP_OBJ_IS_OBJ(o) ((((mp_int_t)(o)) & 3) == 0)
|
||||
#define MP_OBJ_IS_TYPE(o, t) (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t*)(o))->type == (t))) // this does not work for checking int, str or fun; use below macros for that
|
||||
#define MP_OBJ_IS_INT(o) (MP_OBJ_IS_SMALL_INT(o) || MP_OBJ_IS_TYPE(o, &mp_type_int))
|
||||
#define MP_OBJ_IS_STR(o) (MP_OBJ_IS_QSTR(o) || MP_OBJ_IS_TYPE(o, &mp_type_str))
|
||||
#define MP_OBJ_IS_STR_OR_BYTES(o) (MP_OBJ_IS_QSTR(o) || (MP_OBJ_IS_OBJ(o) && ((mp_obj_base_t*)(o))->type->binary_op == mp_obj_str_binary_op))
|
||||
#define MP_OBJ_IS_FUN(o) (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t*)(o))->type->name == MP_QSTR_function))
|
||||
#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A
|
||||
|
||||
static inline bool MP_OBJ_IS_SMALL_INT(mp_const_obj_t o)
|
||||
{ return ((((mp_int_t)(o)) & 1) != 0); }
|
||||
#define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)(o)) >> 1)
|
||||
#define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)((((mp_int_t)(small_int)) << 1) | 1))
|
||||
|
||||
static inline bool MP_OBJ_IS_QSTR(mp_const_obj_t o)
|
||||
{ return ((((mp_int_t)(o)) & 3) == 2); }
|
||||
#define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 2)
|
||||
#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 2) | 2))
|
||||
|
||||
static inline bool MP_OBJ_IS_OBJ(mp_const_obj_t o)
|
||||
{ return ((((mp_int_t)(o)) & 3) == 0); }
|
||||
|
||||
#elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B
|
||||
|
||||
static inline bool MP_OBJ_IS_SMALL_INT(mp_const_obj_t o)
|
||||
{ return ((((mp_int_t)(o)) & 3) == 1); }
|
||||
#define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)(o)) >> 2)
|
||||
#define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)((((mp_int_t)(small_int)) << 2) | 1))
|
||||
|
||||
static inline bool MP_OBJ_IS_QSTR(mp_const_obj_t o)
|
||||
{ return ((((mp_int_t)(o)) & 3) == 3); }
|
||||
#define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 2)
|
||||
#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 2) | 3))
|
||||
|
||||
static inline bool MP_OBJ_IS_OBJ(mp_const_obj_t o)
|
||||
{ return ((((mp_int_t)(o)) & 1) == 0); }
|
||||
|
||||
#endif
|
||||
|
||||
// Macros to convert between mp_obj_t and concrete object types.
|
||||
// These are identity operations in MicroPython, but ability to override
|
||||
// these operations are provided to experiment with other methods of
|
||||
@@ -104,6 +117,26 @@ typedef struct _mp_obj_base_t mp_obj_base_t;
|
||||
#define MP_OBJ_UNCAST(p) ((mp_obj_t)p)
|
||||
#endif
|
||||
|
||||
// The macros below are derived from the ones above and are used to
|
||||
// check for more specific object types.
|
||||
|
||||
#define MP_OBJ_IS_TYPE(o, t) (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t*)(o))->type == (t))) // this does not work for checking int, str or fun; use below macros for that
|
||||
#define MP_OBJ_IS_INT(o) (MP_OBJ_IS_SMALL_INT(o) || MP_OBJ_IS_TYPE(o, &mp_type_int))
|
||||
#define MP_OBJ_IS_STR(o) (MP_OBJ_IS_QSTR(o) || MP_OBJ_IS_TYPE(o, &mp_type_str))
|
||||
#define MP_OBJ_IS_STR_OR_BYTES(o) (MP_OBJ_IS_QSTR(o) || (MP_OBJ_IS_OBJ(o) && ((mp_obj_base_t*)(o))->type->binary_op == mp_obj_str_binary_op))
|
||||
#define MP_OBJ_IS_FUN(o) (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t*)(o))->type->name == MP_QSTR_function))
|
||||
|
||||
// Note: inline functions sometimes use much more code space than the
|
||||
// equivalent macros, depending on the compiler.
|
||||
//static inline bool MP_OBJ_IS_TYPE(mp_const_obj_t o, const mp_obj_type_t *t) { return (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t*)(o))->type == (t))); } // this does not work for checking a string, use below macro for that
|
||||
//static inline bool MP_OBJ_IS_INT(mp_const_obj_t o) { return (MP_OBJ_IS_SMALL_INT(o) || MP_OBJ_IS_TYPE(o, &mp_type_int)); } // returns true if o is a small int or long int
|
||||
// Need to forward declare these for the inline function to compile.
|
||||
extern const struct _mp_obj_type_t mp_type_int;
|
||||
extern const struct _mp_obj_type_t mp_type_bool;
|
||||
static inline bool mp_obj_is_integer(mp_const_obj_t o) { return MP_OBJ_IS_INT(o) || MP_OBJ_IS_TYPE(o, &mp_type_bool); } // returns true if o is bool, small int or long int
|
||||
//static inline bool MP_OBJ_IS_STR(mp_const_obj_t o) { return (MP_OBJ_IS_QSTR(o) || MP_OBJ_IS_TYPE(o, &mp_type_str)); }
|
||||
|
||||
|
||||
// These macros are used to declare and define constant function objects
|
||||
// You can put "static" in front of the definitions to make them local
|
||||
|
||||
@@ -191,7 +224,7 @@ void mp_map_init_fixed_table(mp_map_t *map, mp_uint_t n, const mp_obj_t *table);
|
||||
mp_map_t *mp_map_new(mp_uint_t n);
|
||||
void mp_map_deinit(mp_map_t *map);
|
||||
void mp_map_free(mp_map_t *map);
|
||||
mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind);
|
||||
mp_map_elem_t *mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind);
|
||||
void mp_map_clear(mp_map_t *map);
|
||||
void mp_map_dump(mp_map_t *map);
|
||||
|
||||
@@ -462,16 +495,6 @@ void mp_obj_print(mp_obj_t o, mp_print_kind_t kind);
|
||||
void mp_obj_print_exception(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t exc);
|
||||
|
||||
bool mp_obj_is_true(mp_obj_t arg);
|
||||
|
||||
// TODO make these all lower case when they have proven themselves
|
||||
static inline bool MP_OBJ_IS_OBJ(mp_const_obj_t o) { return ((((mp_int_t)(o)) & 3) == 0); }
|
||||
static inline bool MP_OBJ_IS_SMALL_INT(mp_const_obj_t o) { return ((((mp_int_t)(o)) & 1) != 0); }
|
||||
//static inline bool MP_OBJ_IS_TYPE(mp_const_obj_t o, const mp_obj_type_t *t) { return (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t*)(o))->type == (t))); } // this does not work for checking a string, use below macro for that
|
||||
//static inline bool MP_OBJ_IS_INT(mp_const_obj_t o) { return (MP_OBJ_IS_SMALL_INT(o) || MP_OBJ_IS_TYPE(o, &mp_type_int)); } // returns true if o is a small int or long int
|
||||
static inline bool mp_obj_is_integer(mp_const_obj_t o) { return MP_OBJ_IS_INT(o) || MP_OBJ_IS_TYPE(o, &mp_type_bool); } // returns true if o is bool, small int or long int
|
||||
static inline bool MP_OBJ_IS_QSTR(mp_const_obj_t o) { return ((((mp_int_t)(o)) & 3) == 2); }
|
||||
//static inline bool MP_OBJ_IS_STR(mp_const_obj_t o) { return (MP_OBJ_IS_QSTR(o) || MP_OBJ_IS_TYPE(o, &mp_type_str)); }
|
||||
|
||||
bool mp_obj_is_callable(mp_obj_t o_in);
|
||||
mp_int_t mp_obj_hash(mp_obj_t o_in);
|
||||
bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2);
|
||||
@@ -488,7 +511,7 @@ void mp_obj_get_array_fixed_n(mp_obj_t o, mp_uint_t len, mp_obj_t **items);
|
||||
mp_uint_t mp_get_index(const mp_obj_type_t *type, mp_uint_t len, mp_obj_t index, bool is_slice);
|
||||
mp_obj_t mp_obj_id(mp_obj_t o_in);
|
||||
mp_obj_t mp_obj_len(mp_obj_t o_in);
|
||||
mp_obj_t mp_obj_len_maybe(mp_obj_t o_in); /* may return MP_OBJ_NULL */
|
||||
mp_obj_t mp_obj_len_maybe(mp_obj_t o_in); // may return MP_OBJ_NULL
|
||||
mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t val);
|
||||
|
||||
// bool
|
||||
|
||||
@@ -79,7 +79,7 @@ STATIC void bound_meth_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
}
|
||||
#endif
|
||||
|
||||
const mp_obj_type_t bound_meth_type = {
|
||||
STATIC const mp_obj_type_t mp_type_bound_meth = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_bound_method,
|
||||
#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED
|
||||
@@ -93,7 +93,7 @@ const mp_obj_type_t bound_meth_type = {
|
||||
|
||||
mp_obj_t mp_obj_new_bound_meth(mp_obj_t meth, mp_obj_t self) {
|
||||
mp_obj_bound_meth_t *o = m_new_obj(mp_obj_bound_meth_t);
|
||||
o->base.type = &bound_meth_type;
|
||||
o->base.type = &mp_type_bound_meth;
|
||||
o->meth = meth;
|
||||
o->self = self;
|
||||
return o;
|
||||
|
||||
@@ -55,7 +55,7 @@ STATIC void cell_print(void (*print)(void *env, const char *fmt, ...), void *env
|
||||
}
|
||||
#endif
|
||||
|
||||
const mp_obj_type_t cell_type = {
|
||||
STATIC const mp_obj_type_t mp_type_cell = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_, // cell representation is just value in < >
|
||||
#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED
|
||||
@@ -65,7 +65,7 @@ const mp_obj_type_t cell_type = {
|
||||
|
||||
mp_obj_t mp_obj_new_cell(mp_obj_t obj) {
|
||||
mp_obj_cell_t *o = m_new_obj(mp_obj_cell_t);
|
||||
o->base.type = &cell_type;
|
||||
o->base.type = &mp_type_cell;
|
||||
o->obj = obj;
|
||||
return o;
|
||||
}
|
||||
|
||||
37
py/objfun.c
37
py/objfun.c
@@ -142,6 +142,43 @@ STATIC void dump_args(const mp_obj_t *a, mp_uint_t sz) {
|
||||
// Set this to enable a simple stack overflow check.
|
||||
#define VM_DETECT_STACK_OVERFLOW (0)
|
||||
|
||||
#if MICROPY_STACKLESS
|
||||
mp_code_state *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
MP_STACK_CHECK();
|
||||
mp_obj_fun_bc_t *self = self_in;
|
||||
|
||||
// skip code-info block
|
||||
const byte *code_info = self->bytecode;
|
||||
mp_uint_t code_info_size = mp_decode_uint(&code_info);
|
||||
const byte *ip = self->bytecode + code_info_size;
|
||||
|
||||
// bytecode prelude: skip arg names
|
||||
ip += (self->n_pos_args + self->n_kwonly_args) * sizeof(mp_obj_t);
|
||||
|
||||
// bytecode prelude: state size and exception stack size
|
||||
mp_uint_t n_state = mp_decode_uint(&ip);
|
||||
mp_uint_t n_exc_stack = mp_decode_uint(&ip);
|
||||
|
||||
// allocate state for locals and stack
|
||||
mp_uint_t state_size = n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t);
|
||||
mp_code_state *code_state;
|
||||
code_state = m_new_obj_var_maybe(mp_code_state, byte, state_size);
|
||||
if (!code_state) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
code_state->n_state = n_state;
|
||||
code_state->ip = ip;
|
||||
mp_setup_code_state(code_state, self_in, n_args, n_kw, args);
|
||||
|
||||
// execute the byte code with the correct globals context
|
||||
code_state->old_globals = mp_globals_get();
|
||||
mp_globals_set(self->globals);
|
||||
|
||||
return code_state;
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
MP_STACK_CHECK();
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ STATIC const mp_obj_type_t it_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_iterator,
|
||||
.getiter = mp_identity,
|
||||
.iternext = it_iternext
|
||||
.iternext = it_iternext,
|
||||
};
|
||||
|
||||
// args are those returned from mp_load_method_maybe (ie either an attribute or a method)
|
||||
|
||||
48
py/objstr.c
48
py/objstr.c
@@ -455,8 +455,9 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
|
||||
}
|
||||
|
||||
#define is_ws(c) ((c) == ' ' || (c) == '\t')
|
||||
enum {SPLIT = 0, KEEP = 1, SPLITLINES = 2};
|
||||
|
||||
mp_obj_t mp_obj_str_split(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
STATIC inline mp_obj_t str_split_internal(mp_uint_t n_args, const mp_obj_t *args, int type) {
|
||||
const mp_obj_type_t *self_type = mp_obj_get_type(args[0]);
|
||||
mp_int_t splits = -1;
|
||||
mp_obj_t sep = mp_const_none;
|
||||
@@ -517,7 +518,13 @@ mp_obj_t mp_obj_str_split(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
}
|
||||
s++;
|
||||
}
|
||||
mp_obj_list_append(res, mp_obj_new_str_of_type(self_type, start, s - start));
|
||||
mp_uint_t sub_len = s - start;
|
||||
if (MP_LIKELY(!(sub_len == 0 && s == top && (type && SPLITLINES)))) {
|
||||
if (start + sub_len != top && (type & KEEP)) {
|
||||
sub_len++;
|
||||
}
|
||||
mp_obj_list_append(res, mp_obj_new_str_of_type(self_type, start, sub_len));
|
||||
}
|
||||
if (s >= top) {
|
||||
break;
|
||||
}
|
||||
@@ -531,6 +538,25 @@ mp_obj_t mp_obj_str_split(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
return res;
|
||||
}
|
||||
|
||||
mp_obj_t mp_obj_str_split(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
return str_split_internal(n_args, args, SPLIT);
|
||||
}
|
||||
|
||||
#if MICROPY_PY_BUILTINS_STR_SPLITLINES
|
||||
STATIC mp_obj_t str_splitlines(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_keepends, MP_ARG_BOOL, {.u_bool = false} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
mp_obj_t new_args[2] = {pos_args[0], MP_OBJ_NEW_QSTR(MP_QSTR__backslash_n)};
|
||||
return str_split_internal(2, new_args, SPLITLINES | (args[0].u_bool ? KEEP : 0));
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC mp_obj_t str_rsplit(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
if (n_args < 3) {
|
||||
// If we don't have split limit, it doesn't matter from which side
|
||||
@@ -763,7 +789,7 @@ STATIC mp_obj_t str_rstrip(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
|
||||
// Takes an int arg, but only parses unsigned numbers, and only changes
|
||||
// *num if at least one digit was parsed.
|
||||
static int str_to_int(const char *str, int *num) {
|
||||
STATIC int str_to_int(const char *str, int *num) {
|
||||
const char *s = str;
|
||||
if ('0' <= *s && *s <= '9') {
|
||||
*num = 0;
|
||||
@@ -776,19 +802,19 @@ static int str_to_int(const char *str, int *num) {
|
||||
return s - str;
|
||||
}
|
||||
|
||||
static bool isalignment(char ch) {
|
||||
STATIC bool isalignment(char ch) {
|
||||
return ch && strchr("<>=^", ch) != NULL;
|
||||
}
|
||||
|
||||
static bool istype(char ch) {
|
||||
STATIC bool istype(char ch) {
|
||||
return ch && strchr("bcdeEfFgGnosxX%", ch) != NULL;
|
||||
}
|
||||
|
||||
static bool arg_looks_integer(mp_obj_t arg) {
|
||||
STATIC bool arg_looks_integer(mp_obj_t arg) {
|
||||
return MP_OBJ_IS_TYPE(arg, &mp_type_bool) || MP_OBJ_IS_INT(arg);
|
||||
}
|
||||
|
||||
static bool arg_looks_numeric(mp_obj_t arg) {
|
||||
STATIC bool arg_looks_numeric(mp_obj_t arg) {
|
||||
return arg_looks_integer(arg)
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
|| MP_OBJ_IS_TYPE(arg, &mp_type_float)
|
||||
@@ -796,7 +822,7 @@ static bool arg_looks_numeric(mp_obj_t arg) {
|
||||
;
|
||||
}
|
||||
|
||||
static mp_obj_t arg_as_int(mp_obj_t arg) {
|
||||
STATIC mp_obj_t arg_as_int(mp_obj_t arg) {
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
if (MP_OBJ_IS_TYPE(arg, &mp_type_float)) {
|
||||
return mp_obj_new_int_from_float(mp_obj_get_float(arg));
|
||||
@@ -1763,6 +1789,9 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_index_obj, 2, 4, str_index);
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rindex_obj, 2, 4, str_rindex);
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(str_join_obj, str_join);
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_split_obj, 1, 3, mp_obj_str_split);
|
||||
#if MICROPY_PY_BUILTINS_STR_SPLITLINES
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(str_splitlines_obj, 1, str_splitlines);
|
||||
#endif
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rsplit_obj, 1, 3, str_rsplit);
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_startswith_obj, 2, 3, str_startswith);
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_endswith_obj, 2, 3, str_endswith);
|
||||
@@ -1800,6 +1829,9 @@ STATIC const mp_map_elem_t str8_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rindex), (mp_obj_t)&str_rindex_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_join), (mp_obj_t)&str_join_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_split), (mp_obj_t)&str_split_obj },
|
||||
#if MICROPY_PY_BUILTINS_STR_SPLITLINES
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_splitlines), (mp_obj_t)&str_splitlines_obj },
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rsplit), (mp_obj_t)&str_rsplit_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_startswith), (mp_obj_t)&str_startswith_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_endswith), (mp_obj_t)&str_endswith_obj },
|
||||
|
||||
@@ -73,6 +73,7 @@ MP_DECLARE_CONST_FUN_OBJ(str_index_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(str_rindex_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(str_join_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(str_split_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(str_splitlines_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(str_rsplit_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(str_startswith_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(str_endswith_obj);
|
||||
|
||||
@@ -245,6 +245,9 @@ STATIC const mp_map_elem_t struni_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rindex), (mp_obj_t)&str_rindex_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_join), (mp_obj_t)&str_join_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_split), (mp_obj_t)&str_split_obj },
|
||||
#if MICROPY_PY_BUILTINS_STR_SPLITLINES
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_splitlines), (mp_obj_t)&str_splitlines_obj },
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rsplit), (mp_obj_t)&str_rsplit_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_startswith), (mp_obj_t)&str_startswith_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_endswith), (mp_obj_t)&str_endswith_obj },
|
||||
|
||||
12
py/objtype.c
12
py/objtype.c
@@ -330,9 +330,11 @@ mp_obj_t instance_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, c
|
||||
const qstr mp_unary_op_method_name[] = {
|
||||
[MP_UNARY_OP_BOOL] = MP_QSTR___bool__,
|
||||
[MP_UNARY_OP_LEN] = MP_QSTR___len__,
|
||||
//[MP_UNARY_OP_POSITIVE,
|
||||
//[MP_UNARY_OP_NEGATIVE,
|
||||
//[MP_UNARY_OP_INVERT,
|
||||
#if MICROPY_PY_ALL_SPECIAL_METHODS
|
||||
[MP_UNARY_OP_POSITIVE] = MP_QSTR___pos__,
|
||||
[MP_UNARY_OP_NEGATIVE] = MP_QSTR___neg__,
|
||||
[MP_UNARY_OP_INVERT] = MP_QSTR___invert__,
|
||||
#endif
|
||||
[MP_UNARY_OP_NOT] = MP_QSTR_, // don't need to implement this, used to make sure array has full size
|
||||
};
|
||||
|
||||
@@ -1049,11 +1051,11 @@ STATIC mp_obj_t static_class_method_make_new(mp_obj_t self_in, mp_uint_t n_args,
|
||||
const mp_obj_type_t mp_type_staticmethod = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_staticmethod,
|
||||
.make_new = static_class_method_make_new
|
||||
.make_new = static_class_method_make_new,
|
||||
};
|
||||
|
||||
const mp_obj_type_t mp_type_classmethod = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_classmethod,
|
||||
.make_new = static_class_method_make_new
|
||||
.make_new = static_class_method_make_new,
|
||||
};
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
static const char pad_spaces[] = " ";
|
||||
static const char pad_zeroes[] = "0000000000000000";
|
||||
|
||||
void pfenv_vstr_add_strn(void *data, const char *str, mp_uint_t len){
|
||||
void pfenv_vstr_add_strn(void *data, const char *str, mp_uint_t len) {
|
||||
vstr_add_strn(data, str, len);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,9 +67,9 @@ byte* qstr_build_start(mp_uint_t len, byte **q_ptr);
|
||||
qstr qstr_build_end(byte *q_ptr);
|
||||
|
||||
mp_uint_t qstr_hash(qstr q);
|
||||
const char* qstr_str(qstr q);
|
||||
const char *qstr_str(qstr q);
|
||||
mp_uint_t qstr_len(qstr q);
|
||||
const byte* qstr_data(qstr q, mp_uint_t *len);
|
||||
const byte *qstr_data(qstr q, mp_uint_t *len);
|
||||
|
||||
void qstr_pool_info(mp_uint_t *n_pool, mp_uint_t *n_qstr, mp_uint_t *n_str_data_bytes, mp_uint_t *n_total_bytes);
|
||||
void qstr_dump_data(void);
|
||||
|
||||
@@ -85,6 +85,9 @@ Q(__truediv__)
|
||||
Q(__floordiv__)
|
||||
Q(__iadd__)
|
||||
Q(__isub__)
|
||||
Q(__invert__)
|
||||
Q(__neg__)
|
||||
Q(__pos__)
|
||||
#endif
|
||||
|
||||
Q(micropython)
|
||||
@@ -296,6 +299,11 @@ Q(find)
|
||||
Q(rfind)
|
||||
Q(rindex)
|
||||
Q(split)
|
||||
#if MICROPY_PY_BUILTINS_STR_SPLITLINES
|
||||
Q(splitlines)
|
||||
Q(keepends)
|
||||
Q(\n)
|
||||
#endif
|
||||
Q(rsplit)
|
||||
Q(startswith)
|
||||
Q(endswith)
|
||||
|
||||
21
py/runtime.c
21
py/runtime.c
@@ -577,7 +577,11 @@ mp_obj_t mp_call_method_n_kw(mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *a
|
||||
return mp_call_function_n_kw(args[0], n_args + adjust, n_kw, args + 2 - adjust);
|
||||
}
|
||||
|
||||
mp_obj_t mp_call_method_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const mp_obj_t *args) {
|
||||
// This function only needs to be exposed externally when in stackless mode.
|
||||
#if !MICROPY_STACKLESS
|
||||
STATIC
|
||||
#endif
|
||||
void mp_call_prepare_args_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const mp_obj_t *args, mp_call_args_t *out_args) {
|
||||
mp_obj_t fun = *args++;
|
||||
mp_obj_t self = MP_OBJ_NULL;
|
||||
if (have_self) {
|
||||
@@ -715,8 +719,19 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const mp
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_t res = mp_call_function_n_kw(fun, pos_args_len, (args2_len - pos_args_len) / 2, args2);
|
||||
m_del(mp_obj_t, args2, args2_alloc);
|
||||
out_args->fun = fun;
|
||||
out_args->args = args2;
|
||||
out_args->n_args = pos_args_len;
|
||||
out_args->n_kw = (args2_len - pos_args_len) / 2;
|
||||
out_args->n_alloc = args2_alloc;
|
||||
}
|
||||
|
||||
mp_obj_t mp_call_method_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const mp_obj_t *args) {
|
||||
mp_call_args_t out_args;
|
||||
mp_call_prepare_args_n_kw_var(have_self, n_args_n_kw, args, &out_args);
|
||||
|
||||
mp_obj_t res = mp_call_function_n_kw(out_args.fun, out_args.n_args, out_args.n_kw, out_args.args);
|
||||
m_del(mp_obj_t, out_args.args, out_args.n_alloc);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
15
py/runtime.h
15
py/runtime.h
@@ -97,6 +97,20 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun, mp_uint_t n_args, mp_uint_t n_kw, c
|
||||
mp_obj_t mp_call_method_n_kw(mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args);
|
||||
mp_obj_t mp_call_method_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const mp_obj_t *args);
|
||||
|
||||
typedef struct _mp_call_args_t {
|
||||
mp_obj_t fun;
|
||||
mp_uint_t n_args, n_kw, n_alloc;
|
||||
mp_obj_t *args;
|
||||
} mp_call_args_t;
|
||||
|
||||
#if MICROPY_STACKLESS
|
||||
// Takes arguments which are the most general mix of Python arg types, and
|
||||
// prepares argument array suitable for passing to ->call() method of a
|
||||
// function object (and mp_call_function_n_kw()).
|
||||
// (Only needed in stackless mode.)
|
||||
void mp_call_prepare_args_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const mp_obj_t *args, mp_call_args_t *out_args);
|
||||
#endif
|
||||
|
||||
void mp_unpack_sequence(mp_obj_t seq, mp_uint_t num, mp_obj_t *items);
|
||||
void mp_unpack_ex(mp_obj_t seq, mp_uint_t num, mp_obj_t *items);
|
||||
mp_obj_t mp_store_map(mp_obj_t map, mp_obj_t key, mp_obj_t value);
|
||||
@@ -119,6 +133,7 @@ void mp_import_all(mp_obj_t module);
|
||||
|
||||
// Raise NotImplementedError with given message
|
||||
NORETURN void mp_not_implemented(const char *msg);
|
||||
NORETURN void mp_exc_recursion_depth(void);
|
||||
|
||||
// helper functions for native/viper code
|
||||
mp_uint_t mp_convert_obj_to_native(mp_obj_t obj, mp_uint_t type);
|
||||
|
||||
@@ -148,6 +148,8 @@ typedef enum {
|
||||
MP_F_UNPACK_EX,
|
||||
MP_F_DELETE_NAME,
|
||||
MP_F_DELETE_GLOBAL,
|
||||
MP_F_NEW_CELL,
|
||||
MP_F_MAKE_CLOSURE_FROM_RAW_CODE,
|
||||
MP_F_NUMBER_OF,
|
||||
} mp_fun_kind_t;
|
||||
|
||||
|
||||
@@ -32,10 +32,20 @@
|
||||
// Functions for small integer arithmetic
|
||||
|
||||
// In SMALL_INT, next-to-highest bits is used as sign, so both must match for value in range
|
||||
#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A
|
||||
|
||||
#define MP_SMALL_INT_MIN ((mp_int_t)(((mp_int_t)WORD_MSBIT_HIGH) >> 1))
|
||||
#define MP_SMALL_INT_MAX ((mp_int_t)(~(MP_SMALL_INT_MIN)))
|
||||
#define MP_SMALL_INT_FITS(n) ((((n) ^ ((n) << 1)) & WORD_MSBIT_HIGH) == 0)
|
||||
|
||||
#elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B
|
||||
|
||||
#define MP_SMALL_INT_MIN ((mp_int_t)(((mp_int_t)WORD_MSBIT_HIGH) >> 2))
|
||||
#define MP_SMALL_INT_FITS(n) ((((n) & MP_SMALL_INT_MIN) == 0) || (((n) & MP_SMALL_INT_MIN) == MP_SMALL_INT_MIN))
|
||||
|
||||
#endif
|
||||
|
||||
#define MP_SMALL_INT_MAX ((mp_int_t)(~(MP_SMALL_INT_MIN)))
|
||||
|
||||
bool mp_small_int_mul_overflow(mp_int_t x, mp_int_t y);
|
||||
mp_int_t mp_small_int_modulo(mp_int_t dividend, mp_int_t divisor);
|
||||
mp_int_t mp_small_int_floor_divide(mp_int_t num, mp_int_t denom);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "py/mpstate.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stackctrl.h"
|
||||
|
||||
void mp_stack_ctrl_init(void) {
|
||||
@@ -46,10 +47,14 @@ void mp_stack_set_limit(mp_uint_t limit) {
|
||||
MP_STATE_VM(stack_limit) = limit;
|
||||
}
|
||||
|
||||
void mp_exc_recursion_depth(void) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_RuntimeError,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_maximum_space_recursion_space_depth_space_exceeded)));
|
||||
}
|
||||
|
||||
void mp_stack_check(void) {
|
||||
if (mp_stack_usage() >= MP_STATE_VM(stack_limit)) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_RuntimeError,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_maximum_space_recursion_space_depth_space_exceeded)));
|
||||
mp_exc_recursion_depth();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
125
py/vm.c
125
py/vm.c
@@ -129,9 +129,12 @@ mp_vm_return_kind_t mp_execute_bytecode(mp_code_state *code_state, volatile mp_o
|
||||
// loop and the exception handler, leading to very obscure bugs.
|
||||
#define RAISE(o) do { nlr_pop(); nlr.ret_val = o; goto exception_handler; } while(0)
|
||||
|
||||
#if MICROPY_STACKLESS
|
||||
run_code_state: ;
|
||||
#endif
|
||||
// Pointers which are constant for particular invocation of mp_execute_bytecode()
|
||||
mp_obj_t *const fastn = &code_state->state[code_state->n_state - 1];
|
||||
mp_exc_stack_t *const exc_stack = (mp_exc_stack_t*)(code_state->state + code_state->n_state);
|
||||
mp_obj_t */*const*/ fastn = &code_state->state[code_state->n_state - 1];
|
||||
mp_exc_stack_t */*const*/ exc_stack = (mp_exc_stack_t*)(code_state->state + code_state->n_state);
|
||||
|
||||
// variables that are visible to the exception handler (declared volatile)
|
||||
volatile bool currently_in_except_block = MP_TAGPTR_TAG0(code_state->exc_sp); // 0 or 1, to detect nested exceptions
|
||||
@@ -865,6 +868,26 @@ unwind_jump:;
|
||||
// unum & 0xff == n_positional
|
||||
// (unum >> 8) & 0xff == n_keyword
|
||||
sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe);
|
||||
#if MICROPY_STACKLESS
|
||||
if (mp_obj_get_type(*sp) == &mp_type_fun_bc) {
|
||||
code_state->ip = ip;
|
||||
code_state->sp = sp;
|
||||
code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, currently_in_except_block);
|
||||
mp_code_state *new_state = mp_obj_fun_bc_prepare_codestate(*sp, unum & 0xff, (unum >> 8) & 0xff, sp + 1);
|
||||
if (new_state) {
|
||||
new_state->prev = code_state;
|
||||
code_state = new_state;
|
||||
nlr_pop();
|
||||
goto run_code_state;
|
||||
}
|
||||
#if MICROPY_STACKLESS_STRICT
|
||||
else {
|
||||
deep_recursion_error:
|
||||
mp_exc_recursion_depth();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
SET_TOP(mp_call_function_n_kw(*sp, unum & 0xff, (unum >> 8) & 0xff, sp + 1));
|
||||
DISPATCH();
|
||||
}
|
||||
@@ -877,6 +900,31 @@ unwind_jump:;
|
||||
// We have folowing stack layout here:
|
||||
// fun arg0 arg1 ... kw0 val0 kw1 val1 ... seq dict <- TOS
|
||||
sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe) + 2;
|
||||
#if MICROPY_STACKLESS
|
||||
if (mp_obj_get_type(*sp) == &mp_type_fun_bc) {
|
||||
code_state->ip = ip;
|
||||
code_state->sp = sp;
|
||||
code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, currently_in_except_block);
|
||||
|
||||
mp_call_args_t out_args;
|
||||
mp_call_prepare_args_n_kw_var(false, unum, sp, &out_args);
|
||||
|
||||
mp_code_state *new_state = mp_obj_fun_bc_prepare_codestate(out_args.fun,
|
||||
out_args.n_args, out_args.n_kw, out_args.args);
|
||||
m_del(mp_obj_t, out_args.args, out_args.n_alloc);
|
||||
if (new_state) {
|
||||
new_state->prev = code_state;
|
||||
code_state = new_state;
|
||||
nlr_pop();
|
||||
goto run_code_state;
|
||||
}
|
||||
#if MICROPY_STACKLESS_STRICT
|
||||
else {
|
||||
goto deep_recursion_error;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
SET_TOP(mp_call_method_n_kw_var(false, unum, sp));
|
||||
DISPATCH();
|
||||
}
|
||||
@@ -887,6 +935,30 @@ unwind_jump:;
|
||||
// unum & 0xff == n_positional
|
||||
// (unum >> 8) & 0xff == n_keyword
|
||||
sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe) + 1;
|
||||
#if MICROPY_STACKLESS
|
||||
if (mp_obj_get_type(*sp) == &mp_type_fun_bc) {
|
||||
code_state->ip = ip;
|
||||
code_state->sp = sp;
|
||||
code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, currently_in_except_block);
|
||||
|
||||
mp_uint_t n_args = unum & 0xff;
|
||||
mp_uint_t n_kw = (unum >> 8) & 0xff;
|
||||
int adjust = (sp[1] == NULL) ? 0 : 1;
|
||||
|
||||
mp_code_state *new_state = mp_obj_fun_bc_prepare_codestate(*sp, n_args + adjust, n_kw, sp + 2 - adjust);
|
||||
if (new_state) {
|
||||
new_state->prev = code_state;
|
||||
code_state = new_state;
|
||||
nlr_pop();
|
||||
goto run_code_state;
|
||||
}
|
||||
#if MICROPY_STACKLESS_STRICT
|
||||
else {
|
||||
goto deep_recursion_error;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
SET_TOP(mp_call_method_n_kw(unum & 0xff, (unum >> 8) & 0xff, sp));
|
||||
DISPATCH();
|
||||
}
|
||||
@@ -899,6 +971,31 @@ unwind_jump:;
|
||||
// We have folowing stack layout here:
|
||||
// fun self arg0 arg1 ... kw0 val0 kw1 val1 ... seq dict <- TOS
|
||||
sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe) + 3;
|
||||
#if MICROPY_STACKLESS
|
||||
if (mp_obj_get_type(*sp) == &mp_type_fun_bc) {
|
||||
code_state->ip = ip;
|
||||
code_state->sp = sp;
|
||||
code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, currently_in_except_block);
|
||||
|
||||
mp_call_args_t out_args;
|
||||
mp_call_prepare_args_n_kw_var(true, unum, sp, &out_args);
|
||||
|
||||
mp_code_state *new_state = mp_obj_fun_bc_prepare_codestate(out_args.fun,
|
||||
out_args.n_args, out_args.n_kw, out_args.args);
|
||||
m_del(mp_obj_t, out_args.args, out_args.n_alloc);
|
||||
if (new_state) {
|
||||
new_state->prev = code_state;
|
||||
code_state = new_state;
|
||||
nlr_pop();
|
||||
goto run_code_state;
|
||||
}
|
||||
#if MICROPY_STACKLESS_STRICT
|
||||
else {
|
||||
goto deep_recursion_error;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
SET_TOP(mp_call_method_n_kw_var(true, unum, sp));
|
||||
DISPATCH();
|
||||
}
|
||||
@@ -925,6 +1022,15 @@ unwind_return:
|
||||
nlr_pop();
|
||||
code_state->sp = sp;
|
||||
assert(exc_sp == exc_stack - 1);
|
||||
#if MICROPY_STACKLESS
|
||||
if (code_state->prev != NULL) {
|
||||
mp_obj_t res = *sp;
|
||||
mp_globals_set(code_state->old_globals);
|
||||
code_state = code_state->prev;
|
||||
*code_state->sp = res;
|
||||
goto run_code_state;
|
||||
}
|
||||
#endif
|
||||
return MP_VM_RETURN_NORMAL;
|
||||
|
||||
ENTRY(MP_BC_RAISE_VARARGS): {
|
||||
@@ -1122,6 +1228,9 @@ exception_handler:
|
||||
goto outer_dispatch_loop; // continue with dispatch loop
|
||||
}
|
||||
|
||||
#if MICROPY_STACKLESS
|
||||
unwind_loop:
|
||||
#endif
|
||||
// set file and line number that the exception occurred at
|
||||
// TODO: don't set traceback for exceptions re-raised by END_FINALLY.
|
||||
// But consider how to handle nested exceptions.
|
||||
@@ -1185,6 +1294,18 @@ exception_handler:
|
||||
PUSH(mp_obj_get_type(nlr.ret_val));
|
||||
code_state->sp = sp;
|
||||
|
||||
#if MICROPY_STACKLESS
|
||||
} else if (code_state->prev != NULL) {
|
||||
mp_globals_set(code_state->old_globals);
|
||||
code_state = code_state->prev;
|
||||
fastn = &code_state->state[code_state->n_state - 1];
|
||||
exc_stack = (mp_exc_stack_t*)(code_state->state + code_state->n_state);
|
||||
// variables that are visible to the exception handler (declared volatile)
|
||||
currently_in_except_block = MP_TAGPTR_TAG0(code_state->exc_sp); // 0 or 1, to detect nested exceptions
|
||||
exc_sp = MP_TAGPTR_PTR(code_state->exc_sp); // stack grows up, exc_sp points to top of stack
|
||||
goto unwind_loop;
|
||||
|
||||
#endif
|
||||
} else {
|
||||
// propagate exception to higher level
|
||||
// TODO what to do about ip and sp? they don't really make sense at this point
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _FFCONF
|
||||
#define _FFCONF 80376 /* Revision ID */
|
||||
#define _FFCONF 32020 /* Revision ID */
|
||||
|
||||
#include "mpconfigport.h"
|
||||
|
||||
@@ -49,13 +49,13 @@
|
||||
|
||||
#define _FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes basic writing API functions, f_write(),
|
||||
/ f_sync(), f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(),
|
||||
/ f_getfree() and optional writing functions as well. */
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some API functions.
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: All basic functions are enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(),
|
||||
@@ -73,9 +73,13 @@
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define _USE_FIND 0
|
||||
/* This option switches filtered directory read feature and related functions,
|
||||
/ f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_MKFS 1
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable)
|
||||
/ To enable it, also _FS_READONLY need to be set to 0. */
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 0
|
||||
@@ -88,8 +92,8 @@
|
||||
|
||||
|
||||
#define _USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
/* To enable it, also _FS_TINY need to be set to 1. */
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable)
|
||||
/ To enable it, also _FS_TINY need to be set to 1. */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
@@ -100,32 +104,24 @@
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/
|
||||
/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows)
|
||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
||||
/ 949 - Korean (DBCS, OEM, Windows)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
||||
/ 1250 - Central Europe (Windows)
|
||||
/ 1251 - Cyrillic (Windows)
|
||||
/ 1252 - Latin 1 (Windows)
|
||||
/ 1253 - Greek (Windows)
|
||||
/ 1254 - Turkish (Windows)
|
||||
/ 1255 - Hebrew (Windows)
|
||||
/ 1256 - Arabic (Windows)
|
||||
/ 1257 - Baltic (Windows)
|
||||
/ 1258 - Vietnam (OEM, Windows)
|
||||
/ 437 - U.S. (OEM)
|
||||
/ 720 - Arabic (OEM)
|
||||
/ 737 - Greek (OEM)
|
||||
/ 775 - Baltic (OEM)
|
||||
/ 850 - Multilingual Latin 1 (OEM)
|
||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
||||
/ 852 - Latin 2 (OEM)
|
||||
/ 855 - Cyrillic (OEM)
|
||||
/ 866 - Russian (OEM)
|
||||
/ 857 - Turkish (OEM)
|
||||
/ 862 - Hebrew (OEM)
|
||||
/ 874 - Thai (OEM, Windows)
|
||||
/ 1 - ASCII (No extended character. Valid for only non-LFN configuration.) */
|
||||
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 775 - Baltic
|
||||
/ 850 - Multilingual Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 858 - Multilingual Latin 1 + Euro
|
||||
/ 862 - Hebrew
|
||||
/ 866 - Russian
|
||||
/ 874 - Thai
|
||||
/ 932 - Japanese Shift_JIS (DBCS)
|
||||
/ 936 - Simplified Chinese GBK (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS)
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN (MICROPY_ENABLE_LFN)
|
||||
@@ -194,7 +190,7 @@
|
||||
/ number is bound to the same physical drive number and only an FAT volume found on
|
||||
/ the physical drive will be mounted. When multi-partition feature is enabled (1),
|
||||
/ each logical drive number is bound to arbitrary physical drive and partition
|
||||
/ listed in the VolToPart[]. Also f_fdisk() funciton will be enabled. */
|
||||
/ listed in the VolToPart[]. Also f_fdisk() funciton will be available. */
|
||||
|
||||
|
||||
#define _MIN_SS 512
|
||||
@@ -231,9 +227,9 @@
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_NORTC 0
|
||||
#define _NORTC_MON 11
|
||||
#define _NORTC_MDAY 9
|
||||
#define _NORTC_YEAR 2014
|
||||
#define _NORTC_MON 2
|
||||
#define _NORTC_MDAY 1
|
||||
#define _NORTC_YEAR 2015
|
||||
/* The _FS_NORTC option switches timestamp feature. If the system does not have
|
||||
/ an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable
|
||||
/ the timestamp feature. All objects modified by FatFs will have a fixed timestamp
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
||||
#define MICROPY_PY_FUNCTION_ATTRS (1)
|
||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
|
||||
#define MICROPY_PY_BUILTINS_STR_SPLITLINES (1)
|
||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
|
||||
#define MICROPY_PY_BUILTINS_FROZENSET (1)
|
||||
#define MICROPY_PY_BUILTINS_EXECFILE (1)
|
||||
|
||||
13
tests/basics/string_splitlines.py
Normal file
13
tests/basics/string_splitlines.py
Normal file
@@ -0,0 +1,13 @@
|
||||
try:
|
||||
str.splitlines
|
||||
except:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
print("foo\nbar".splitlines())
|
||||
print("foo\nbar\n".splitlines())
|
||||
print("foo\nbar".splitlines(True))
|
||||
print("foo\nbar\n".splitlines(True))
|
||||
print("foo\nbar".splitlines(keepends=True))
|
||||
print("foo\nbar\n".splitlines(keepends=True))
|
||||
32
tests/micropython/native_closure.py
Normal file
32
tests/micropython/native_closure.py
Normal file
@@ -0,0 +1,32 @@
|
||||
# test native emitter can handle closures correctly
|
||||
|
||||
# basic closure
|
||||
@micropython.native
|
||||
def f():
|
||||
x = 1
|
||||
@micropython.native
|
||||
def g():
|
||||
nonlocal x
|
||||
return x
|
||||
return g
|
||||
print(f()())
|
||||
|
||||
# closing over an argument
|
||||
@micropython.native
|
||||
def f(x):
|
||||
@micropython.native
|
||||
def g():
|
||||
nonlocal x
|
||||
return x
|
||||
return g
|
||||
print(f(2)())
|
||||
|
||||
# closing over an argument and a normal local
|
||||
@micropython.native
|
||||
def f(x):
|
||||
y = 2 * x
|
||||
@micropython.native
|
||||
def g(z):
|
||||
return x + y + z
|
||||
return g
|
||||
print(f(2)(3))
|
||||
3
tests/micropython/native_closure.py.exp
Normal file
3
tests/micropython/native_closure.py.exp
Normal file
@@ -0,0 +1,3 @@
|
||||
1
|
||||
2
|
||||
9
|
||||
@@ -153,7 +153,7 @@ def run_tests(pyb, tests, args):
|
||||
# Some tests are known to fail with native emitter
|
||||
# Remove them from the below when they work
|
||||
if args.emit == 'native':
|
||||
skip_tests.update({'basics/%s.py' % t for t in 'bytes_gen class_store_class class_super class_super_object closure1 closure2 closure_defargs del_deref del_local fun3 fun_calldblstar fun_callstar fun_callstardblstar fun_defargs fun_defargs2 fun_kwargs fun_kwonly fun_kwonlydef fun_kwvarargs fun_varargs gen_yield_from gen_yield_from_close gen_yield_from_ducktype gen_yield_from_exc gen_yield_from_iter gen_yield_from_send gen_yield_from_throw generator1 generator2 generator_args generator_close generator_closure generator_exc generator_return generator_send globals_del string_format string_join subclass_native2_list subclass_native2_tuple try_finally_loops try_finally_return try_reraise try_reraise2 unboundlocal with1 with_break with_continue with_return'.split()})
|
||||
skip_tests.update({'basics/%s.py' % t for t in 'bytes_gen class_store_class closure_defargs del_deref del_local fun3 fun_calldblstar fun_callstar fun_callstardblstar fun_defargs fun_defargs2 fun_kwargs fun_kwonly fun_kwonlydef fun_kwvarargs fun_varargs gen_yield_from gen_yield_from_close gen_yield_from_ducktype gen_yield_from_exc gen_yield_from_iter gen_yield_from_send gen_yield_from_throw generator1 generator2 generator_args generator_close generator_closure generator_exc generator_return generator_send globals_del string_format string_join subclass_native2_list subclass_native2_tuple try_finally_loops try_finally_return try_reraise try_reraise2 unboundlocal with1 with_break with_continue with_return'.split()})
|
||||
skip_tests.add('basics/array_construct2.py') # requires generators
|
||||
skip_tests.add('basics/bool1.py') # seems to randomly fail
|
||||
skip_tests.add('basics/boundmeth1.py') # requires support for many args
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
#define MICROPY_PY_FUNCTION_ATTRS (1)
|
||||
#define MICROPY_PY_DESCRIPTORS (1)
|
||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
|
||||
#define MICROPY_PY_BUILTINS_STR_SPLITLINES (1)
|
||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
|
||||
#define MICROPY_PY_BUILTINS_FROZENSET (1)
|
||||
#define MICROPY_PY_BUILTINS_COMPILE (1)
|
||||
@@ -76,6 +77,9 @@
|
||||
#define MICROPY_PY_IO_FILEIO (1)
|
||||
#define MICROPY_PY_GC_COLLECT_RETVAL (1)
|
||||
|
||||
#define MICROPY_STACKLESS (0)
|
||||
#define MICROPY_STACKLESS_STRICT (0)
|
||||
|
||||
#define MICROPY_PY_UCTYPES (1)
|
||||
#define MICROPY_PY_UZLIB (1)
|
||||
#define MICROPY_PY_UJSON (1)
|
||||
|
||||
Reference in New Issue
Block a user