8000 atmel-samd: Rework boot, main and REPL order. · sparkfun/circuitpython@790c38e · GitHub
[go: up one dir, main page]

Skip to content

Commit 790c38e

Browse files
committed
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.
1 parent 7672bf7 commit 790c38e

File tree

10 files changed

+118
-29
lines changed

10 files changed

+118
-29
lines changed

atmel-samd/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ SRC_C = \
183183
autoreload.c \
184184
builtin_open.c \
185185
fatfs_port.c \
186+
flash_api.c \
186187
main.c \
187188
moduos.c \
188189
mphalport.c \

atmel-samd/flash_api.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include "flash_api.h"
28+
29+
#include "py/mpstate.h"
30+
31+
#define VFS_INDEX 0
32+
33+
void flash_set_usb_writeable(bool usb_writeable) {
34+
if (VFS_INDEX >= MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount))) {
8000 35+
return;
36+
}
37+
fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[VFS_INDEX];
38+
if (vfs == NULL) {
39+
return;
40+
}
41+
42+
if (usb_writeable) {
43+
vfs->flags |= FSUSER_USB_WRITEABLE;
44+
} else {
45+
vfs->flags &= ~FSUSER_USB_WRITEABLE;
46+
}
47+
}

atmel-samd/flash_api.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,11 @@
2626
#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H__
2727
#define __MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H__
2828

29+
#include "extmod/fsusermount.h"
30+
2931
extern void flash_init_vfs(fs_user_mount_t *vfs);
3032
extern void flash_flush(void);
3133

34+
void flash_set_usb_writeable(bool usb_writeable);
35+
3236
#endif // __MICROPY_INCLUDED_ATMEL_SAMD_FLASH_API_H__

atmel-samd/internal_flash.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ const mp_obj_type_t internal_flash_type = {
293293
};
294294

295295
void flash_init_vfs(fs_user_mount_t *vfs) {
296-
vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL | FSUSER_USB_WRITEABLE;
296+
vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
297297
vfs->readblocks[0] = (mp_obj_t)&internal_flash_obj_readblocks_obj;
298298
vfs->readblocks[1] = (mp_obj_t)&internal_flash_obj;
299299
vfs->readblocks[2] = (mp_obj_t)internal_flash_read_blocks; // native version

atmel-samd/main.c

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,6 @@ void init_flash_fs(void) {
8686
if (res == FR_NO_FILESYSTEM) {
8787
// no filesystem so create a fresh one
8888

89-
// We are before USB initializes so temporarily undo the USB_WRITEABLE
90-
// requirement.
91-
bool usb_writeable = (vfs->flags & FSUSER_USB_WRITEABLE) > 0;
92-
vfs->flags &= ~FSUSER_USB_WRITEABLE;
93-
9489
res = f_mkfs("/flash", 0, 0);
9590
// Flush the new file system to make sure its repaired immediately.
9691
flash_flush();
@@ -101,10 +96,6 @@ void init_flash_fs(void) {
10196

10297
// set label
10398
f_setlabel("CIRCUITPY");
104-
105-
if (usb_writeable) {
106-
vfs->flags |= FSUSER_USB_WRITEABLE;
107-
}
10899
} else if (res != FR_OK) {
109100
MP_STATE_PORT(fs_user_mount)[0] = NULL;
110101
return;
@@ -251,21 +242,13 @@ bool start_mp(void) {
251242
mp_hal_stdout_tx_str("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\r\n");
252243
}
253244
#endif
254-
255-
new_status_color(BOOT_RUNNING);
256-
pyexec_result_t result;
257-
bool found_boot = maybe_run("settings.txt", &result) ||
258-
maybe_run("settings.py", &result) ||
259-
maybe_run("boot.py", &result) ||
260-
maybe_run("boot.txt", &result);
261245
bool found_main = false;
262-
if (!found_boot || !(result.return_code & PYEXEC_FORCED_EXIT)) {
263-
new_status_color(MAIN_RUNNING);
264-
found_main = maybe_run("code.txt", &result) ||
265-
maybe_run("code.py", &result) ||
266-
maybe_run("main.py", &result) ||
267-
maybe_run("main.txt", &result);
268-
}
246+
pyexec_result_t result;
247+
new_status_color(MAIN_RUNNING);
248+
found_main = maybe_run("code.txt", &result) ||
249+
maybe_run("code.py", &result) ||
250+
maybe_run("main.py", &result) ||
251+
maybe_run("main.txt", &result);
269252
reset_status_led();
270253

271254
if (result.return_code & PYEXEC_FORCED_EXIT) {
@@ -520,37 +503,73 @@ int main(void) {
520503
// as current dir.
521504
init_flash_fs();
522505

506+
// Reset everything and prep MicroPython to run boot.py.
507+
reset_samd21();
508+
reset_mp();
509+
510+
// Run boot before initing USB and capture output in a file.
511+
new_status_color(BOOT_RUNNING);
512+
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
513+
FIL file_pointer;
514+
boot_output_file = &file_pointer;
515+
FRESULT result = f_open(boot_output_f 10000 ile, CIRCUITPY_BOOT_OUTPUT_FILE, FA_WRITE | FA_CREATE_ALWAYS);
516+
if (result != FR_OK) {
517+
while (true) {}
518+
}
519+
#endif
520+
521+
// TODO(tannewt): Re-add support for flashing boot error output.
522+
bool found_boot = maybe_run("settings.txt", NULL) ||
523+
maybe_run("settings.py", NULL) ||
524+
maybe_run("boot.py", NULL) ||
525+
maybe_run("boot.txt", NULL);
526+
(void) found_boot;
527+
528+
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
529+
f_close(boot_output_file);
530+
boot_output_file = NULL;
531+
#endif
532+
533+
// Turn off local writing in favor of USB writing prior to initializing USB.
534+
flash_set_usb_writeable(true);
535+
523536
usb_hid_init();
524537

525538
// Start USB after getting everything going.
526539
#ifdef USB_REPL
527540
udc_start();
528541
#endif
529542

543+
// Reset to remove any state that boot.py setup. It should only be used to
544+
// change internal state thats not in the heap.
545+
reset_samd21();
546+
reset_mp();
530547

531-
// Main script is finished, so now go into REPL mode.
532-
// The REPL mode can change, or it can request a reload.
548+
// Boot script is finished, so now go into REPL/main mode.
533549
int exit_code = PYEXEC_FORCED_EXIT;
534550
bool skip_repl = true;
535551
bool first_run = true;
536552
for (;;) {
537553
if (!skip_repl) {
554+
// The REPL mode can change, or it can request a reload.
538555
autoreload_disable();
539556
new_status_color(REPL_RUNNING);
540557
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
541558
exit_code = pyexec_raw_repl();
542559
} else {
543560
exit_code = pyexec_friendly_repl();
544561
}
562+
reset_samd21();
563+
reset_mp();
545564
}
546565
if (exit_code == PYEXEC_FORCED_EXIT) {
547566
if (!first_run) {
548567
mp_hal_stdout_tx_str("soft reboot\r\n");
549568
}
550-
reset_samd21();
551-
reset_mp();
552569
first_run = false;
553570
skip_repl = start_mp();
571+
reset_samd21();
572+
reset_mp();
554573
} else if (exit_code != 0) {
555574
break;
556575
}

atmel-samd/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,5 +204,6 @@ bool udi_msc_process_trans(void);
204204
#define MICROPY_VM_HOOK_RETURN udi_msc_process_trans();
205205

206206
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
207+
#define CIRCUITPY_BOOT_OUTPUT_FILE "/flash/boot_out.txt"
207208

208209
#endif // __INCLUDED_MPCONFIGPORT_H

atmel-samd/mphalport.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,13 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) {
191191
usart_write_buffer_wait(&usart_instance, (uint8_t*) str, len);
192192
#endif
193193

194+
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
195+
if (boot_output_file != NULL) {
196+
UINT bytes_written = 0;
197+
f_write(boot_output_file, str, len, &bytes_written);
198+
}
199+
#endif
200+
194201
#ifdef USB_REPL
195202
// Always make sure there is enough room in the usb buffer for the outgoing
196203
// string. If there isn't we risk getting caught in a loop within the usb

atmel-samd/mphalport.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929

3030
#include "py/obj.h"
3131

32+
#include "lib/fatfs/ff.h"
33+
3234
#define USB_RX_BUF_SIZE 128
3335

3436
// Global millisecond tick count (driven by SysTick interrupt).
@@ -41,6 +43,8 @@ static inline mp_uint_t mp_hal_ticks_ms(void) {
4143
volatile uint8_t usb_rx_count;
4244
volatile bool mp_cdc_enabled;
4345

46+
FIL* boot_output_file;
47+
4448
int receive_usb(void);
4549

4650
void mp_hal_set_interrupt_char(int c);

atmel-samd/spi_flash.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ const mp_obj_type_t spi_flash_type = {
661661
};
662662

663663
void flash_init_vfs(fs_user_mount_t *vfs) {
664-
vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL | FSUSER_USB_WRITEABLE;
664+
vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
665665
vfs->readblocks[0] = (mp_obj_t)&spi_flash_obj_readblocks_obj;
666666
vfs->readblocks[1] = (mp_obj_t)&spi_flash_obj;
667667
vfs->readblocks[2] = (mp_obj_t)spi_flash_read_blocks; // native version

extmod/fsusermount.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
* THE SOFTWARE.
2525
*/
2626

27+
28+
#ifndef __MICROPY_INCLUDED_EXTMOD_FSUSERMOUNT_H__
29+
#define __MICROPY_INCLUDED_EXTMOD_FSUSERMOUNT_H__
30+
2731
#include "lib/fatfs/ff.h"
2832
#include "py/obj.h"
2933

@@ -65,3 +69,5 @@ mp_obj_t fatfs_umount(mp_obj_t bdev_or_path_in);
6569
MP_DECLARE_CONST_FUN_OBJ_KW(fsuser_mount_obj);
6670
MP_DECLARE_CONST_FUN_OBJ_1(fsuser_umount_obj);
6771
MP_DECLARE_CONST_FUN_OBJ_KW(fsuser_mkfs_obj);
72+
73+
#endif // __MICROPY_INCLUDED_EXTMOD_FSUSERMOUNT_H__

0 commit comments

Comments
 (0)
0