summaryrefslogtreecommitdiff
path: root/supervisor
diff options
context:
space:
mode:
authorJeff Epler <jepler@gmail.com>2020-09-24 11:20:32 -0500
committerJeff Epler <jepler@gmail.com>2020-09-28 18:55:56 -0500
commit726dcdb60aa84b5070e5484a19e896abdaffeb93 (patch)
tree24cb3b01a1805353dd8a27335faad09a917df60a /supervisor
parent6bfcb01ee79d49f470a1a8ca5e693ba92fadf307 (diff)
Add some NORETURN attributes
I have a function where it should be impossible to reach the end, so I put in a safe-mode reset at the bottom: ``` int find_unused_slot(void) { // precondition: you already verified that a slot was available for (int i=0; i<NUM_SLOTS; i++) { if( slot_free(i)) { return i; } } safe_mode_reset(MICROPY_FATAL_ERROR); } ``` However, the compiler still gave a diagnostic, because safe_mode_reset was not declared NORETURN. So I started by teaching the compiler that reset_into_safe_mode never returned. This leads at least one level deeper due to reset_cpu needing to be a NORETURN function. Each port is a little different in this area. I also marked reset_to_bootloader as NORETURN. Additional notes: * stm32's reset_to_bootloader was not implemented, but now does a bare reset. Most stm32s are not fitted with uf2 bootloaders anyway. * ditto cxd56 * esp32s2 did not implement reset_cpu at all. I used esp_restart(). (not tested) * litex did not implement reset_cpu at all. I used reboot_ctrl_write. But notably this is what reset_to_bootloader already did, so one or the other must be incorrect (not tested). reboot_ctrl_write cannot be declared NORETURN, as it returns unless the special value 0xac is written), so a new unreachable forever-loop is added. * cxd56's reset is via a boardctl() call which can't generically be declared NORETURN, so a new unreacahble "for(;;)" forever-loop is added. * In several places, NVIC_SystemReset is redeclared with NORETURN applied. This is accepted just fine by gcc. I chose this as preferable to editing the multiple copies of CMSIS headers where it is normally declared. * the stub safe_mode reset simply aborts. This is used in mpy-cross.
Diffstat (limited to 'supervisor')
-rw-r--r--supervisor/port.h4
-rw-r--r--supervisor/shared/safe_mode.h4
-rw-r--r--supervisor/stub/safe_mode.c5
3 files changed, 8 insertions, 5 deletions
diff --git a/supervisor/port.h b/supervisor/port.h
index ddb96bd52..f5b3c15d1 100644
--- a/supervisor/port.h
+++ b/supervisor/port.h
@@ -44,7 +44,7 @@ extern uint32_t _ebss;
safe_mode_t port_init(void);
// Reset the microcontroller completely.
-void reset_cpu(void);
+void reset_cpu(void) NORETURN;
// Reset the microcontroller state.
void reset_port(void);
@@ -53,7 +53,7 @@ void reset_port(void);
void reset_board(void);
// Reset to the bootloader
-void reset_to_bootloader(void);
+void reset_to_bootloader(void) NORETURN;
// Get stack limit address
uint32_t *port_stack_get_limit(void);
diff --git a/supervisor/shared/safe_mode.h b/supervisor/shared/safe_mode.h
index 7d3cd63b5..34fc3c8ae 100644
--- a/supervisor/shared/safe_mode.h
+++ b/supervisor/shared/safe_mode.h
@@ -27,6 +27,8 @@
#ifndef MICROPY_INCLUDED_SUPERVISOR_SAFE_MODE_H
#define MICROPY_INCLUDED_SUPERVISOR_SAFE_MODE_H
+#include "py/mpconfig.h"
+
typedef enum {
NO_SAFE_MODE = 0,
BROWNOUT,
@@ -48,7 +50,7 @@ typedef enum {
safe_mode_t wait_for_safe_mode_reset(void);
void safe_mode_on_next_reset(safe_mode_t reason);
-void reset_into_safe_mode(safe_mode_t reason);
+void reset_into_safe_mode(safe_mode_t reason) NORETURN;
void print_safe_mode_message(safe_mode_t reason);
diff --git a/supervisor/stub/safe_mode.c b/supervisor/stub/safe_mode.c
index 8072be2c6..a70ac6b6d 100644
--- a/supervisor/stub/safe_mode.c
+++ b/supervisor/stub/safe_mode.c
@@ -26,14 +26,15 @@
#include "supervisor/shared/safe_mode.h"
+#include <stdlib.h>
+
safe_mode_t wait_for_safe_mode_reset(void) {
return NO_SAFE_MODE;
}
void reset_into_safe_mode(safe_mode_t reason) {
(void) reason;
- for (;;) {
- }
+ abort();
}
void print_safe_mode_message(safe_mode_t reason) {