Prevent infinite display update recursion and fix VFS mounting

Fixes #1529
This commit is contained in:
Scott Shawcroft 2019-02-14 12:54:34 -08:00
parent 4e75aaecd0
commit 46fd60c703
No known key found for this signature in database
GPG Key ID: FD0EDC4B6C53CA59
6 changed files with 31 additions and 29 deletions

View File

@ -186,12 +186,15 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar
break; break;
} }
} }
assert(vfs != NULL);
if ((vfs->flags & FSUSER_USB_WRITABLE) != 0 && (mode & FA_WRITE) != 0) {
mp_raise_OSError(MP_EROFS);
}
pyb_file_obj_t *o = m_new_obj_with_finaliser(pyb_file_obj_t); pyb_file_obj_t *o = m_new_obj_with_finaliser(pyb_file_obj_t);
o->base.type = type; o->base.type = type;
const char *fname = mp_obj_str_get_str(args[0].u_obj); const char *fname = mp_obj_str_get_str(args[0].u_obj);
assert(vfs != NULL);
FRESULT res = f_open(&vfs->fatfs, &o->fp, fname, mode); FRESULT res = f_open(&vfs->fatfs, &o->fp, fname, mode);
if (res != FR_OK) { if (res != FR_OK) {
m_del_obj(pyb_file_obj_t, o); m_del_obj(pyb_file_obj_t, o);

14
main.c
View File

@ -127,6 +127,20 @@ void stop_mp(void) {
#if CIRCUITPY_NETWORK #if CIRCUITPY_NETWORK
network_module_deinit(); network_module_deinit();
#endif #endif
#if MICROPY_VFS
mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table);
// Unmount all heap allocated vfs mounts.
while (gc_nbytes(vfs) > 0) {
vfs = vfs->next;
}
MP_STATE_VM(vfs_mount_table) = vfs;
MP_STATE_VM(vfs_cur) = vfs;
#endif
// Run any finalizers before we stop using the heap.
gc_sweep_all();
} }
#define STRING_LIST(...) {__VA_ARGS__, ""} #define STRING_LIST(...) {__VA_ARGS__, ""}

View File

@ -123,7 +123,6 @@
#define MICROPY_FATFS_USE_LABEL (1) #define MICROPY_FATFS_USE_LABEL (1)
#define MICROPY_FATFS_RPATH (2) #define MICROPY_FATFS_RPATH (2)
#define MICROPY_FATFS_MULTI_PARTITION (1) #define MICROPY_FATFS_MULTI_PARTITION (1)
#define MICROPY_FATFS_NUM_PERSISTENT (1)
// Only enable this if you really need it. It allocates a byte cache of this size. // Only enable this if you really need it. It allocates a byte cache of this size.
// #define MICROPY_FATFS_MAX_SS (4096) // #define MICROPY_FATFS_MAX_SS (4096)

View File

@ -131,31 +131,6 @@ void mp_init(void) {
sizeof(MP_STATE_VM(fs_user_mount)) - MICROPY_FATFS_NUM_PERSISTENT); sizeof(MP_STATE_VM(fs_user_mount)) - MICROPY_FATFS_NUM_PERSISTENT);
#endif #endif
#if MICROPY_VFS
#if MICROPY_FATFS_NUM_PERSISTENT > 0
// We preserve the last MICROPY_FATFS_NUM_PERSISTENT mounts because newer
// mounts are put at the front of the list.
mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table);
// Count how many mounts we have.
uint8_t count = 0;
while (vfs != NULL) {
vfs = vfs->next;
count++;
}
// Find the vfs MICROPY_FATFS_NUM_PERSISTENT mounts from the end.
vfs = MP_STATE_VM(vfs_mount_table);
for (uint8_t j = 0; j < count - MICROPY_FATFS_NUM_PERSISTENT; j++) {
vfs = vfs->next;
}
MP_STATE_VM(vfs_mount_table) = vfs;
MP_STATE_VM(vfs_cur) = vfs;
#else
// initialise the VFS sub-system
MP_STATE_VM(vfs_cur) = NULL;
MP_STATE_VM(vfs_mount_table) = NULL;
#endif
#endif
#if MICROPY_PY_THREAD_GIL #if MICROPY_PY_THREAD_GIL
mp_thread_mutex_init(&MP_STATE_VM(gil_mutex)); mp_thread_mutex_init(&MP_STATE_VM(gil_mutex));
#endif #endif

View File

@ -6,6 +6,7 @@
#include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/Display.h"
#include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Group.h"
#include "shared-bindings/displayio/Palette.h" #include "shared-bindings/displayio/Palette.h"
#include "supervisor/shared/autoreload.h"
#include "supervisor/shared/display.h" #include "supervisor/shared/display.h"
#include "supervisor/memory.h" #include "supervisor/memory.h"
#include "supervisor/usb.h" #include "supervisor/usb.h"
@ -18,7 +19,13 @@ static inline void swap(uint16_t* a, uint16_t* b) {
*b = temp; *b = temp;
} }
bool refreshing_displays = false;
void displayio_refresh_displays(void) { void displayio_refresh_displays(void) {
if (refreshing_displays) {
return;
}
refreshing_displays = true;
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
if (displays[i].display.base.type == NULL || displays[i].display.base.type == &mp_type_NoneType) { if (displays[i].display.base.type == NULL || displays[i].display.base.type == &mp_type_NoneType) {
continue; continue;
@ -27,6 +34,7 @@ void displayio_refresh_displays(void) {
displayio_display_update_backlight(display); displayio_display_update_backlight(display);
if (!displayio_display_frame_queued(display)) { if (!displayio_display_frame_queued(display)) {
refreshing_displays = false;
return; return;
} }
if (displayio_display_refresh_queued(display)) { if (displayio_display_refresh_queued(display)) {
@ -89,8 +97,9 @@ void displayio_refresh_displays(void) {
index += 1; index += 1;
// The buffer is full, send it. // The buffer is full, send it.
if (index >= buffer_size) { if (index >= buffer_size) {
if (!displayio_display_send_pixels(display, buffer, buffer_size / 2)) { if (!displayio_display_send_pixels(display, buffer, buffer_size / 2) || reload_requested) {
displayio_display_finish_region_update(display); displayio_display_finish_region_update(display);
refreshing_displays = false;
return; return;
} }
// TODO(tannewt): Make refresh displays faster so we don't starve other // TODO(tannewt): Make refresh displays faster so we don't starve other
@ -103,12 +112,14 @@ void displayio_refresh_displays(void) {
// Send the remaining data. // Send the remaining data.
if (index && !displayio_display_send_pixels(display, buffer, index * 2)) { if (index && !displayio_display_send_pixels(display, buffer, index * 2)) {
displayio_display_finish_region_update(display); displayio_display_finish_region_update(display);
refreshing_displays = false;
return; return;
} }
displayio_display_finish_region_update(display); displayio_display_finish_region_update(display);
} }
displayio_display_finish_refresh(display); displayio_display_finish_refresh(display);
} }
refreshing_displays = false;
} }
void common_hal_displayio_release_displays(void) { void common_hal_displayio_release_displays(void) {

View File

@ -95,7 +95,7 @@ void filesystem_flush(void) {
void filesystem_writable_by_python(bool writable) { void filesystem_writable_by_python(bool writable) {
fs_user_mount_t *vfs = &_internal_vfs; fs_user_mount_t *vfs = &_internal_vfs;
if (writable) { if (!writable) {
vfs->flags |= FSUSER_USB_WRITABLE; vfs->flags |= FSUSER_USB_WRITABLE;
} else { } else {
vfs->flags &= ~FSUSER_USB_WRITABLE; vfs->flags &= ~FSUSER_USB_WRITABLE;