atmel-samd: Rework boot, main and REPL order.
Boot will only run once now before USB is started. Its output goes to boot_out.txt. After main and REPL will run with VM and hardware resets between each.
This commit is contained in:
parent
7672bf7736
commit
790c38e18c
|
@ -183,6 +183,7 @@ SRC_C = \
|
|||
autoreload.c \
|
||||
builtin_open.c \
|
||||
fatfs_port.c \
|
||||
flash_api.c \
|
||||
main.c \
|
||||
moduos.c \
|
||||
mphalport.c \
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 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 "flash_api.h"
|
||||
|
||||
#include "py/mpstate.h"
|
||||
|
||||
#define VFS_INDEX 0
|
||||
|
||||
void flash_set_usb_writeable(bool usb_writeable) {
|
||||
if (VFS_INDEX >= MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount))) {
|
||||
return;
|
||||
}
|
||||
fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[VFS_INDEX];
|
||||
if (vfs == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (usb_writeable) {
|
||||
vfs->flags |= FSUSER_USB_WRITEABLE;
|
||||
} else {
|
||||
vfs->flags &= ~FSUSER_USB_WRITEABLE;
|
||||
}
|
||||
}
|
|
@ -26,7 +26,11 @@
|
|||
#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H__
|
||||
#define __MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H__
|
||||
|
||||
#include "extmod/fsusermount.h"
|
||||
|
||||
extern void flash_init_vfs(fs_user_mount_t *vfs);
|
||||
extern void flash_flush(void);
|
||||
|
||||
void flash_set_usb_writeable(bool usb_writeable);
|
||||
|
||||
#endif // __MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H__
|
||||
|
|
|
@ -293,7 +293,7 @@ const mp_obj_type_t internal_flash_type = {
|
|||
};
|
||||
|
||||
void flash_init_vfs(fs_user_mount_t *vfs) {
|
||||
vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL | FSUSER_USB_WRITEABLE;
|
||||
vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
|
||||
vfs->readblocks[0] = (mp_obj_t)&internal_flash_obj_readblocks_obj;
|
||||
vfs->readblocks[1] = (mp_obj_t)&internal_flash_obj;
|
||||
vfs->readblocks[2] = (mp_obj_t)internal_flash_read_blocks; // native version
|
||||
|
|
|
@ -86,11 +86,6 @@ void init_flash_fs(void) {
|
|||
if (res == FR_NO_FILESYSTEM) {
|
||||
// no filesystem so create a fresh one
|
||||
|
||||
// We are before USB initializes so temporarily undo the USB_WRITEABLE
|
||||
// requirement.
|
||||
bool usb_writeable = (vfs->flags & FSUSER_USB_WRITEABLE) > 0;
|
||||
vfs->flags &= ~FSUSER_USB_WRITEABLE;
|
||||
|
||||
res = f_mkfs("/flash", 0, 0);
|
||||
// Flush the new file system to make sure its repaired immediately.
|
||||
flash_flush();
|
||||
|
@ -101,10 +96,6 @@ void init_flash_fs(void) {
|
|||
|
||||
// set label
|
||||
f_setlabel("CIRCUITPY");
|
||||
|
||||
if (usb_writeable) {
|
||||
vfs->flags |= FSUSER_USB_WRITEABLE;
|
||||
}
|
||||
} else if (res != FR_OK) {
|
||||
MP_STATE_PORT(fs_user_mount)[0] = NULL;
|
||||
return;
|
||||
|
@ -251,21 +242,13 @@ bool start_mp(void) {
|
|||
mp_hal_stdout_tx_str("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
new_status_color(BOOT_RUNNING);
|
||||
pyexec_result_t result;
|
||||
bool found_boot = maybe_run("settings.txt", &result) ||
|
||||
maybe_run("settings.py", &result) ||
|
||||
maybe_run("boot.py", &result) ||
|
||||
maybe_run("boot.txt", &result);
|
||||
bool found_main = false;
|
||||
if (!found_boot || !(result.return_code & PYEXEC_FORCED_EXIT)) {
|
||||
new_status_color(MAIN_RUNNING);
|
||||
found_main = maybe_run("code.txt", &result) ||
|
||||
maybe_run("code.py", &result) ||
|
||||
maybe_run("main.py", &result) ||
|
||||
maybe_run("main.txt", &result);
|
||||
}
|
||||
pyexec_result_t result;
|
||||
new_status_color(MAIN_RUNNING);
|
||||
found_main = maybe_run("code.txt", &result) ||
|
||||
maybe_run("code.py", &result) ||
|
||||
maybe_run("main.py", &result) ||
|
||||
maybe_run("main.txt", &result);
|
||||
reset_status_led();
|
||||
|
||||
if (result.return_code & PYEXEC_FORCED_EXIT) {
|
||||
|
@ -520,6 +503,36 @@ int main(void) {
|
|||
// as current dir.
|
||||
init_flash_fs();
|
||||
|
||||
// Reset everything and prep MicroPython to run boot.py.
|
||||
reset_samd21();
|
||||
reset_mp();
|
||||
|
||||
// Run boot before initing USB and capture output in a file.
|
||||
new_status_color(BOOT_RUNNING);
|
||||
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
|
||||
FIL file_pointer;
|
||||
boot_output_file = &file_pointer;
|
||||
FRESULT result = f_open(boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_WRITE | FA_CREATE_ALWAYS);
|
||||
if (result != FR_OK) {
|
||||
while (true) {}
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO(tannewt): Re-add support for flashing boot error output.
|
||||
bool found_boot = maybe_run("settings.txt", NULL) ||
|
||||
maybe_run("settings.py", NULL) ||
|
||||
maybe_run("boot.py", NULL) ||
|
||||
maybe_run("boot.txt", NULL);
|
||||
(void) found_boot;
|
||||
|
||||
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
|
||||
f_close(boot_output_file);
|
||||
boot_output_file = NULL;
|
||||
#endif
|
||||
|
||||
// Turn off local writing in favor of USB writing prior to initializing USB.
|
||||
flash_set_usb_writeable(true);
|
||||
|
||||
usb_hid_init();
|
||||
|
||||
// Start USB after getting everything going.
|
||||
|
@ -527,14 +540,18 @@ int main(void) {
|
|||
udc_start();
|
||||
#endif
|
||||
|
||||
// Reset to remove any state that boot.py setup. It should only be used to
|
||||
// change internal state thats not in the heap.
|
||||
reset_samd21();
|
||||
reset_mp();
|
||||
|
||||
// Main script is finished, so now go into REPL mode.
|
||||
// The REPL mode can change, or it can request a reload.
|
||||
// Boot script is finished, so now go into REPL/main mode.
|
||||
int exit_code = PYEXEC_FORCED_EXIT;
|
||||
bool skip_repl = true;
|
||||
bool first_run = true;
|
||||
for (;;) {
|
||||
if (!skip_repl) {
|
||||
// The REPL mode can change, or it can request a reload.
|
||||
autoreload_disable();
|
||||
new_status_color(REPL_RUNNING);
|
||||
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
|
||||
|
@ -542,15 +559,17 @@ int main(void) {
|
|||
} else {
|
||||
exit_code = pyexec_friendly_repl();
|
||||
}
|
||||
reset_samd21();
|
||||
reset_mp();
|
||||
}
|
||||
if (exit_code == PYEXEC_FORCED_EXIT) {
|
||||
if (!first_run) {
|
||||
mp_hal_stdout_tx_str("soft reboot\r\n");
|
||||
}
|
||||
reset_samd21();
|
||||
reset_mp();
|
||||
first_run = false;
|
||||
skip_repl = start_mp();
|
||||
reset_samd21();
|
||||
reset_mp();
|
||||
} else if (exit_code != 0) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -204,5 +204,6 @@ bool udi_msc_process_trans(void);
|
|||
#define MICROPY_VM_HOOK_RETURN udi_msc_process_trans();
|
||||
|
||||
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
|
||||
#define CIRCUITPY_BOOT_OUTPUT_FILE "/flash/boot_out.txt"
|
||||
|
||||
#endif // __INCLUDED_MPCONFIGPORT_H
|
||||
|
|
|
@ -191,6 +191,13 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) {
|
|||
usart_write_buffer_wait(&usart_instance, (uint8_t*) str, len);
|
||||
#endif
|
||||
|
||||
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
|
||||
if (boot_output_file != NULL) {
|
||||
UINT bytes_written = 0;
|
||||
f_write(boot_output_file, str, len, &bytes_written);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USB_REPL
|
||||
// Always make sure there is enough room in the usb buffer for the outgoing
|
||||
// string. If there isn't we risk getting caught in a loop within the usb
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include "py/obj.h"
|
||||
|
||||
#include "lib/fatfs/ff.h"
|
||||
|
||||
#define USB_RX_BUF_SIZE 128
|
||||
|
||||
// Global millisecond tick count (driven by SysTick interrupt).
|
||||
|
@ -41,6 +43,8 @@ static inline mp_uint_t mp_hal_ticks_ms(void) {
|
|||
volatile uint8_t usb_rx_count;
|
||||
volatile bool mp_cdc_enabled;
|
||||
|
||||
FIL* boot_output_file;
|
||||
|
||||
int receive_usb(void);
|
||||
|
||||
void mp_hal_set_interrupt_char(int c);
|
||||
|
|
|
@ -661,7 +661,7 @@ const mp_obj_type_t spi_flash_type = {
|
|||
};
|
||||
|
||||
void flash_init_vfs(fs_user_mount_t *vfs) {
|
||||
vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL | FSUSER_USB_WRITEABLE;
|
||||
vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
|
||||
vfs->readblocks[0] = (mp_obj_t)&spi_flash_obj_readblocks_obj;
|
||||
vfs->readblocks[1] = (mp_obj_t)&spi_flash_obj;
|
||||
vfs->readblocks[2] = (mp_obj_t)spi_flash_read_blocks; // native version
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __MICROPY_INCLUDED_EXTMOD_FSUSERMOUNT_H__
|
||||
#define __MICROPY_INCLUDED_EXTMOD_FSUSERMOUNT_H__
|
||||
|
||||
#include "lib/fatfs/ff.h"
|
||||
#include "py/obj.h"
|
||||
|
||||
|
@ -65,3 +69,5 @@ mp_obj_t fatfs_umount(mp_obj_t bdev_or_path_in);
|
|||
MP_DECLARE_CONST_FUN_OBJ_KW(fsuser_mount_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_1(fsuser_umount_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_KW(fsuser_mkfs_obj);
|
||||
|
||||
#endif // __MICROPY_INCLUDED_EXTMOD_FSUSERMOUNT_H__
|
||||
|
|
Loading…
Reference in New Issue