Skip to content
Snippets Groups Projects
Verified Commit 604a5036 authored by rahix's avatar rahix
Browse files

Merge branch 'rahix/lifecycle'


This changeset implements a proper lifecycle of the core 1 payload.
The implementation faces some difficulties because there is no way to
properly reset just core 1.  Instead, we chose a cooperative approach:

To perform a reset, core 1 jumps to a reset-stub and is then fed a new
IVT location which it uses to "restart" with a new payload.  The jump to
the reset-stub is either voluntary by a call to epic_exit() or epix_exec(),
or involuntary by Epicardium issuing a "reset" interrupt.  This is a
special API interrupt whose handler is pre-implemented in the API-caller
lib.

Additionally, this changeset contains support for defining which python
script Pycardium should execute on startup.  This way, scripts can issue
the start of one another using `epic_exec("script-name.py")`.

Finally, this changeset also changes the power-button behavior.
Pressing the power button will now excert the following behavior:

    - `<400 ms`: Return back to menu
    - `<1 s`: Reset card10
    - `>1 s`: Poweroff

Signed-off-by: default avatarRahix <rahix@rahix.de>
parents 14930b38 d3c52d1c
No related branches found
No related tags found
No related merge requests found
...@@ -33,6 +33,9 @@ SECTIONS { ...@@ -33,6 +33,9 @@ SECTIONS {
.text : .text :
{ {
/* The vector table needs 128 byte alignment */
. = ALIGN(128);
KEEP(*(.text.isr_vector))
*(.text*) *(.text*)
*(.rodata*) *(.rodata*)
......
...@@ -3,7 +3,7 @@ l0dable_startup_lib = static_library( ...@@ -3,7 +3,7 @@ l0dable_startup_lib = static_library(
'crt.s', 'crt.s',
'hardware.c', 'hardware.c',
dependencies: [api_caller], dependencies: [api_caller],
pic: true, c_args: ['-fpie'],
) )
l0dable_startup = declare_dependency( l0dable_startup = declare_dependency(
......
...@@ -28,6 +28,13 @@ if get_option('debug_prints') ...@@ -28,6 +28,13 @@ if get_option('debug_prints')
) )
endif endif
if get_option('debug_core1')
add_global_arguments(
['-DCARD10_DEBUG_CORE1=1'],
language: 'c',
)
endif
add_global_link_arguments( add_global_link_arguments(
'-Wl,--gc-sections', '-Wl,--gc-sections',
'-lm', '-lm',
......
...@@ -6,6 +6,14 @@ option( ...@@ -6,6 +6,14 @@ option(
description: 'Whether to print debug messages on the serial console' description: 'Whether to print debug messages on the serial console'
) )
option(
'debug_core1',
type: 'boolean',
value: false,
description: 'Enable core 1 debugging interface'
)
option( option(
'ble_trace', 'ble_trace',
type: 'boolean', type: 'boolean',
......
#include "epicardium.h" #include "epicardium.h"
#include "api/caller.h"
#include "mphalport.h" #include "mphalport.h"
#include "card10-version.h" #include "card10-version.h"
...@@ -24,10 +25,19 @@ static const char header[] = ...@@ -24,10 +25,19 @@ static const char header[] =
int main(void) int main(void)
{ {
epic_uart_write_str(header, sizeof(header)); char script_name[128] = { 0 };
int cnt = api_fetch_args(script_name, sizeof(script_name));
pycardium_hal_init(); pycardium_hal_init();
epic_uart_write_str(header, sizeof(header));
if (cnt < 0) {
printf("pycardium: Error fetching args: %d\n", cnt);
} else if (cnt > 0) {
printf(" Loading %s ...\n", script_name);
}
mp_stack_set_top(&__StackTop); mp_stack_set_top(&__StackTop);
mp_stack_set_limit((mp_int_t)&__StackLimit); mp_stack_set_limit((mp_int_t)&__StackLimit);
...@@ -35,12 +45,22 @@ int main(void) ...@@ -35,12 +45,22 @@ int main(void)
gc_init(&__HeapBase + 1024 * 10, &__HeapLimit); gc_init(&__HeapBase + 1024 * 10, &__HeapLimit);
mp_init(); mp_init();
pyexec_file_if_exists("main.py");
if (cnt > 0) {
pyexec_file_if_exists(script_name);
}
pyexec_friendly_repl(); pyexec_friendly_repl();
mp_deinit(); mp_deinit();
} }
} }
void HardFault_Handler(void)
{
epic_exit(255);
}
void gc_collect(void) void gc_collect(void)
{ {
void *sp = (void *)__get_MSP(); void *sp = (void *)__get_MSP();
......
...@@ -6,6 +6,7 @@ modsrc = files( ...@@ -6,6 +6,7 @@ modsrc = files(
'modules/interrupt.c', 'modules/interrupt.c',
'modules/sys_leds.c', 'modules/sys_leds.c',
'modules/light_sensor.c', 'modules/light_sensor.c',
'modules/os.c',
'modules/sys_display.c', 'modules/sys_display.c',
'modules/utime.c', 'modules/utime.c',
'modules/vibra.c', 'modules/vibra.c',
......
#include "epicardium.h"
#include "py/obj.h"
#include "py/runtime.h"
#include <string.h>
static mp_obj_t mp_os_exit(size_t n_args, const mp_obj_t *args)
{
int ret = 0;
if (n_args == 1) {
ret = mp_obj_get_int(args[0]);
}
epic_exit(ret);
/* unreachable */
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(exit_obj, 0, 1, mp_os_exit);
static mp_obj_t mp_os_exec(mp_obj_t name_in)
{
const char *name_ptr;
char name_str[256];
size_t len, maxlen;
name_ptr = mp_obj_str_get_data(name_in, &len);
/*
* The string retrieved from MicroPython is not NULL-terminated so we
* first need to copy it and add a NULL-byte.
*/
maxlen = len < (sizeof(name_str) - 1) ? len : (sizeof(name_str) - 1);
memcpy(name_str, name_ptr, maxlen);
name_str[maxlen] = '\0';
int ret = epic_exec(name_str);
/*
* If epic_exec() returns, something went wrong. We can raise an
* exception in all cases.
*/
mp_raise_OSError(-ret);
/* unreachable */
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_1(exec_obj, mp_os_exec);
static const mp_rom_map_elem_t os_module_gobals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_os) },
{ MP_ROM_QSTR(MP_QSTR_exit), MP_ROM_PTR(&exit_obj) },
{ MP_ROM_QSTR(MP_QSTR_exec), MP_ROM_PTR(&exec_obj) },
};
static MP_DEFINE_CONST_DICT(os_module_globals, os_module_gobals_table);
const mp_obj_module_t os_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&os_module_globals,
};
/* This is a special macro that will make MicroPython aware of this module */
/* clang-format off */
MP_REGISTER_MODULE(MP_QSTR_os, os_module, MODULE_OS_ENABLED);
...@@ -85,3 +85,7 @@ Q(tell) ...@@ -85,3 +85,7 @@ Q(tell)
Q(TextIOWrapper) Q(TextIOWrapper)
Q(write) Q(write)
/* os */
Q(os)
Q(exit)
Q(exec)
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#define MODULE_INTERRUPT_ENABLED (1) #define MODULE_INTERRUPT_ENABLED (1)
#define MODULE_LEDS_ENABLED (1) #define MODULE_LEDS_ENABLED (1)
#define MODULE_LIGHT_SENSOR_ENABLED (1) #define MODULE_LIGHT_SENSOR_ENABLED (1)
#define MODULE_OS_ENABLED (1)
#define MODULE_UTIME_ENABLED (1) #define MODULE_UTIME_ENABLED (1)
#define MODULE_VIBRA_ENABLED (1) #define MODULE_VIBRA_ENABLED (1)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment