Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
25c3e3a
validated ota app userland app support for current kernel
viswajith-g Nov 8, 2023
276d048
added apploader test userland application
viswajith-g Feb 17, 2024
200b874
rebase and add examples/test/app_loader. New app binaries are located…
viswajith-g Mar 29, 2024
174faed
example to work with async loading
viswajith-g Jun 27, 2024
96c8201
added two new apps
viswajith-g Feb 1, 2025
bc61042
Switched to newer libtock interface for app_loader apps.
viswajith-g Feb 2, 2025
c5a1ce2
moved syscall wrappers to their own file and moved binaries.h and pyt…
viswajith-g Feb 12, 2025
d74768d
clean up and revert lvgl version change
viswajith-g Feb 13, 2025
b6347d1
added abort test + refactored code for other apps.
viswajith-g Feb 16, 2025
f747b64
revert lvgl update
viswajith-g Feb 19, 2025
14c6442
cleanup
viswajith-g Feb 19, 2025
b2e42db
check if process loading succeeded based on result in upcall + addres…
viswajith-g Feb 27, 2025
d7f452d
modified to match kernel at impl.
viswajith-g Mar 5, 2025
fea7646
updated abort_test.c to include finalize()
viswajith-g Mar 5, 2025
4d90efb
removed padding bytes from blink and adc binaries
viswajith-g Mar 6, 2025
b36ed65
examples: tests: app_loader: clean up
viswajith-g May 1, 2025
646bf31
changed app_binaries directory structure
viswajith-g May 3, 2025
fe5c634
new directory structure for app_binaries and fix libtock function cal…
viswajith-g May 3, 2025
93cd91d
split apps into separate files + changed app input to console
viswajith-g May 4, 2025
730699f
tests: app_loader: abort_test: fix ci-format error
viswajith-g May 5, 2025
3adec04
tests: abort-test: remove extra debug print statement
viswajith-g May 5, 2025
f5ab812
make abort test standalone
viswajith-g May 5, 2025
d96b600
WIP: Automate app image creation; hard-coded arch, buttons only
ppannuto May 28, 2025
3b94ff6
WIP: convert abort-test to auto-build
ppannuto May 28, 2025
3fff30a
remove python utility
ppannuto May 28, 2025
55eff7b
make app embeds arch-agnostic
ppannuto May 29, 2025
0871279
add check for trailing slash in paths
ppannuto May 29, 2025
b19cffc
add fallback for xxd-based embed
ppannuto May 29, 2025
e20a02f
AppLoaderSupport.mk: comment explaining gcc version dependency + chan…
viswajith-g May 29, 2025
a3e8f0b
fix ci failure
viswajith-g May 29, 2025
fcaf3bd
just disable #embed completely for now :(
ppannuto May 29, 2025
6922fbc
separate app load logic from button press + abort-test upkeep
viswajith-g May 29, 2025
c38f85b
apploader: build embedded app if-needed
ppannuto May 30, 2025
71c80ed
button_press_loading: make button ISR simpler
viswajith-g Jun 4, 2025
323baf0
update main code and makefiles to match tutorial type format
viswajith-g Jul 24, 2025
c3d1d56
tests: app_loader: add gitignore
viswajith-g Jul 24, 2025
7b20e82
redistribute logic from test main.c to app_loader.c
viswajith-g Jul 24, 2025
3f4f056
tests: app_loader: add uninstall test app + matching syscalls and wra…
viswajith-g Jul 25, 2025
d00dfbb
libtock: kernel: app_loader: remove leftover lines from rebase + form…
viswajith-g Jul 25, 2025
6759946
fix ci build failure
viswajith-g Jul 25, 2025
bb8e912
write() now accepts chunks of binaryinstead of all of it at once
viswajith-g Jul 26, 2025
be4c51e
match abort_test's write() implementation with the new write() signature
viswajith-g Jul 26, 2025
c73e000
tut: dyn_app_load: update app_loader to match new interface
viswajith-g Jul 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Helpers.mk
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ check_no_spaces = \
$(if $(findstring $(strip $($(strip $1))),$($(strip $1))),,$(error Error: Space in variable $(strip $1))) \
$(if $(word 2,$($(strip $1))),$(error Error: Multiple entries in variable $(strip $1)),)

# Reject directory paths with trailing slashes.
#
# Params:
# 1. Variable name holding path to test.
reject_trailing_slash = \
$(if $(filter $(dir $1),$1),$(error Error: Trailing slash in path "$1"))

# Check for a ~/ at the beginning of a path variable (TOCK_USERLAND_BASE_DIR).
# Make will not properly expand this.
ifdef TOCK_USERLAND_BASE_DIR
Expand Down
1 change: 1 addition & 0 deletions examples/tests/app_loader/abort-test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
loadable_binaries.h
14 changes: 14 additions & 0 deletions examples/tests/app_loader/abort-test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Makefile for user application

# Specify this directory relative to the current application.
TOCK_USERLAND_BASE_DIR = ../../../..

# Which files to compile.
C_SRCS := $(wildcard *.c)

# List of apps to generate embed rules for
APPS_TO_EMBED := \
$(TOCK_USERLAND_BASE_DIR)/examples/tests/adc/adc

# Include app loading support rules. Rules to generate app binary images.
include ../support/CommonAppMake.mk
9 changes: 9 additions & 0 deletions examples/tests/app_loader/abort-test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Dynamic App Loader Abort Test (Helper App)
============================================
This app showcases the ability of the `abort` functionality of
the Dynamic Process Loader.

When the app boots, it tries to load the `adc` app, aborts midway
and logs the result. Ideally, we should see:
`[Success] Abort Successful.`, and the `abort-test` app should
terminate.
125 changes: 125 additions & 0 deletions examples/tests/app_loader/abort-test/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#include <math.h>
#include <stdio.h>
#include <string.h>

#include <libtock-sync/interface/console.h>
#include <libtock-sync/services/alarm.h>
#include <libtock/kernel/app_loader.h>
#include <libtock/tock.h>

#include "loadable_binaries.h"

/******************************************************************************************************
* Callback Tracking Flags
******************************************************************************************************/
static bool setup_done = false; // to check if setup is done
static bool abort_done = false; // to check if write abort was successful
volatile bool abort_flag = false; // track if abort request was sent
uint32_t write_buffer_size = 4096;

/******************************************************************************************************
* Function Prototypes
******************************************************************************************************/
void abort_test(void);

/******************************************************************************************************
* Callback functions
*
* 1. Set callback to initiate the dynamic app load process
* 2. Set callback to call `abort()` with a timer
*******************************************************************************************************/

static void app_setup_done_callback(__attribute__((unused)) int arg0,
__attribute__((unused)) int arg1,
__attribute__((unused)) int arg2,
__attribute__((unused)) void* ud) {
setup_done = true;
}

static void app_abort_done_callback(__attribute__((unused)) int arg0,
__attribute__((unused)) int arg1,
__attribute__((unused)) int arg2,
__attribute__((unused)) void* ud) {
abort_done = true;
}

static void abort_alarm_cb(__attribute__ ((unused)) uint32_t now,
__attribute__ ((unused)) uint32_t scheduled,
__attribute__ ((unused)) void* opaque) {
printf("[Timer] Triggering abort now.\n");
abort_flag = true;
int ret = libtock_app_loader_abort(app_abort_done_callback);
if (ret != RETURNCODE_SUCCESS) {
printf("[Error] Abort Failed: %d.\n", ret);
}

// wait on abort done callback
yield_for(&abort_done);
abort_done = false;
printf("[Success] Abort Successful.\n");
}

/******************************************************************************************************
* Function to test the abort functionality of Tock's dynamic app loading feature set
*
* Takes callback function as argument
******************************************************************************************************/

void abort_test(void) {

libtock_alarm_t abort_alarm;

unsigned char* app_data = (uint8_t*)(uintptr_t)binaries[0];
size_t app_size = binary_sizes[0];
size_t binary_size = actual_sizes[0];

int ret = libtock_app_loader_setup(app_size, app_setup_done_callback);
if (ret != RETURNCODE_SUCCESS) {
printf("[Error] Setup Failed: %d.\n", ret);
tock_exit(ret);
}

// wait on setup done callback
yield_for(&setup_done);
setup_done = false;

libtock_alarm_in_ms(150, abort_alarm_cb, NULL, &abort_alarm);

size_t offset = 0;
while (offset < binary_size) {
if (abort_flag) break;
size_t chunk_len = (binary_size - offset > write_buffer_size)
? write_buffer_size
: binary_size - offset;

int ret1 = libtock_app_loader_write(offset, &app_data[offset], chunk_len);
if (ret1 != RETURNCODE_SUCCESS) {
printf("[Error] Chunk write failed at offset %zu\n", offset);
break;
}
offset += chunk_len;
}
}

/******************************************************************************************************
* Main
******************************************************************************************************/

int main(void) {
printf("[Log] Simple test app to test abort functionality of dynamic process loading.\n");

// check if app loader driver exists
if (!libtock_app_loader_exists()) {
printf("No App Loader driver!\n");
return -1;
}

libtocksync_alarm_delay_ms(5000);

printf("[Log] Initiating Abort Test.\n");

abort_test();

printf("[Log] Exiting Abort Test.\n");
return 0;
}
1 change: 1 addition & 0 deletions examples/tests/app_loader/button-press-loading/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
loadable_binaries.h
15 changes: 15 additions & 0 deletions examples/tests/app_loader/button-press-loading/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Makefile for user application

# Specify this directory relative to the current application.
TOCK_USERLAND_BASE_DIR = ../../../..

# Which files to compile.
C_SRCS := $(wildcard *.c)

# List of apps to generate embed rules for
APPS_TO_EMBED = \
$(TOCK_USERLAND_BASE_DIR)/examples/blink \
$(TOCK_USERLAND_BASE_DIR)/examples/tests/adc/adc

# Include app loading support rules. Rules to generate app binary images.
include ../support/CommonAppMake.mk
47 changes: 47 additions & 0 deletions examples/tests/app_loader/button-press-loading/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Dynamic App Loader (Helper App)
=================================

This app waits upon the user to press one of two buttons on the device (if supported).

When Button 1 (Default user button on boards) is pressed, the app tried to load in the
`blink` app.

When Button 2 is pressed, the app tries to load in the `adc` app.

There are three stages to this:

1. Setup Phase
2. Flash Phase
3. Load Phase

#### Setup Phase
During the setup phase, the application passes the size of the new app `(blink)/(adc)`'s
binary to the app_loader capsule.

The capsule returns with either a success or failure.

On success, the app requests the app_loader capsule to flash the `blink/adc` app.

On Failure, the app exits logs the reason for failure and exits.

#### Flash Phase
The app sends the binary of the `blink/adc` app 512 bytes (this is the size of the shared
buffer between the app and the capsule) at a time along with the offset.

The capsule checks that these values do not violate the bounds dictated by the kernel
and then requests the kernel to flash the app.

The kernel performs more stringent checking on the request to ensure that memory access
violations do not take place, and flashes the app.

The capsule then returns with either a success or failure.

On success, the app requests the app_loader capsule to load the `blink/adc` app.

On Failure, the app exits logs the reason for failure and exits.

#### Load Phase
The app requests the capsule to load the new app. There are only two outcomes:

1. The `blink/adc` app is loaded successfully and functions without requiring a restart.
2. The load process failed somewhere, and the app is erased.
Loading