Skip to content

Commit

Permalink
Merge pull request #886 from UncleGrumpy/stm32_abort
Browse files Browse the repository at this point in the history
Enable STM32 abort
  • Loading branch information
fadushin authored Oct 24, 2023
2 parents 3dd1630 + ce85667 commit 33da149
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 5 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Fixed a bug where guards would raise exceptions instead of just being false
- Fixed support for big endian CPUs (such as some MIPS CPUs).
- Fixed STM32 not aborting when `AVM_ABORT()` is used
- Fixed a bug that would leave the STM32 trapped in a loop on hard faults, rather than aborting

### Added

- Added support for the OTP `socket` interface.
- Enhancd performance of STM32 by enabling flash cache and i-cache with branch prediction.
- Added cmake configuration option `AVM_CONFIG_REBOOT_ON_NOT_OK` for STM32

## [0.6.0-alpha.1] - 2023-10-09

Expand Down
3 changes: 3 additions & 0 deletions doc/src/build-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,9 @@ is 8N1 with no flow control.

> If building for a different target USART and gpio pins may need to be adjusted in `main.c`.
### Configuring for "deployment"
After your application has been tested (_and debugged_) and is ready to put into active use you may want to tune the build of AtomVM. For instance disabling logging with `-DAVM_LOG_DISABLE=on` as a `cmake` configuration option may result in slightly better performance. This will have no affect on the console output of your application, just disable low level log messages from the AtomVM system. You may also want to enabling automatic reboot in the case that your application ever exits with a return other than `ok`. This can be enabled with the `cmake` option `-DAVM_CONFIG_REBOOT_ON_NOT_OK=on`.

## Building for Raspberry Pi Pico

### Prerequisites
Expand Down
7 changes: 6 additions & 1 deletion src/platforms/stm32/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ option(AVM_NEWLIB_NANO "Use 'nano' newlib. Saves 46kB, no `long long` support" O
option(AVM_LOG_DISABLE "Disable log output" OFF)
option(AVM_ENABLE_LOG_COLOR "Use color log output" OFF)
option(AVM_ENABLE_LOG_LINES "Include source and line info for all enbled levels" OFF)
option(AVM_CONFIG_REBOOT_ON_NOT_OK "Reboot when application exits with non 'ok' return" OFF)

set(AVM_DISABLE_SMP ON FORCE)

Expand All @@ -40,7 +41,11 @@ if (AVM_NEWLIB_NANO)
set(AVM_LOG_DISABLE ON FORCE)
endif()

# Configure logging
if (AVM_CONFIG_REBOOT_ON_NOT_OK)
add_compile_definitions(CONFIG_REBOOT_ON_NOT_OK)
endif()

# Configure logging
if (AVM_LOG_DISABLE)
add_compile_definitions(AVM_LOG_DISABLE)
elseif (AVM_LOG_LEVEL_MAX)
Expand Down
63 changes: 59 additions & 4 deletions src/platforms/stm32/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,21 @@
*/

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

#include <libopencm3/cm3/cortex.h>
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/cm3/scb.h>
#include <libopencm3/cm3/systick.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/usart.h>

#include <avmpack.h>
#include <context.h>
#include <defaultatoms.h>
#include <globalcontext.h>
#include <module.h>
#include <utils.h>
Expand Down Expand Up @@ -61,6 +65,8 @@
"\n"

int _write(int file, char *ptr, int len);
pid_t _getpid(void);
int _kill(pid_t pid, int sig);

static void clock_setup()
{
Expand Down Expand Up @@ -124,6 +130,31 @@ int _write(int file, char *ptr, int len)
return -1;
}

// newlib stubs to support AVM_ABORT
pid_t _getpid()
{
return 1;
}

int _kill(pid_t pid, int sig)
{
UNUSED(pid);
if (sig == SIGABRT) {
fprintf(stderr, "Aborted\n");
} else {
fprintf(stderr, "Unknown signal %d\n", sig);
}
errno = EINVAL;
return -1;
}

// Redefine weak linked while(1) loop from libopencm3/cm3/nvic.h.
void hard_fault_handler()
{
fprintf(stderr, "\nHard Fault detected!\n");
AVM_ABORT();
}

int main()
{
// Flash cache must be enabled before system clock is activated
Expand Down Expand Up @@ -172,11 +203,35 @@ int main()
ctx->leader = 1;

AVM_LOGI(TAG, "Starting: %s...\n", startup_module_name);
context_execute_loop(ctx, mod, "start", 0);
AVM_LOGI(TAG, "Return value: %lx", (long) term_to_int32(ctx->x[0]));
fprintf(stdout, "---\n");

while (1)
;
context_execute_loop(ctx, mod, "start", 0);

term ret_value = ctx->x[0];
char *ret_atom_string = interop_atom_to_string(ctx, ret_value);
if (ret_atom_string != NULL) {
AVM_LOGI(TAG, "Exited with return: %s", ret_atom_string);
} else {
AVM_LOGI(TAG, "Exited with return value: %lx", (long) term_to_int32(ret_value));
}
free(ret_atom_string);

bool reboot_on_not_ok =
#if defined(CONFIG_REBOOT_ON_NOT_OK)
CONFIG_REBOOT_ON_NOT_OK ? true : false;
#else
false;
#endif
if (reboot_on_not_ok && ret_value != OK_ATOM) {
AVM_LOGE(TAG, "AtomVM application terminated with non-ok return value. Rebooting ...");
scb_reset_system();
} else {
AVM_LOGI(TAG, "AtomVM application terminated. Going to sleep forever ...");
// Disable all interrupts
cm_disable_interrupts();
while (1) {
;
}
}
return 0;
}

0 comments on commit 33da149

Please sign in to comment.