Merge remote-tracking branch 'origin/main'

This commit is contained in:
Hosted Weblate 2022-10-17 01:55:31 +02:00
commit 12be7b136a
No known key found for this signature in database
GPG Key ID: A3FAAA06E6569B4C
53 changed files with 723 additions and 236 deletions

View File

@ -27,6 +27,7 @@ import pathlib
import re
import subprocess
import sys
import functools
from concurrent.futures import ThreadPoolExecutor
@ -80,12 +81,11 @@ This is the same list as in the preprocess_frozen_modules script."""
repository_urls = {}
"""Cache of repository URLs for frozen modules."""
root_dir = pathlib.Path(__file__).resolve().parent.parent
def get_circuitpython_root_dir():
""" The path to the root './circuitpython' directory.
"""
file_path = pathlib.Path(__file__).resolve()
root_dir = file_path.parent.parent
return root_dir
def get_shared_bindings():
@ -102,7 +102,7 @@ def get_board_mapping():
"""
boards = {}
for port in SUPPORTED_PORTS:
board_path = os.path.join("../ports", port, "boards")
board_path = root_dir / "ports" / port / "boards"
for board_path in os.scandir(board_path):
if board_path.is_dir():
board_files = os.listdir(board_path.path)
@ -276,6 +276,7 @@ def lookup_setting(settings, key, default=''):
key = value[2:-1]
return value
@functools.cache
def all_ports_all_boards(ports=SUPPORTED_PORTS):
for port in ports:

View File

@ -9,7 +9,7 @@
#include <stdio.h>
#include "py/ioctl.h"
#include "py/stream.h"
#include "py/runtime.h"
#include "py/obj.h"
#include "py/objlist.h"

View File

@ -400,6 +400,35 @@ STATIC mp_obj_t vfs_fat_umount(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_umount_obj, vfs_fat_umount);
STATIC mp_obj_t vfs_fat_utime(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t times_in) {
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
const char *path = mp_obj_str_get_str(path_in);
if (!mp_obj_is_tuple_compatible(times_in)) {
mp_raise_type_arg(&mp_type_TypeError, times_in);
}
mp_obj_t *otimes;
mp_obj_get_array_fixed_n(times_in, 2, &otimes);
// Validate that both elements of the tuple are int and discard the second one
int time[2];
time[0] = mp_obj_get_int(otimes[0]);
time[1] = mp_obj_get_int(otimes[1]);
timeutils_struct_time_t tm;
timeutils_seconds_since_epoch_to_struct_time(time[0], &tm);
FILINFO fno;
fno.fdate = (WORD)(((tm.tm_year - 1980) * 512U) | tm.tm_mon * 32U | tm.tm_mday);
fno.ftime = (WORD)(tm.tm_hour * 2048U | tm.tm_min * 32U | tm.tm_sec / 2U);
FRESULT res = f_utime(&self->fatfs, path, &fno);
if (res != FR_OK) {
mp_raise_OSError_fresult(res);
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_utime_obj, vfs_fat_utime);
#if MICROPY_FATFS_USE_LABEL
STATIC mp_obj_t vfs_fat_getlabel(mp_obj_t self_in) {
fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in);
@ -451,6 +480,7 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&fat_vfs_statvfs_obj) },
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&vfs_fat_mount_obj) },
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&fat_vfs_umount_obj) },
{ MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&fat_vfs_utime_obj) },
#if MICROPY_FATFS_USE_LABEL
{ MP_ROM_QSTR(MP_QSTR_label), MP_ROM_PTR(&fat_vfs_label_obj) },
#endif

View File

@ -117,6 +117,10 @@ msgstr ""
msgid "%q init failed"
msgstr ""
#: shared-bindings/dualbank/__init__.c
msgid "%q is %q"
msgstr ""
#: py/argcheck.c
msgid "%q length must be %d"
msgstr ""
@ -211,7 +215,7 @@ msgstr ""
msgid "%q, %q, and %q must all be the same length"
msgstr ""
#: py/objint.c
#: py/objint.c shared-bindings/storage/__init__.c
msgid "%q=%q"
msgstr ""
@ -1001,7 +1005,15 @@ msgid "Filters too complex"
msgstr ""
#: ports/espressif/common-hal/dualbank/__init__.c
msgid "Firmware image is invalid"
msgid "Firmware is duplicate"
msgstr ""
#: ports/espressif/common-hal/dualbank/__init__.c
msgid "Firmware is invalid"
msgstr ""
#: ports/espressif/common-hal/dualbank/__init__.c
msgid "Firmware is too big"
msgstr ""
#: shared-bindings/bitmaptools/__init__.c
@ -4151,7 +4163,7 @@ msgstr ""
msgid "unexpected keyword argument"
msgstr ""
#: py/bc.c py/objnamedtuple.c
#: py/bc.c py/objnamedtuple.c shared-bindings/traceback/__init__.c
msgid "unexpected keyword argument '%q'"
msgstr ""

View File

@ -11,3 +11,5 @@ CIRCUITPY_BUILD_EXTENSIONS = bin,uf2
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_FULL_BUILD = 0
CIRCUITPY_RAINBOWIO = 0

View File

@ -11,4 +11,5 @@ CIRCUITPY_BUILD_EXTENSIONS = bin,uf2
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_FULL_BUILD = 0
CIRCUITPY_RAINBOWIO = 0

View File

@ -15,12 +15,13 @@ CIRCUITPY_FULL_BUILD = 0
# A number of modules are removed for RFM69 to make room for frozen libraries.
# Many I/O functions are not available.
CIRCUITPY_ANALOGIO = 1
CIRCUITPY_BUSDEVICE = 1
CIRCUITPY_RAINBOWIO = 0
CIRCUITPY_ROTARYIO = 0
CIRCUITPY_RTC = 0
CIRCUITPY_TOUCHIO = 0
CIRCUITPY_USB_MIDI = 0
CIRCUITPY_USB_HID = 0
CIRCUITPY_TOUCHIO = 0
CIRCUITPY_BUSDEVICE = 1
# Include these Python libraries in firmware.
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_RFM69

View File

@ -20,11 +20,13 @@ CIRCUITPY_BITBANG_APA102 = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CTARGET = 0
CIRCUITPY_NEOPIXEL_WRITE = 0
CIRCUITPY_ONEWIREIO = 0
CIRCUITPY_PARALLELDISPLAY = 0
CIRCUITPY_PIXELBUF = 0
CIRCUITPY_PS2IO = 0
CIRCUITPY_PULSEIO = 0
CIRCUITPY_PWMIO = 0
CIRCUITPY_RAINBOWIO = 0
CIRCUITPY_ROTARYIO = 0
CIRCUITPY_RTC = 0
CIRCUITPY_SAMD = 0

View File

@ -9,3 +9,5 @@ CHIP_FAMILY = samd21
SPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICES = "W25Q32FV"
LONGINT_IMPL = MPZ
CIRCUITPY_RAINBOWIO = 0

View File

@ -73,46 +73,37 @@
#include "peripheral_clk_config.h"
#define ADC_TEMP_SAMPLE_LENGTH 4
#define INT1V_VALUE_FLOAT 1.0
#define INT1V_DIVIDER_1000 1000.0
#define ADC_12BIT_FULL_SCALE_VALUE_FLOAT 4095.0
#define INT1V_VALUE_FLOAT MICROPY_FLOAT_CONST(1.0)
#define INT1V_DIVIDER_1000 MICROPY_FLOAT_CONST(1000.0)
#define ADC_12BIT_FULL_SCALE_VALUE_FLOAT MICROPY_FLOAT_CONST(4095.0)
// channel argument (ignored in calls below)
#define IGNORED_CHANNEL 0
// Decimal to fraction conversion. (adapted from ASF sample).
STATIC float convert_dec_to_frac(uint8_t val) {
float float_val = (float)val;
if (val < 10) {
return float_val / 10.0;
} else if (val < 100) {
return float_val / 100.0;
} else {
return float_val / 1000.0;
}
}
// Extract the production calibration data information from NVM (adapted from ASF sample),
// then calculate the temperature
//
// This code performs almost all operations with scaled integers. For
// instance, tempR is in units of 1/10°C, INT1VR is in units of 1mV, etc,
// This is important to reduce the code size of the function. The effect on
// precision is a ~.9°C difference vs the floating point algorithm on an
// approximate 0..60°C range with a difference of ~.5°C at 25°C. When the fine
// calculation step is skipped, the additional error approximately doubles.
//
// To save code size, rounding is neglected. However, trying to add back rounding
// (by computing (a + b/2) / b instead of just a / b) actually didn't help
// accuracy anyway.
#ifdef SAMD21
STATIC float calculate_temperature(uint16_t raw_value) {
volatile uint32_t val1; /* Temperature Log Row Content first 32 bits */
volatile uint32_t val2; /* Temperature Log Row Content another 32 bits */
uint8_t room_temp_val_int; /* Integer part of room temperature in °C */
uint8_t room_temp_val_dec; /* Decimal part of room temperature in °C */
uint8_t hot_temp_val_int; /* Integer part of hot temperature in °C */
uint8_t hot_temp_val_dec; /* Decimal part of hot temperature in °C */
int8_t room_int1v_val; /* internal 1V reference drift at room temperature */
int8_t hot_int1v_val; /* internal 1V reference drift at hot temperature*/
float tempR; // Production Room temperature
float tempH; // Production Hot temperature
float INT1VR; // Room temp 2's complement of the internal 1V reference value
float INT1VH; // Hot temp 2's complement of the internal 1V reference value
uint16_t ADCR; // Production Room temperature ADC value
uint16_t ADCH; // Production Hot temperature ADC value
float VADCR; // Room temperature ADC voltage
float VADCH; // Hot temperature ADC voltage
uint32_t val1; /* Temperature Log Row Content first 32 bits */
uint32_t val2; /* Temperature Log Row Content another 32 bits */
int room_temp_val_int; /* Integer part of room temperature in °C */
int room_temp_val_dec; /* Decimal part of room temperature in °C */
int hot_temp_val_int; /* Integer part of hot temperature in °C */
int hot_temp_val_dec; /* Decimal part of hot temperature in °C */
int room_int1v_val; /* internal 1V reference drift at room temperature */
int hot_int1v_val; /* internal 1V reference drift at hot temperature*/
uint32_t *temp_log_row_ptr = (uint32_t *)NVMCTRL_TEMP_LOG;
@ -120,32 +111,29 @@ STATIC float calculate_temperature(uint16_t raw_value) {
temp_log_row_ptr++;
val2 = *temp_log_row_ptr;
room_temp_val_int = (uint8_t)((val1 & FUSES_ROOM_TEMP_VAL_INT_Msk) >> FUSES_ROOM_TEMP_VAL_INT_Pos);
room_temp_val_dec = (uint8_t)((val1 & FUSES_ROOM_TEMP_VAL_DEC_Msk) >> FUSES_ROOM_TEMP_VAL_DEC_Pos);
room_temp_val_int = ((val1 & FUSES_ROOM_TEMP_VAL_INT_Msk) >> FUSES_ROOM_TEMP_VAL_INT_Pos);
room_temp_val_dec = ((val1 & FUSES_ROOM_TEMP_VAL_DEC_Msk) >> FUSES_ROOM_TEMP_VAL_DEC_Pos);
hot_temp_val_int = (uint8_t)((val1 & FUSES_HOT_TEMP_VAL_INT_Msk) >> FUSES_HOT_TEMP_VAL_INT_Pos);
hot_temp_val_dec = (uint8_t)((val1 & FUSES_HOT_TEMP_VAL_DEC_Msk) >> FUSES_HOT_TEMP_VAL_DEC_Pos);
hot_temp_val_int = ((val1 & FUSES_HOT_TEMP_VAL_INT_Msk) >> FUSES_HOT_TEMP_VAL_INT_Pos);
hot_temp_val_dec = ((val1 & FUSES_HOT_TEMP_VAL_DEC_Msk) >> FUSES_HOT_TEMP_VAL_DEC_Pos);
// necessary casts: must interpret 8 bits as signed
room_int1v_val = (int8_t)((val1 & FUSES_ROOM_INT1V_VAL_Msk) >> FUSES_ROOM_INT1V_VAL_Pos);
hot_int1v_val = (int8_t)((val2 & FUSES_HOT_INT1V_VAL_Msk) >> FUSES_HOT_INT1V_VAL_Pos);
ADCR = (uint16_t)((val2 & FUSES_ROOM_ADC_VAL_Msk) >> FUSES_ROOM_ADC_VAL_Pos);
ADCH = (uint16_t)((val2 & FUSES_HOT_ADC_VAL_Msk) >> FUSES_HOT_ADC_VAL_Pos);
int ADCR = ((val2 & FUSES_ROOM_ADC_VAL_Msk) >> FUSES_ROOM_ADC_VAL_Pos);
int ADCH = ((val2 & FUSES_HOT_ADC_VAL_Msk) >> FUSES_HOT_ADC_VAL_Pos);
tempR = room_temp_val_int + convert_dec_to_frac(room_temp_val_dec);
tempH = hot_temp_val_int + convert_dec_to_frac(hot_temp_val_dec);
int tempR = 10 * room_temp_val_int + room_temp_val_dec;
int tempH = 10 * hot_temp_val_int + hot_temp_val_dec;
INT1VR = 1 - ((float)room_int1v_val / INT1V_DIVIDER_1000);
INT1VH = 1 - ((float)hot_int1v_val / INT1V_DIVIDER_1000);
int INT1VR = 1000 - room_int1v_val;
int INT1VH = 1000 - hot_int1v_val;
VADCR = ((float)ADCR * INT1VR) / ADC_12BIT_FULL_SCALE_VALUE_FLOAT;
VADCH = ((float)ADCH * INT1VH) / ADC_12BIT_FULL_SCALE_VALUE_FLOAT;
int VADCR = ADCR * INT1VR;
int VADCH = ADCH * INT1VH;
float VADC; /* Voltage calculation using ADC result for Coarse Temp calculation */
float VADCM; /* Voltage calculation using ADC result for Fine Temp calculation. */
float INT1VM; /* Voltage calculation for reality INT1V value during the ADC conversion */
VADC = ((float)raw_value * INT1V_VALUE_FLOAT) / ADC_12BIT_FULL_SCALE_VALUE_FLOAT;
int VADC = raw_value * 1000;
// Hopefully compiler will remove common subepxressions here.
@ -153,21 +141,31 @@ STATIC float calculate_temperature(uint16_t raw_value) {
// 1b as mentioned in data sheet section "Temperature Sensor Characteristics"
// of Electrical Characteristics. (adapted from ASF sample code).
// Coarse Temp Calculation by assume INT1V=1V for this ADC conversion
float coarse_temp = tempR + (((tempH - tempR) / (VADCH - VADCR)) * (VADC - VADCR));
int coarse_temp = tempR + (tempH - tempR) * (VADC - VADCR) / (VADCH - VADCR);
#if CIRCUITPY_FULL_BUILD
// Calculation to find the real INT1V value during the ADC conversion
int INT1VM; /* Voltage calculation for reality INT1V value during the ADC conversion */
INT1VM = INT1VR + (((INT1VH - INT1VR) * (coarse_temp - tempR)) / (tempH - tempR));
VADCM = ((float)raw_value * INT1VM) / ADC_12BIT_FULL_SCALE_VALUE_FLOAT;
int VADCM = raw_value * INT1VM;
// Fine Temp Calculation by replace INT1V=1V by INT1V = INT1Vm for ADC conversion
float fine_temp = tempR + (((tempH - tempR) / (VADCH - VADCR)) * (VADCM - VADCR));
float fine_temp = tempR + (((tempH - tempR) * (VADCM - VADCR)) / (VADCH - VADCR));
return fine_temp;
return fine_temp / 10;
#else
return coarse_temp / 10.;
#endif
}
#endif // SAMD21
#ifdef SAM_D5X_E5X
// Decimal to fraction conversion. (adapted from ASF sample).
STATIC float convert_dec_to_frac(uint8_t val) {
return val / MICROPY_FLOAT_CONST(10.);
}
STATIC float calculate_temperature(uint16_t TP, uint16_t TC) {
uint32_t TLI = (*(uint32_t *)FUSES_ROOM_TEMP_VAL_INT_ADDR & FUSES_ROOM_TEMP_VAL_INT_Msk) >> FUSES_ROOM_TEMP_VAL_INT_Pos;
uint32_t TLD = (*(uint32_t *)FUSES_ROOM_TEMP_VAL_DEC_ADDR & FUSES_ROOM_TEMP_VAL_DEC_Msk) >> FUSES_ROOM_TEMP_VAL_DEC_Pos;

View File

@ -3,35 +3,46 @@
STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS
{ MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_LED_BUILTIN), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO3) },
{ MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) },
{ MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO4) },
{ MP_ROM_QSTR(MP_QSTR_T4), MP_ROM_PTR(&pin_GPIO4) },
{ MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) },
{ MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO5) },
{ MP_ROM_QSTR(MP_QSTR_T5), MP_ROM_PTR(&pin_GPIO5) },
{ MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) },
{ MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_T6), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_T7), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO8) },
{ MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO8) },
{ MP_ROM_QSTR(MP_QSTR_T8), MP_ROM_PTR(&pin_GPIO8) },
{ MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) },
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO9) },
{ MP_ROM_QSTR(MP_QSTR_T9), MP_ROM_PTR(&pin_GPIO9) },
{ MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) },
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO10) },
{ MP_ROM_QSTR(MP_QSTR_T10), MP_ROM_PTR(&pin_GPIO10) },
{ MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) },
{ MP_ROM_QSTR(MP_QSTR_VP_EN), MP_ROM_PTR(&pin_GPIO11) },
@ -43,20 +54,27 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_VIN), MP_ROM_PTR(&pin_GPIO13) },
{ MP_ROM_QSTR(MP_QSTR_VBATT), MP_ROM_PTR(&pin_GPIO13) },
{ MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO13) },
{ MP_ROM_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_GPIO13) },
{ MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) },
{ MP_ROM_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_GPIO14) },
{ MP_ROM_QSTR(MP_QSTR_T14), MP_ROM_PTR(&pin_GPIO14) },
{ MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) },
{ MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO15) },
{ MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_GPIO15) },
{ MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) },
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO16) },
{ MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO16) },
{ MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) },
{ MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO17) },
{ MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO17) },
{ MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) },
{ MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO18) },
{ MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO18) },
{ MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) },
{ MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) },
@ -71,6 +89,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_D42), MP_ROM_PTR(&pin_GPIO42) },
{ MP_ROM_QSTR(MP_QSTR_RGB), MP_ROM_PTR(&pin_GPIO46) },
{ MP_ROM_QSTR(MP_QSTR_RGB_BUILTIN), MP_ROM_PTR(&pin_GPIO46) },
{ MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO46) },
{ MP_ROM_QSTR(MP_QSTR_D46), MP_ROM_PTR(&pin_GPIO46) },

View File

@ -57,14 +57,13 @@ void common_hal_dualbank_flash(const void *buf, const size_t len, const size_t o
if (update_partition == NULL) {
update_partition = esp_ota_get_next_update_partition(NULL);
assert(update_partition != NULL);
ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)",
running->type, running->subtype, running->address);
ESP_LOGI(TAG, "Writing partition type %d subtype %d (offset 0x%08x)\n",
update_partition->type, update_partition->subtype, update_partition->address);
assert(update_partition != NULL);
}
if (update_handle == 0) {
@ -86,14 +85,14 @@ void common_hal_dualbank_flash(const void *buf, const size_t len, const size_t o
// check new version with running version
if (memcmp(new_app_info.version, running_app_info.version, sizeof(new_app_info.version)) == 0) {
ESP_LOGW(TAG, "New version is the same as running version.");
task_fatal_error();
mp_raise_RuntimeError(translate("Firmware is duplicate"));
}
// check new version with last invalid partition
if (last_invalid != NULL) {
if (memcmp(new_app_info.version, invalid_app_info.version, sizeof(new_app_info.version)) == 0) {
ESP_LOGW(TAG, "New version is the same as invalid version.");
task_fatal_error();
mp_raise_RuntimeError(translate("Firmware is invalid"));
}
}
@ -104,7 +103,7 @@ void common_hal_dualbank_flash(const void *buf, const size_t len, const size_t o
}
} else {
ESP_LOGE(TAG, "received package is not fit len");
task_fatal_error();
mp_raise_RuntimeError(translate("Firmware is too big"));
}
}
@ -128,7 +127,7 @@ void common_hal_dualbank_switch(void) {
if (err != ESP_OK) {
if (err == ESP_ERR_OTA_VALIDATE_FAILED) {
ESP_LOGE(TAG, "Image validation failed, image is corrupted");
mp_raise_RuntimeError(translate("Firmware image is invalid"));
mp_raise_RuntimeError(translate("Firmware is invalid"));
}
ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err));
task_fatal_error();

View File

@ -5,6 +5,12 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set
CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG=y
# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set
# end of Bootloader config
# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set
@ -60,6 +66,17 @@ CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y
CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2
# end of Hardware Abstraction Layer (HAL) and Low Level (LL)
#
# Log output
#
# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
# end of Log output
CONFIG_LWIP_ESP_LWIP_ASSERT=y
#
# Deprecated options for backward compatibility

View File

@ -5,6 +5,12 @@ CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set
# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set
CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y
# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set
# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set
# end of Bootloader config
#
@ -73,6 +79,17 @@ CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y
CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=1
# end of Hardware Abstraction Layer (HAL) and Low Level (LL)
#
# Log output
#
CONFIG_LOG_DEFAULT_LEVEL_NONE=y
# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set
# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set
# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
# end of Log output
#
# LWIP
#

View File

@ -24,6 +24,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "supervisor/internal_flash.h"
#include <stdint.h>
@ -32,27 +33,52 @@
#include "extmod/vfs.h"
#include "extmod/vfs_fat.h"
#include "py/mphal.h"
#include "py/obj.h"
#include "py/runtime.h"
#include "lib/oofatfs/ff.h"
#include "components/spi_flash/include/esp_partition.h"
#include "esp_ota_ops.h"
#include "esp_partition.h"
#include "supervisor/filesystem.h"
#include "supervisor/flash.h"
#include "supervisor/usb.h"
STATIC const esp_partition_t *_partition;
#define OP_READ 0
#define OP_WRITE 1
// TODO: Split the caching out of supervisor/shared/external_flash so we can use it.
#define SECTOR_SIZE 4096
STATIC uint8_t _cache[SECTOR_SIZE];
STATIC uint32_t _cache_lba = 0xffffffff;
#if CIRCUITPY_STORAGE_EXTEND
#if FF_MAX_SS == FF_MIN_SS
#define SECSIZE(fs) (FF_MIN_SS)
#else
#define SECSIZE(fs) ((fs)->ssize)
#endif // FF_MAX_SS == FF_MIN_SS
STATIC DWORD fatfs_bytes(void) {
FATFS *fatfs = filesystem_circuitpy();
return (fatfs->csize * SECSIZE(fatfs)) * (fatfs->n_fatent - 2);
}
STATIC bool storage_extended = true;
STATIC const esp_partition_t *_partition[2];
#else
STATIC const esp_partition_t *_partition[1];
#endif // CIRCUITPY_STORAGE_EXTEND
void supervisor_flash_init(void) {
_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,
if (_partition[0] != NULL) {
return;
}
_partition[0] = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,
ESP_PARTITION_SUBTYPE_DATA_FAT,
NULL);
#if CIRCUITPY_STORAGE_EXTEND
_partition[1] = esp_ota_get_next_update_partition(NULL);
#endif
}
uint32_t supervisor_flash_get_block_size(void) {
@ -60,19 +86,61 @@ uint32_t supervisor_flash_get_block_size(void) {
}
uint32_t supervisor_flash_get_block_count(void) {
return _partition->size / FILESYSTEM_BLOCK_SIZE;
#if CIRCUITPY_STORAGE_EXTEND
return ((storage_extended) ? (_partition[0]->size + _partition[1]->size) : _partition[0]->size) / FILESYSTEM_BLOCK_SIZE;
#else
return _partition[0]->size / FILESYSTEM_BLOCK_SIZE;
#endif
}
void port_internal_flash_flush(void) {
}
STATIC void single_partition_rw(const esp_partition_t *partition, uint8_t *data,
const uint32_t offset, const uint32_t size_total, const bool op) {
if (op == OP_READ) {
esp_partition_read(partition, offset, data, size_total);
} else {
esp_partition_erase_range(partition, offset, size_total);
esp_partition_write(partition, offset, _cache, size_total);
}
}
#if CIRCUITPY_STORAGE_EXTEND
STATIC void multi_partition_rw(uint8_t *data,
const uint32_t offset, const uint32_t size_total, const bool op) {
if (offset > _partition[0]->size) {
// only r/w partition 1
single_partition_rw(_partition[1], data, (offset - _partition[0]->size), size_total, op);
} else if ((offset + size_total) > _partition[0]->size) {
// first r/w partition 0, then partition 1
uint32_t size_0 = _partition[0]->size - offset;
uint32_t size_1 = size_total - size_0;
if (op == OP_READ) {
esp_partition_read(_partition[0], offset, data, size_0);
esp_partition_read(_partition[1], 0, (data + size_0), size_1);
} else {
esp_partition_erase_range(_partition[0], offset, size_0);
esp_partition_write(_partition[0], offset, _cache, size_0);
esp_partition_erase_range(_partition[1], 0, size_1);
esp_partition_write(_partition[1], 0, (_cache + size_0), size_1);
}
} else {
// only r/w partition 0
single_partition_rw(_partition[0], data, offset, size_total, op);
}
}
#endif
mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
esp_partition_read(_partition,
block * FILESYSTEM_BLOCK_SIZE,
dest,
num_blocks * FILESYSTEM_BLOCK_SIZE);
return 0;
const uint32_t offset = block * FILESYSTEM_BLOCK_SIZE;
const uint32_t read_total = num_blocks * FILESYSTEM_BLOCK_SIZE;
#if CIRCUITPY_STORAGE_EXTEND
multi_partition_rw(dest, offset, read_total, OP_READ);
#else
single_partition_rw(_partition[0], dest, offset, read_total, OP_READ);
#endif
return 0; // success
}
mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) {
@ -82,12 +150,8 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32
uint32_t block_address = lba + block;
uint32_t sector_offset = block_address / blocks_per_sector * SECTOR_SIZE;
uint8_t block_offset = block_address % blocks_per_sector;
if (_cache_lba != block_address) {
esp_partition_read(_partition,
sector_offset,
_cache,
SECTOR_SIZE);
supervisor_flash_read_blocks(_cache, sector_offset / FILESYSTEM_BLOCK_SIZE, blocks_per_sector);
_cache_lba = sector_offset;
}
for (uint8_t b = block_offset; b < blocks_per_sector; b++) {
@ -100,15 +164,34 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32
FILESYSTEM_BLOCK_SIZE);
block++;
}
esp_partition_erase_range(_partition, sector_offset, SECTOR_SIZE);
esp_partition_write(_partition,
sector_offset,
_cache,
SECTOR_SIZE);
#if CIRCUITPY_STORAGE_EXTEND
multi_partition_rw(_cache, sector_offset, SECTOR_SIZE, OP_WRITE);
#else
single_partition_rw(_partition[0], _cache, sector_offset, SECTOR_SIZE, OP_READ);
#endif
}
return 0; // success
}
void supervisor_flash_release_cache(void) {
}
void supervisor_flash_set_extended(bool extended) {
#if CIRCUITPY_STORAGE_EXTEND
storage_extended = extended;
#endif
}
bool supervisor_flash_get_extended(void) {
#if CIRCUITPY_STORAGE_EXTEND
return storage_extended;
#else
return false;
#endif
}
void supervisor_flash_update_extended(void) {
#if CIRCUITPY_STORAGE_EXTEND
storage_extended = (_partition[0]->size < fatfs_bytes());
#endif
}

View File

@ -35,6 +35,12 @@
static int power_management_value = PM_DISABLED;
void cyw43_enter_deep_sleep(void) {
#define WL_REG_ON 23
gpio_set_dir(WL_REG_ON, GPIO_OUT);
gpio_put(WL_REG_ON, false);
}
void bindings_cyw43_wifi_enforce_pm() {
cyw43_wifi_pm(&cyw43_state, power_management_value);
}

View File

@ -51,3 +51,4 @@ const mcu_pin_obj_t *validate_obj_is_pin_including_cyw43(mp_obj_t obj);
#define PM_DISABLED CONSTANT_CYW43_PM_VALUE(CYW43_NO_POWERSAVE_MODE, 200, 1, 1, 10)
extern void bindings_cyw43_wifi_enforce_pm(void);
void cyw43_enter_deep_sleep(void);

View File

@ -13,7 +13,7 @@ CIRCUITPY__EVE = 1
CIRCUITPY_CYW43 = 1
CIRCUITPY_SSL = 1
CIRCUITPY_SSL_MBEDTLS = 1
CIRCUITPY_HASHLIB = 0
CIRCUITPY_HASHLIB = 1
CIRCUITPY_WEB_WORKFLOW = 0
CIRCUITPY_MDNS = 0
CIRCUITPY_SOCKETPOOL = 1

View File

@ -38,6 +38,10 @@
#include "shared-bindings/microcontroller/__init__.h"
#if CIRCUITPY_CYW43
#include "bindings/cyw43/__init__.h"
#endif
#include "supervisor/port.h"
#include "supervisor/shared/workflow.h"
@ -204,6 +208,10 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala
void NORETURN common_hal_alarm_enter_deep_sleep(void) {
bool timealarm_set = alarm_time_timealarm_is_set();
#if CIRCUITPY_CYW43
cyw43_enter_deep_sleep();
#endif
// If there's a timealarm, just enter a very deep light sleep
if (timealarm_set) {
// Prune the clock for sleep

View File

@ -50,6 +50,12 @@ digitalinout_result_t common_hal_digitalio_digitalinout_construct(
self->output = false;
self->open_drain = false;
#if CIRCUITPY_CYW43
if (IS_CYW(self)) {
return DIGITALINOUT_OK;
}
#endif
// Set to input. No output value.
gpio_init(pin->number);
return DIGITALINOUT_OK;

View File

@ -0,0 +1,57 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Scott Shawcroft for Adafruit Industries
*
* 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 "shared-bindings/hashlib/Hash.h"
#include "mbedtls/ssl.h"
void common_hal_hashlib_hash_update(hashlib_hash_obj_t *self, const uint8_t *data, size_t datalen) {
if (self->hash_type == MBEDTLS_SSL_HASH_SHA1) {
mbedtls_sha1_update_ret(&self->sha1, data, datalen);
return;
}
}
void common_hal_hashlib_hash_digest(hashlib_hash_obj_t *self, uint8_t *data, size_t datalen) {
if (datalen < common_hal_hashlib_hash_get_digest_size(self)) {
return;
}
if (self->hash_type == MBEDTLS_SSL_HASH_SHA1) {
// We copy the sha1 state so we can continue to update if needed or get
// the digest a second time.
mbedtls_sha1_context copy;
mbedtls_sha1_clone(&copy, &self->sha1);
mbedtls_sha1_finish_ret(&self->sha1, data);
mbedtls_sha1_clone(&self->sha1, &copy);
}
}
size_t common_hal_hashlib_hash_get_digest_size(hashlib_hash_obj_t *self) {
if (self->hash_type == MBEDTLS_SSL_HASH_SHA1) {
return 20;
}
return 0;
}

View File

@ -1,9 +1,9 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* SPDX-FileCopyrightText: Copyright (c) 2013-2015 Damien P. George
* Copyright (c) 2022 Jeff Epler for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -23,16 +23,16 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_PY_IOCTL_H
#define MICROPY_INCLUDED_PY_IOCTL_H
#define MP_IOCTL_POLL (0x100 | 1)
#pragma once
// These values are compatible with Linux, which are in turn
// compatible with iBCS2 spec.
#define MP_IOCTL_POLL_RD (0x0001)
#define MP_IOCTL_POLL_WR (0x0004)
#define MP_IOCTL_POLL_ERR (0x0008)
#define MP_IOCTL_POLL_HUP (0x0010)
#include "mbedtls/sha1.h"
#endif // MICROPY_INCLUDED_PY_IOCTL_H
typedef struct {
mp_obj_base_t base;
union {
mbedtls_sha1_context sha1;
};
// Of MBEDTLS_SSL_HASH_*
uint8_t hash_type;
} hashlib_hash_obj_t;

View File

@ -0,0 +1,40 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Scott Shawcroft for Adafruit Industries
*
* 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 "shared-bindings/hashlib/__init__.h"
#include "mbedtls/ssl.h"
bool common_hal_hashlib_new(hashlib_hash_obj_t *self, const char *algorithm) {
if (strcmp(algorithm, "sha1") == 0) {
self->hash_type = MBEDTLS_SSL_HASH_SHA1;
mbedtls_sha1_init(&self->sha1);
mbedtls_sha1_starts_ret(&self->sha1);
return true;
}
return false;
}

View File

@ -1080,7 +1080,7 @@ int socketpool_socket_recv_into(socketpool_socket_obj_t *socket,
ret = lwip_raw_udp_receive(socket, (byte *)buf, len, NULL, NULL, &_errno);
break;
}
if (ret < 0) {
if (ret == (unsigned)-1) {
return -_errno;
}
return ret;
@ -1089,7 +1089,7 @@ int socketpool_socket_recv_into(socketpool_socket_obj_t *socket,
mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) {
int received = socketpool_socket_recv_into(self, buf, len);
if (received < 0) {
mp_raise_OSError(received);
mp_raise_OSError(-received);
}
return received;
}

View File

@ -401,6 +401,9 @@ CFLAGS += -DCIRCUITPY_STATUS_BAR=$(CIRCUITPY_STATUS_BAR)
CIRCUITPY_STORAGE ?= 1
CFLAGS += -DCIRCUITPY_STORAGE=$(CIRCUITPY_STORAGE)
CIRCUITPY_STORAGE_EXTEND ?= $(CIRCUITPY_DUALBANK)
CFLAGS += -DCIRCUITPY_STORAGE_EXTEND=$(CIRCUITPY_STORAGE_EXTEND)
CIRCUITPY_STRUCT ?= 1
CFLAGS += -DCIRCUITPY_STRUCT=$(CIRCUITPY_STRUCT)

17
py/gc.c
View File

@ -138,7 +138,6 @@ void gc_init(void *start, void *end) {
MP_STATE_MEM(gc_alloc_table_start) = (byte *)start;
#if MICROPY_ENABLE_FINALISER
size_t gc_finaliser_table_byte_len = (MP_STATE_MEM(gc_alloc_table_byte_len) * BLOCKS_PER_ATB + BLOCKS_PER_FTB - 1) / BLOCKS_PER_FTB;
MP_STATE_MEM(gc_finaliser_table_start) = MP_STATE_MEM(gc_alloc_table_start) + MP_STATE_MEM(gc_alloc_table_byte_len) + 1;
#endif
@ -147,18 +146,16 @@ void gc_init(void *start, void *end) {
MP_STATE_MEM(gc_pool_end) = end;
#if MICROPY_ENABLE_FINALISER
size_t gc_finaliser_table_byte_len = (MP_STATE_MEM(gc_alloc_table_byte_len) * BLOCKS_PER_ATB + BLOCKS_PER_FTB - 1) / BLOCKS_PER_FTB;
(void)gc_finaliser_table_byte_len; // avoid unused variable diagnostic if asserts are disabled
assert(MP_STATE_MEM(gc_pool_start) >= MP_STATE_MEM(gc_finaliser_table_start) + gc_finaliser_table_byte_len);
#endif
// Clear ATBs plus one more byte. The extra byte might be read when we read the final ATB and
// then try to count its tail. Clearing the byte ensures it is 0 and ends the chain. Without an
// FTB, it'll just clear the pool byte early.
memset(MP_STATE_MEM(gc_alloc_table_start), 0, MP_STATE_MEM(gc_alloc_table_byte_len) + 1);
#if MICROPY_ENABLE_FINALISER
// clear FTBs
memset(MP_STATE_MEM(gc_finaliser_table_start), 0, gc_finaliser_table_byte_len);
#endif
// Clear ATBs & finalisers (if enabled). This also clears the extra byte
// which appears between ATBs and finalisers that ensures every chain in
// the ATB terminates, rather than erroneously using bits from the
// finalisers.
memset(MP_STATE_MEM(gc_alloc_table_start), 0, MP_STATE_MEM(gc_pool_start) - MP_STATE_MEM(gc_alloc_table_start));
// Set first free ATB index to the start of the heap.
for (size_t i = 0; i < MICROPY_ATB_INDICES; i++) {

View File

@ -25,7 +25,7 @@
*/
#include "py/mperrno.h"
#include "py/ioctl.h"
#include "py/stream.h"
#include "py/objproperty.h"
#include "py/runtime.h"
#include "py/stream.h"
@ -138,15 +138,15 @@ STATIC mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t r
check_for_deinit(self);
raise_error_if_not_connected(self);
mp_uint_t ret;
if (request == MP_IOCTL_POLL) {
if (request == MP_STREAM_POLL) {
mp_uint_t flags = arg;
ret = 0;
if ((flags & MP_IOCTL_POLL_RD) && common_hal_bleio_characteristic_buffer_rx_characters_available(self) > 0) {
ret |= MP_IOCTL_POLL_RD;
if ((flags & MP_STREAM_POLL_RD) && common_hal_bleio_characteristic_buffer_rx_characters_available(self) > 0) {
ret |= MP_STREAM_POLL_RD;
}
// No writing provided.
// if ((flags & MP_IOCTL_POLL_WR) && common_hal_busio_uart_ready_to_tx(self)) {
// ret |= MP_IOCTL_POLL_WR;
// if ((flags & MP_STREAM_POLL_WR) && common_hal_busio_uart_ready_to_tx(self)) {
// ret |= MP_STREAM_POLL_WR;
// }
} else {
*errcode = MP_EINVAL;

View File

@ -25,7 +25,7 @@
*/
#include "py/mperrno.h"
#include "py/ioctl.h"
#include "py/stream.h"
#include "py/objproperty.h"
#include "py/runtime.h"
#include "py/stream.h"

View File

@ -33,7 +33,7 @@
#include "shared/runtime/context_manager_helpers.h"
#include "shared/runtime/interrupt_char.h"
#include "py/ioctl.h"
#include "py/stream.h"
#include "py/objproperty.h"
#include "py/objtype.h"
#include "py/runtime.h"
@ -276,14 +276,14 @@ STATIC mp_uint_t busio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t
busio_uart_obj_t *self = native_uart(self_in);
check_for_deinit(self);
mp_uint_t ret;
if (request == MP_IOCTL_POLL) {
if (request == MP_STREAM_POLL) {
mp_uint_t flags = arg;
ret = 0;
if ((flags & MP_IOCTL_POLL_RD) && common_hal_busio_uart_rx_characters_available(self) > 0) {
ret |= MP_IOCTL_POLL_RD;
if ((flags & MP_STREAM_POLL_RD) && common_hal_busio_uart_rx_characters_available(self) > 0) {
ret |= MP_STREAM_POLL_RD;
}
if ((flags & MP_IOCTL_POLL_WR) && common_hal_busio_uart_ready_to_tx(self)) {
ret |= MP_IOCTL_POLL_WR;
if ((flags & MP_STREAM_POLL_WR) && common_hal_busio_uart_ready_to_tx(self)) {
ret |= MP_STREAM_POLL_WR;
}
} else {
*errcode = MP_EINVAL;

View File

@ -26,6 +26,10 @@
#include "shared-bindings/dualbank/__init__.h"
#if CIRCUITPY_STORAGE_EXTEND
#include "supervisor/flash.h"
#endif
//| """DUALBANK Module
//|
//| The `dualbank` module adds ability to update and switch
@ -55,6 +59,14 @@
//| """
//| ...
#if CIRCUITPY_STORAGE_EXTEND
STATIC void raise_error_if_storage_extended(void) {
if (supervisor_flash_get_extended()) {
mp_raise_msg_varg(&mp_type_RuntimeError, translate("%q is %q"), MP_QSTR_storage, MP_QSTR_extended);
}
}
#endif
//| def flash(buffer: ReadableBuffer, offset: int = 0) -> None:
//| """Writes one of two app partitions at the given offset.
//|
@ -70,6 +82,10 @@ STATIC mp_obj_t dualbank_flash(size_t n_args, const mp_obj_t *pos_args, mp_map_t
{ MP_QSTR_offset, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
};
#if CIRCUITPY_STORAGE_EXTEND
raise_error_if_storage_extended();
#endif
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@ -94,6 +110,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(dualbank_flash_obj, 0, dualbank_flash);
//| ...
//|
STATIC mp_obj_t dualbank_switch(void) {
#if CIRCUITPY_STORAGE_EXTEND
raise_error_if_storage_extended();
#endif
common_hal_dualbank_switch();
return mp_const_none;
}

View File

@ -24,7 +24,7 @@
* THE SOFTWARE.
*/
#include "py/ioctl.h"
#include "py/stream.h"
#include "py/mperrno.h"
#include "py/objproperty.h"
#include "py/runtime.h"
@ -147,8 +147,8 @@ STATIC mp_uint_t eventqueue_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t
case MP_STREAM_POLL: {
mp_uint_t flags = arg;
mp_uint_t ret = 0;
if ((flags & MP_IOCTL_POLL_RD) && common_hal_keypad_eventqueue_get_length(self)) {
ret |= MP_IOCTL_POLL_RD;
if ((flags & MP_STREAM_POLL_RD) && common_hal_keypad_eventqueue_get_length(self)) {
ret |= MP_STREAM_POLL_RD;
}
return ret;
}

View File

@ -104,7 +104,11 @@ MP_PROPERTY_GETTER(mcu_processor_reset_reason_obj,
//| temperature: Optional[float]
//| """The on-chip temperature, in Celsius, as a float. (read-only)
//|
//| Is `None` if the temperature is not available."""
//| Is `None` if the temperature is not available.
//|
//| .. note :: On small SAMD21 builds without external flash,
//| the reported temperature has reduced accuracy and precision, to save code space.
//| """
STATIC mp_obj_t mcu_processor_get_temperature(mp_obj_t self) {
float temperature = common_hal_mcu_processor_get_temperature();
return isnan(temperature) ? mp_const_none : mp_obj_new_float(temperature);

View File

@ -248,6 +248,17 @@ STATIC mp_obj_t os_urandom(mp_obj_t size_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
//| def utime(path: str, times: Tuple[int, int]) -> None:
//| """Change the timestamp of a file."""
//| ...
//|
STATIC mp_obj_t os_utime(mp_obj_t path_in, mp_obj_t times_in) {
const char *path = mp_obj_str_get_str(path_in);
common_hal_os_utime(path, times_in);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(os_utime_obj, os_utime);
STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_os) },
@ -264,6 +275,7 @@ STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&os_stat_obj) },
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&os_statvfs_obj) },
{ MP_ROM_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&os_remove_obj) }, // unlink aliases to remove
{ MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&os_utime_obj) },
{ MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&os_sync_obj) },

View File

@ -45,6 +45,7 @@ void common_hal_os_rename(const char *old_path, const char *new_path);
void common_hal_os_rmdir(const char *path);
mp_obj_t common_hal_os_stat(const char *path);
mp_obj_t common_hal_os_statvfs(const char *path);
void common_hal_os_utime(const char *path, mp_obj_t times);
// Returns true if data was correctly sourced from a true random number generator.
bool common_hal_os_urandom(uint8_t *buffer, mp_uint_t length);

View File

@ -34,6 +34,7 @@
#include "py/runtime.h"
#include "shared-bindings/storage/__init__.h"
#include "supervisor/shared/translate/translate.h"
#include "supervisor/flash.h"
//| """Storage management
//|
@ -150,7 +151,7 @@ STATIC mp_obj_t storage_getmount(const mp_obj_t mnt_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(storage_getmount_obj, storage_getmount);
//| def erase_filesystem() -> None:
//| def erase_filesystem(extended: Optional[bool] = None) -> None:
//| """Erase and re-create the ``CIRCUITPY`` filesystem.
//|
//| On boards that present USB-visible ``CIRCUITPY`` drive (e.g., SAMD21 and SAMD51),
@ -160,16 +161,38 @@ MP_DEFINE_CONST_FUN_OBJ_1(storage_getmount_obj, storage_getmount);
//| This function can be called from the REPL when ``CIRCUITPY``
//| has become corrupted.
//|
//| :param bool extended: On boards that support ``dualbank`` module
//| and the ``extended`` parameter, the ``CIRCUITPY`` storage can be
//| extended by setting this to `True`. If this isn't provided or
//| set to `None` (default), the existing configuration will be used.
//|
//| .. warning:: All the data on ``CIRCUITPY`` will be lost, and
//| CircuitPython will restart on certain boards."""
//| ...
//|
STATIC mp_obj_t storage_erase_filesystem(void) {
common_hal_storage_erase_filesystem();
STATIC mp_obj_t storage_erase_filesystem(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_extended };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_extended, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
#if CIRCUITPY_STORAGE_EXTEND
bool extended = (args[ARG_extended].u_obj == mp_const_none) ? supervisor_flash_get_extended() : mp_obj_is_true(args[ARG_extended].u_obj);
common_hal_storage_erase_filesystem(extended);
#else
if (mp_obj_is_true(args[ARG_extended].u_obj)) {
mp_raise_NotImplementedError_varg(translate("%q=%q"), MP_QSTR_extended, MP_QSTR_True);
}
common_hal_storage_erase_filesystem(false);
#endif
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(storage_erase_filesystem_obj, storage_erase_filesystem);
MP_DEFINE_CONST_FUN_OBJ_KW(storage_erase_filesystem_obj, 0, storage_erase_filesystem);
//| def disable_usb_drive() -> None:
//| """Disable presenting ``CIRCUITPY`` as a USB mass storage device.

View File

@ -37,7 +37,7 @@ void common_hal_storage_umount_path(const char *path);
void common_hal_storage_umount_object(mp_obj_t vfs_obj);
void common_hal_storage_remount(const char *path, bool readonly, bool disable_concurrent_write_protection);
mp_obj_t common_hal_storage_getmount(const char *path);
void common_hal_storage_erase_filesystem(void);
void common_hal_storage_erase_filesystem(bool extended);
bool common_hal_storage_disable_usb_drive(void);
bool common_hal_storage_enable_usb_drive(void);

View File

@ -29,7 +29,7 @@
#include "shared-bindings/terminalio/Terminal.h"
#include "shared-bindings/util.h"
#include "py/ioctl.h"
#include "py/stream.h"
#include "py/objproperty.h"
#include "py/objstr.h"
#include "py/runtime.h"
@ -111,11 +111,11 @@ STATIC mp_uint_t terminalio_terminal_write(mp_obj_t self_in, const void *buf_in,
STATIC mp_uint_t terminalio_terminal_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
terminalio_terminal_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_uint_t ret;
if (request == MP_IOCTL_POLL) {
if (request == MP_STREAM_POLL) {
mp_uint_t flags = arg;
ret = 0;
if ((flags & MP_IOCTL_POLL_WR) && common_hal_terminalio_terminal_ready_to_tx(self)) {
ret |= MP_IOCTL_POLL_WR;
if ((flags & MP_STREAM_POLL_WR) && common_hal_terminalio_terminal_ready_to_tx(self)) {
ret |= MP_STREAM_POLL_WR;
}
} else {
*errcode = MP_EINVAL;

View File

@ -38,7 +38,45 @@
//| """
//| ...
STATIC void traceback_exception_common(mp_print_t *print, mp_obj_t value, mp_obj_t tb_obj, mp_obj_t limit_obj) {
STATIC void traceback_exception_common(bool is_print_exception, mp_print_t *print, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_exc, ARG_value, ARG_tb, ARG_limit, ARG_file, ARG_chain };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_value, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_tb, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_limit, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_file, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_chain, MP_ARG_BOOL, {.u_bool = true} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
mp_obj_t value = args[ARG_value].u_obj;
if (value == MP_OBJ_NULL) {
value = args[ARG_exc].u_obj;
}
mp_obj_t tb_obj = args[ARG_tb].u_obj;
mp_obj_t limit_obj = args[ARG_limit].u_obj;
if (args[ARG_file].u_obj != mp_const_none) {
if (!is_print_exception) {
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
mp_arg_error_terse_mismatch();
#else
mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("unexpected keyword argument '%q'"), MP_QSTR_file);
#endif
}
#if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES
mp_get_stream_raise(args[ARG_file].u_obj, MP_STREAM_OP_WRITE);
print->data = MP_OBJ_TO_PTR(args[ARG_file].u_obj);
print->print_strn = mp_stream_write_adaptor;
#else
mp_raise_NotImplementedError(translate("file write is not available"));
#endif
}
if (!mp_obj_is_exception_instance(value)) {
mp_raise_TypeError(translate("invalid exception"));
}
@ -53,7 +91,9 @@ STATIC void traceback_exception_common(mp_print_t *print, mp_obj_t value, mp_obj
mp_obj_exception_t *exc = mp_obj_exception_get_native(value);
mp_obj_traceback_t *trace_backup = exc->traceback;
if (tb_obj != mp_const_none && print_tb) {
if (tb_obj == MP_OBJ_NULL) {
/* Print the traceback's exception as is */
} else if (tb_obj != mp_const_none && print_tb) {
exc->traceback = mp_arg_validate_type(tb_obj, &mp_type_traceback, MP_QSTR_tb);
} else {
exc->traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj;
@ -64,14 +104,24 @@ STATIC void traceback_exception_common(mp_print_t *print, mp_obj_t value, mp_obj
}
//| def format_exception(
//| etype: Type[BaseException],
//| value: BaseException,
//| tb: TracebackType,
//| exc: BaseException | Type[BaseException],
//| /,
//| value: Optional[BaseException] = None,
//| tb: Optional[TracebackType] = None,
//| limit: Optional[int] = None,
//| chain: Optional[bool] = True,
//| ) -> None:
//| ) -> List[str]:
//| """Format a stack trace and the exception information.
//|
//| If the exception value is passed in ``exc``, then this exception value and its
//| associated traceback are used. This is compatible with CPython 3.10 and newer.
//|
//| If the exception value is passed in ``value``, then any value passed in for
//| ``exc`` is ignored. ``value`` is used as the exception value and the
//| traceback in the ``tb`` argument is used. In this case, if ``tb`` is None,
//| no traceback will be shown. This is compatible with CPython 3.5 and
//| newer.
//|
//| The arguments have the same meaning as the corresponding arguments
//| to print_exception(). The return value is a list of strings, each
//| ending in a newline and some containing internal newlines. When
@ -80,54 +130,50 @@ STATIC void traceback_exception_common(mp_print_t *print, mp_obj_t value, mp_obj
//|
//| .. note:: Setting ``chain`` will have no effect as chained exceptions are not yet implemented.
//|
//| :param Type[BaseException] etype: This is ignored and inferred from the type of ``value``.
//| :param BaseException value: The exception. Must be an instance of `BaseException`.
//| :param TracebackType tb: The traceback object. If `None`, the traceback will not be printed.
//| :param exc: The exception. Must be an instance of `BaseException`. Unused if value is specified.
//| :param value: If specified, is used in place of ``exc``.
//| :param TracebackType tb: When value is alsp specified, ``tb`` is used in place of the exception's own traceback. If `None`, the traceback will not be printed.
//| :param int limit: Print up to limit stack trace entries (starting from the callers frame) if limit is positive.
//| Otherwise, print the last ``abs(limit)`` entries. If limit is omitted or None, all entries are printed.
//| :param bool chain: If `True` then chained exceptions will be printed (note: not yet implemented).
//|
//| """
//| ...
//|
STATIC mp_obj_t traceback_format_exception(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_etype, ARG_value, ARG_tb, ARG_limit, ARG_chain };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_etype, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_value, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_tb, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_limit, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_chain, MP_ARG_BOOL, {.u_bool = true} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
mp_print_t print;
vstr_t vstr;
vstr_init_print(&vstr, 0, &print);
traceback_exception_common(&print, args[ARG_value].u_obj, args[ARG_tb].u_obj, args[ARG_limit].u_obj);
return mp_obj_new_str_from_vstr(&mp_type_str, &vstr);
traceback_exception_common(false, &print, n_args, pos_args, kw_args);
mp_obj_t output = mp_obj_new_str_from_vstr(&mp_type_str, &vstr);
return mp_obj_new_list(1, &output);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(traceback_format_exception_obj, 0, traceback_format_exception);
//| def print_exception(
//| etype: Type[BaseException],
//| value: BaseException,
//| tb: TracebackType,
//| exc: BaseException | Type[BaseException],
//| /,
//| value: Optional[BaseException] = None,
//| tb: Optional[TracebackType] = None,
//| limit: Optional[int] = None,
//| file: Optional[io.FileIO] = None,
//| chain: Optional[bool] = True,
//| ) -> None:
//|
//| """Prints exception information and stack trace entries.
//|
//| If the exception value is passed in ``exc``, then this exception value and its
//| associated traceback are used. This is compatible with CPython 3.10 and newer.
//|
//| If the exception value is passed in ``value``, then any value passed in for
//| ``exc`` is ignored. ``value`` is used as the exception value and the
//| traceback in the ``tb`` argument is used. In this case, if ``tb`` is None,
//| no traceback will be shown. This is compatible with CPython 3.5 and
//| newer.
//|
//| .. note:: Setting ``chain`` will have no effect as chained exceptions are not yet implemented.
//|
//| :param Type[BaseException] etype: This is ignored and inferred from the type of ``value``.
//| :param BaseException value: The exception. Must be an instance of `BaseException`.
//| :param TracebackType tb: The traceback object. If `None`, the traceback will not be printed.
//| :param exc: The exception. Must be an instance of `BaseException`. Unused if value is specified.
//| :param value: If specified, is used in place of ``exc``.
//| :param tb: When value is alsp specified, ``tb`` is used in place of the exception's own traceback. If `None`, the traceback will not be printed.
//| :param int limit: Print up to limit stack trace entries (starting from the callers frame) if limit is positive.
//| Otherwise, print the last ``abs(limit)`` entries. If limit is omitted or None, all entries are printed.
//| :param io.FileIO file: If file is omitted or `None`, the output goes to `sys.stderr`; otherwise it should be an open
@ -139,31 +185,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(traceback_format_exception_obj, 0, traceback_f
//|
STATIC mp_obj_t traceback_print_exception(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_etype, ARG_value, ARG_tb, ARG_limit, ARG_file, ARG_chain };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_etype, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_value, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_tb, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_limit, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_file, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_chain, MP_ARG_BOOL, {.u_bool = true} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
mp_print_t print = mp_plat_print;
if (args[ARG_file].u_obj != mp_const_none) {
#if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES
mp_get_stream_raise(args[ARG_file].u_obj, MP_STREAM_OP_WRITE);
print.data = MP_OBJ_TO_PTR(args[ARG_file].u_obj);
print.print_strn = mp_stream_write_adaptor;
#else
mp_raise_NotImplementedError(translate("file write is not available"));
#endif
}
traceback_exception_common(&print, args[ARG_value].u_obj, args[ARG_tb].u_obj, args[ARG_limit].u_obj);
traceback_exception_common(true, &print, n_args, pos_args, kw_args);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(traceback_print_exception_obj, 0, traceback_print_exception);

View File

@ -29,7 +29,7 @@
#include "shared-bindings/usb_cdc/Serial.h"
#include "shared-bindings/util.h"
#include "py/ioctl.h"
#include "py/stream.h"
#include "py/objproperty.h"
#include "py/runtime.h"
#include "py/stream.h"
@ -114,14 +114,14 @@ STATIC mp_uint_t usb_cdc_serial_ioctl_stream(mp_obj_t self_in, mp_uint_t request
usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_uint_t ret = 0;
switch (request) {
case MP_IOCTL_POLL: {
case MP_STREAM_POLL: {
mp_uint_t flags = arg;
ret = 0;
if ((flags & MP_IOCTL_POLL_RD) && common_hal_usb_cdc_serial_get_in_waiting(self) > 0) {
ret |= MP_IOCTL_POLL_RD;
if ((flags & MP_STREAM_POLL_RD) && common_hal_usb_cdc_serial_get_in_waiting(self) > 0) {
ret |= MP_STREAM_POLL_RD;
}
if ((flags & MP_IOCTL_POLL_WR) && common_hal_usb_cdc_serial_get_out_waiting(self) == 0) {
ret |= MP_IOCTL_POLL_WR;
if ((flags & MP_STREAM_POLL_WR) && common_hal_usb_cdc_serial_get_out_waiting(self) == 0) {
ret |= MP_STREAM_POLL_WR;
}
break;
}

View File

@ -29,7 +29,7 @@
#include "shared-bindings/usb_midi/PortIn.h"
#include "shared-bindings/util.h"
#include "py/ioctl.h"
#include "py/stream.h"
#include "py/objproperty.h"
#include "py/runtime.h"
#include "py/stream.h"
@ -81,11 +81,11 @@ STATIC mp_uint_t usb_midi_portin_read(mp_obj_t self_in, void *buf_in, mp_uint_t
STATIC mp_uint_t usb_midi_portin_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
usb_midi_portin_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_uint_t ret;
if (request == MP_IOCTL_POLL) {
if (request == MP_STREAM_POLL) {
mp_uint_t flags = arg;
ret = 0;
if ((flags & MP_IOCTL_POLL_RD) && common_hal_usb_midi_portin_bytes_available(self) > 0) {
ret |= MP_IOCTL_POLL_RD;
if ((flags & MP_STREAM_POLL_RD) && common_hal_usb_midi_portin_bytes_available(self) > 0) {
ret |= MP_STREAM_POLL_RD;
}
} else {
*errcode = MP_EINVAL;

View File

@ -29,7 +29,7 @@
#include "shared-bindings/usb_midi/PortOut.h"
#include "shared-bindings/util.h"
#include "py/ioctl.h"
#include "py/stream.h"
#include "py/objproperty.h"
#include "py/runtime.h"
#include "py/stream.h"
@ -64,11 +64,11 @@ STATIC mp_uint_t usb_midi_portout_write(mp_obj_t self_in, const void *buf_in, mp
STATIC mp_uint_t usb_midi_portout_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
usb_midi_portout_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_uint_t ret;
if (request == MP_IOCTL_POLL) {
if (request == MP_STREAM_POLL) {
mp_uint_t flags = arg;
ret = 0;
if ((flags & MP_IOCTL_POLL_WR) && common_hal_usb_midi_portout_ready_to_tx(self)) {
ret |= MP_IOCTL_POLL_WR;
if ((flags & MP_STREAM_POLL_WR) && common_hal_usb_midi_portout_ready_to_tx(self)) {
ret |= MP_STREAM_POLL_WR;
}
} else {
*errcode = MP_EINVAL;

View File

@ -29,6 +29,7 @@
#include "shared-bindings/dotenv/__init__.h"
#include "py/misc.h"
#include "py/mpstate.h"
#include "py/objstr.h"
#include "supervisor/filesystem.h"
@ -272,10 +273,17 @@ mp_obj_t common_hal_dotenv_get_key(const char *path, const char *key) {
return mp_const_none;
}
if ((size_t)actual_len >= sizeof(value)) {
mp_obj_str_t *str = MP_OBJ_TO_PTR(mp_obj_new_str_copy(&mp_type_str, NULL, actual_len + 1));
dotenv_get_key(path, key, (char *)str->data, actual_len + 1);
str->hash = qstr_compute_hash(str->data, actual_len);
return MP_OBJ_FROM_PTR(str);
byte *buf = m_new(byte, actual_len + 1);
dotenv_get_key(path, key, (char *)buf, actual_len);
buf[actual_len] = 0;
mp_obj_str_t *o = m_new_obj(mp_obj_str_t);
o->base.type = &mp_type_str;
o->len = actual_len;
o->data = buf;
o->hash = qstr_compute_hash(buf, actual_len);
return MP_OBJ_FROM_PTR(o);
}
return mp_obj_new_str(value, actual_len);
}

View File

@ -226,3 +226,10 @@ mp_obj_t common_hal_os_statvfs(const char *path) {
}
return mp_vfs_proxy_call(vfs, MP_QSTR_statvfs, 1, &path_out);
}
void common_hal_os_utime(const char *path, mp_obj_t times) {
mp_obj_t args[2];
mp_vfs_mount_t *vfs = lookup_path(path, &args[0]);
args[1] = times;
mp_vfs_proxy_call(vfs, MP_QSTR_utime, 2, args);
}

View File

@ -267,11 +267,14 @@ void common_hal_storage_remount(const char *mount_path, bool readonly, bool disa
filesystem_set_internal_concurrent_write_protection(!disable_concurrent_write_protection);
}
void common_hal_storage_erase_filesystem(void) {
void common_hal_storage_erase_filesystem(bool extended) {
#if CIRCUITPY_USB
usb_disconnect();
#endif
mp_hal_delay_ms(1000);
#if CIRCUITPY_STORAGE_EXTEND
supervisor_flash_set_extended(extended);
#endif
(void)filesystem_init(false, true); // Force a re-format. Ignore failure.
common_hal_mcu_reset();
// We won't actually get here, since we're resetting.

View File

@ -28,6 +28,8 @@
#include <stddef.h>
#include <string.h>
#include "py/mpconfig.h"
#ifndef likely
#define likely(x) __builtin_expect((x), 1)
#endif
@ -35,6 +37,7 @@
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
void *memcpy(void *dst, const void *src, size_t n) {
#if CIRCUITPY_FULL_BUILD
if (likely(!(((uintptr_t)dst) & 3) && !(((uintptr_t)src) & 3))) {
// pointers aligned
uint32_t *d = dst;
@ -56,7 +59,9 @@ void *memcpy(void *dst, const void *src, size_t n) {
// copy byte
*((uint8_t*)d) = *((const uint8_t*)s);
}
} else {
} else
#endif
{
// unaligned access, copy bytes
uint8_t *d = dst;
const uint8_t *s = src;
@ -93,6 +98,7 @@ void *memmove(void *dest, const void *src, size_t n) {
}
void *memset(void *s, int c, size_t n) {
#if CIRCUITPY_FULL_BUILD
if (c == 0 && ((uintptr_t)s & 3) == 0) {
// aligned store of 0
uint32_t *s32 = s;
@ -106,7 +112,9 @@ void *memset(void *s, int c, size_t n) {
if (n & 1) {
*((uint8_t*)s32) = 0;
}
} else {
} else
#endif
{
uint8_t *s2 = s;
for (; n > 0; n--) {
*s2++ = c;

View File

@ -50,4 +50,8 @@ void supervisor_flash_init_vfs(struct _fs_user_mount_t *vfs);
void supervisor_flash_flush(void);
void supervisor_flash_release_cache(void);
void supervisor_flash_set_extended(bool extended);
bool supervisor_flash_get_extended(void);
void supervisor_flash_update_extended(void);
#endif // MICROPY_INCLUDED_SUPERVISOR_FLASH_H

View File

@ -143,16 +143,22 @@ bool filesystem_init(bool create_allowed, bool force_create) {
} else if (res != FR_OK) {
return false;
}
vfs->str = "/";
vfs->len = 1;
vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
vfs->next = NULL;
MP_STATE_VM(vfs_mount_table) = vfs;
// The current directory is used as the boot up directory.
// It is set to the internal flash filesystem by default.
MP_STATE_PORT(vfs_cur) = vfs;
#if CIRCUITPY_STORAGE_EXTEND
supervisor_flash_update_extended();
#endif
return true;
}

View File

@ -23,3 +23,15 @@ quoted_then_comment='value'#comment
hash_with_spaces=#value value
aa🐍bb=key with emoji
value_with_emoji=aa🐍bb
sz0=x
sz1=xx
sz2=xxxx
sz3=xxxxxxxx
sz4=xxxxxxxxxxxxxxxx
sz5=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
sz6=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
sz7=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
sz8=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
sz9=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
sz10=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
sz11=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

View File

@ -25,3 +25,7 @@ print(f"quoted_then_comment={dotenv.get_key(FILE, 'quoted_then_comment')}")
print(f"hash_with_spaces={dotenv.get_key(FILE, 'hash_with_spaces')}")
print(f"aa🐍bb={dotenv.get_key(FILE, 'aa🐍bb')}")
print(f"value_with_emoji={dotenv.get_key(FILE, 'value_with_emoji')}")
for i in range(12):
key = f"sz{i}"
print(f"len({key})={len(dotenv.get_key(FILE, key))}")

View File

@ -21,3 +21,15 @@ quoted_then_comment=value
hash_with_spaces=#value value
aa🐍bb=key with emoji
value_with_emoji=aa🐍bb
len(sz0)=1
len(sz1)=2
len(sz2)=4
len(sz3)=8
len(sz4)=16
len(sz5)=32
len(sz6)=64
len(sz7)=128
len(sz8)=256
len(sz9)=512
len(sz10)=1024
len(sz11)=2048

View File

@ -15,13 +15,13 @@ except Exception as exc:
print("\nNo Trace:")
traceback.print_exception(None, exc, None)
print("\nDefault Trace:")
traceback.print_exception(None, exc, exc.__traceback__)
traceback.print_exception(exc)
print("\nLimit=1 Trace:")
traceback.print_exception(None, exc, exc.__traceback__, limit=1)
print("\nLimit=0 Trace:")
traceback.print_exception(None, exc, exc.__traceback__, limit=0)
print("\nLimit=-1 Trace:")
traceback.print_exception(None, exc, exc.__traceback__, limit=-1)
print("".join(traceback.format_exception(None, exc, exc.__traceback__, limit=-1)), end="")
class NonNativeException(Exception):

71
tools/ci_set_matrix.py Normal file → Executable file
View File

@ -12,6 +12,13 @@ on the event that triggered run. Pull request runs will compare to the
base branch while pushes will compare to the current ref. We override this
for the adafruit/circuitpython repo so we build all docs/boards for pushes.
When making changes to the script it is useful to manually test it.
You can for instance run
```shell
tools/ci_set_matrix ports/raspberrypi/common-hal/socket/SSLSocket.c
```
and (at the time this comment was written) get a series of messages indicating
that only the single board raspberry_pi_pico_w would be built.
"""
import re
@ -19,9 +26,21 @@ import os
import sys
import json
import yaml
import pathlib
from concurrent.futures import ThreadPoolExecutor
tools_dir = pathlib.Path(__file__).resolve().parent
top_dir = tools_dir.parent
sys.path.insert(0, str(tools_dir / "adabot"))
sys.path.insert(0, str(top_dir / "docs"))
import build_board_info
from shared_bindings_matrix import get_settings_from_makefile
from shared_bindings_matrix import (
get_settings_from_makefile,
SUPPORTED_PORTS,
all_ports_all_boards,
)
PORT_TO_ARCH = {
"atmel-samd": "arm",
@ -40,12 +59,17 @@ IGNORE = [
"tools/ci_check_duplicate_usb_vid_pid.py",
]
changed_files = {}
try:
changed_files = json.loads(os.environ["CHANGED_FILES"])
except json.decoder.JSONDecodeError as exc:
if exc.msg != "Expecting value":
raise
if len(sys.argv) > 1:
print("Using files list on commandline")
changed_files = sys.argv[1:]
else:
c = os.environ["CHANGED_FILES"]
if c == "":
print("CHANGED_FILES is in environment, but value is empty")
changed_files = []
else:
print("Using files list in CHANGED_FILES")
changed_files = json.loads(os.environ["CHANGED_FILES"])
def set_output(name, value):
@ -53,7 +77,7 @@ def set_output(name, value):
with open(os.environ["GITHUB_OUTPUT"], "at") as f:
print(f"{name}={value}", file=f)
else:
print("Would set GitHub actions output {name} to '{value}'")
print(f"Would set GitHub actions output {name} to '{value}'")
def set_boards_to_build(build_all):
@ -74,6 +98,20 @@ def set_boards_to_build(build_all):
port_to_boards[port].add(board_id)
board_to_port[board_id] = port
def compute_board_settings(boards):
need = set(boards) - set(board_settings.keys())
if not need:
return
def get_settings(board):
return (
board,
get_settings_from_makefile(str(top_dir / "ports" / board_to_port[board]), board),
)
with ThreadPoolExecutor(max_workers=os.cpu_count()) as ex:
board_settings.update(ex.map(get_settings, need))
boards_to_build = all_board_ids
if not build_all:
@ -81,7 +119,7 @@ def set_boards_to_build(build_all):
board_pattern = re.compile(r"^ports/[^/]+/boards/([^/]+)/")
port_pattern = re.compile(r"^ports/([^/]+)/")
module_pattern = re.compile(
r"^(ports/[^/]+/common-hal|shared-bindings|shared-module)/([^/]+)/"
r"^(ports/[^/]+/(?:common-hal|bindings)|shared-bindings|shared-module)/([^/]+)/"
)
for p in changed_files:
# See if it is board specific
@ -93,9 +131,9 @@ def set_boards_to_build(build_all):
# See if it is port specific
port_matches = port_pattern.search(p)
port = port_matches.group(1) if port_matches else None
module_matches = module_pattern.search(p)
if port_matches and not module_matches:
port = port_matches.group(1)
if port and not module_matches:
if port != "unix":
boards_to_build.update(port_to_boards[port])
continue
@ -111,11 +149,12 @@ def set_boards_to_build(build_all):
# As a (nearly) last resort, for some certain files, we compute the settings from the
# makefile for each board and determine whether to build them that way.
if p.startswith("frozen") or p.startswith("supervisor") or module_matches:
for board in all_board_ids:
if board not in board_settings:
board_settings[board] = get_settings_from_makefile(
"../ports/" + board_to_port[board], board
)
if port:
board_ids = port_to_boards[port]
else:
board_ids = all_board_ids
compute_board_settings(board_ids)
for board in board_ids:
settings = board_settings[board]
# Check frozen files to see if they are in each board.