Example Applications¶
This page documents the example applications included in the Nexus repository. Each example demonstrates specific features and serves as a reference for building your own applications.
All examples are located in the applications/ directory of the repository.
Overview¶
The Nexus repository includes the following example applications:
Example |
Purpose |
Key Features |
|---|---|---|
blinky |
Basic GPIO control |
LED blinking, GPIO initialization, HAL basics |
config_demo |
Configuration management |
Config storage, namespaces, import/export, UART output |
freertos_demo |
Multi-tasking with OSAL |
Tasks, mutexes, semaphores, queues, producer-consumer pattern |
shell_demo |
Command-line interface |
Shell commands, UART CLI, command registration, line editing |
Blinky Example¶
Location: applications/blinky/
Description: A simple LED blinky application that demonstrates basic GPIO control and HAL initialization.
Features¶
HAL system initialization
GPIO configuration as output
LED blinking in sequence
Error handling with LED indicators
Hardware Requirements¶
STM32F4 Discovery board (or compatible)
LEDs on PD12 (Green), PD13 (Orange), PD14 (Red), PD15 (Blue)
Building and Running¶
# Configure for STM32F4
CMake -B build-stm32f4 \
-DCMAKE_TOOLCHAIN_FILE=CMake/toolchains/arm-none-eabi.CMake \
-DNEXUS_PLATFORM=stm32f4
# Build
CMake --build build-stm32f4 --target blinky
# Flash
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg \
-c "program build-stm32f4/applications/blinky/blinky.elf verify reset exit"
Expected Behavior¶
All four LEDs on the STM32F4 Discovery board blink in sequence:
Green LED toggles (500ms)
Orange LED toggles (500ms)
Red LED toggles (500ms)
Blue LED toggles (500ms)
Repeat
Key Code Sections¶
LED Initialization:
static hal_status_t led_init(void) {
hal_gpio_config_t config = {
.direction = HAL_GPIO_DIR_OUTPUT,
.pull = HAL_GPIO_PULL_NONE,
.output_mode = HAL_GPIO_OUTPUT_PP,
.speed = HAL_GPIO_SPEED_LOW,
.init_level = HAL_GPIO_LEVEL_LOW
};
/* Initialize all LEDs */
hal_gpio_init(LED_GREEN_PORT, LED_GREEN_PIN, &config);
hal_gpio_init(LED_ORANGE_PORT, LED_ORANGE_PIN, &config);
hal_gpio_init(LED_RED_PORT, LED_RED_PIN, &config);
hal_gpio_init(LED_BLUE_PORT, LED_BLUE_PIN, &config);
return HAL_OK;
}
Main Loop:
while (1) {
hal_gpio_toggle(LED_GREEN_PORT, LED_GREEN_PIN);
hal_delay_ms(BLINK_DELAY_MS);
hal_gpio_toggle(LED_ORANGE_PORT, LED_ORANGE_PIN);
hal_delay_ms(BLINK_DELAY_MS);
hal_gpio_toggle(LED_RED_PORT, LED_RED_PIN);
hal_delay_ms(BLINK_DELAY_MS);
hal_gpio_toggle(LED_BLUE_PORT, LED_BLUE_PIN);
hal_delay_ms(BLINK_DELAY_MS);
}
Learning Outcomes¶
After studying this example, you will understand:
How to initialize the HAL subsystem
How to configure GPIO pins as outputs
How to control LED states
How to use HAL delay functions
Basic error handling patterns
Config Demo Example¶
Location: applications/config_demo/
Description: Demonstrates the Config Manager middleware for storing and retrieving configuration data.
Features¶
Configuration storage and retrieval
Multiple data types (int32, uint32, float, bool, string, blob)
Namespace isolation
Configuration query and enumeration
JSON import/export
Binary import/export
UART output for demonstration
Hardware Requirements¶
STM32F4 Discovery board
USB-to-Serial adapter connected to UART2 (PA2/PA3)
Serial terminal at 115200 baud
Building and Running¶
# Configure for STM32F4
CMake -B build-stm32f4 \
-DCMAKE_TOOLCHAIN_FILE=CMake/toolchains/arm-none-eabi.CMake \
-DNEXUS_PLATFORM=stm32f4
# Build
CMake --build build-stm32f4 --target config_demo
# Flash
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg \
-c "program build-stm32f4/applications/config_demo/config_demo.elf verify reset exit"
Expected Behavior¶
The application runs through several demonstrations:
Basic Configuration: Stores and retrieves various data types
Namespaces: Demonstrates namespace isolation (WiFi and BLE configs)
Query: Lists all configuration entries
JSON Export/Import: Exports config to JSON and reimports
Binary Export/Import: Exports config to binary format and reimports
Green LED turns on when ready, and blinks slowly when complete.
Key Code Sections¶
Basic Configuration Storage:
/* Store different data types */
config_set_i32("app.timeout", 5000);
config_set_u32("app.retry", 3);
config_set_float("sensor.threshold", 25.5f);
config_set_bool("feature.enabled", true);
config_set_str("device.name", "Nexus-Demo");
/* Read values back */
int32_t timeout = 0;
config_get_i32("app.timeout", &timeout, 0);
Namespace Usage:
/* Open namespaces */
config_ns_handle_t wifi_ns, ble_ns;
config_open_namespace("wifi", &wifi_ns);
config_open_namespace("ble", &ble_ns);
/* Store WiFi settings */
config_ns_set_str(wifi_ns, "ssid", "MyNetwork");
config_ns_set_bool(wifi_ns, "auto_connect", true);
/* Close namespaces */
config_close_namespace(wifi_ns);
config_close_namespace(ble_ns);
JSON Export:
/* Export to JSON */
char buffer[1024];
size_t actual_size = 0;
config_status_t status = config_export(CONFIG_FORMAT_JSON, 0, buffer,
sizeof(buffer), &actual_size);
Learning Outcomes¶
After studying this example, you will understand:
How to initialize and use the Config Manager
How to store and retrieve different data types
How to use namespaces for configuration isolation
How to export and import configurations
How to query configuration entries
How to use UART for debug output
FreeRTOS Demo Example¶
Location: applications/freertos_demo/
Description: Demonstrates multi-tasking using the OSAL with FreeRTOS backend.
Features¶
Multiple concurrent tasks
Task priorities and scheduling
Mutex for resource protection
Semaphore for task synchronization
Message queue for inter-task communication
Producer-consumer pattern
System statistics tracking
Hardware Requirements¶
STM32F4 Discovery board with FreeRTOS support
LEDs for visual feedback
Building and Running¶
# Configure for STM32F4 with FreeRTOS
CMake -B build-stm32f4 \
-DCMAKE_TOOLCHAIN_FILE=CMake/toolchains/arm-none-eabi.CMake \
-DNEXUS_PLATFORM=stm32f4 \
-DNEXUS_OSAL_BACKEND=FreeRTOS
# Build
CMake --build build-stm32f4 --target freertos_demo
# Flash
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg \
-c "program build-stm32f4/applications/freertos_demo/freertos_demo.elf verify reset exit"
Expected Behavior¶
The application creates four tasks:
Producer Task: Generates sensor data every 100ms, sends to queue
Consumer Task: Receives data from queue, processes it
LED Task: Blinks green LED as heartbeat (500ms)
Stats Task: Periodically reports system statistics (2s)
LED Indicators:
Green: Heartbeat (system running)
Orange: Consumer processing data
Blue: Producer sending data
Red: Queue overflow or error
Key Code Sections¶
Task Creation:
/* Producer task - Normal priority */
osal_task_config_t producer_config = {
.name = "Producer",
.func = producer_task,
.arg = NULL,
.priority = OSAL_TASK_PRIORITY_NORMAL,
.stack_size = TASK_STACK_SIZE
};
osal_task_create(&producer_config, &g_producer_task);
Message Queue:
/* Create message queue for sensor data */
osal_queue_create(sizeof(sensor_data_t), SENSOR_QUEUE_SIZE,
&g_sensor_queue);
/* Send to queue */
osal_queue_send(g_sensor_queue, &data, 10);
/* Receive from queue */
osal_queue_receive(g_sensor_queue, &data, OSAL_WAIT_FOREVER);
Mutex Protection:
/* Create mutex */
osal_mutex_create(&g_stats_mutex);
/* Lock mutex */
if (osal_mutex_lock(g_stats_mutex, 100) == OSAL_OK) {
/* Critical section - update shared statistics */
g_stats.samples_produced++;
osal_mutex_unlock(g_stats_mutex);
}
Semaphore Signaling:
/* Create semaphore */
osal_sem_create_counting(SENSOR_QUEUE_SIZE, 0, &g_data_ready_sem);
/* Signal data ready */
osal_sem_give(g_data_ready_sem);
/* Wait for data */
osal_sem_take(g_data_ready_sem, 500);
Learning Outcomes¶
After studying this example, you will understand:
How to initialize OSAL and create tasks
How to use task priorities
How to protect shared resources with mutexes
How to synchronize tasks with semaphores
How to pass messages between tasks with queues
How to implement producer-consumer patterns
How to start the RTOS scheduler
Related Documentation¶
Multi-Tasking with OSAL - Multi-tasking tutorial
OS Abstraction Layer (OSAL) - OSAL user guide
Shell Demo Example¶
Location: applications/shell_demo/
Description: Demonstrates the Shell/CLI middleware for interactive command-line interfaces.
Features¶
Interactive command-line interface over UART
Custom command registration
Command parsing and execution
Command completion
Built-in commands (help, version, etc.)
LED control commands
System commands (tick, delay, reboot)
Hardware Requirements¶
STM32F4 Discovery board
USB-to-Serial adapter connected to UART2 (PA2/PA3)
Serial terminal at 115200 baud
Building and Running¶
# Configure for STM32F4
CMake -B build-stm32f4 \
-DCMAKE_TOOLCHAIN_FILE=CMake/toolchains/arm-none-eabi.CMake \
-DNEXUS_PLATFORM=stm32f4
# Build
CMake --build build-stm32f4 --target shell_demo
# Flash
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg \
-c "program build-stm32f4/applications/shell_demo/shell_demo.elf verify reset exit"
Expected Behavior¶
After flashing, open a serial terminal and you’ll see:
========================================
Nexus Shell Demo v1.0.0
STM32F4 Discovery Board
Type 'help' for available commands
========================================
nexus>
Available Commands:
help- Show available commandsled <color> <on|off|toggle>- Control LEDs (green, orange, red, blue, all)button- Read user button statustick- Show system tick countdelay <ms>- Delay for specified millisecondsreboot- Reboot the system
Example Session:
nexus> help
Available commands:
help - Show this help
led - Control LEDs on the board
button - Read user button status
tick - Show system tick count
delay - Delay for specified milliseconds
reboot - Reset system
nexus> led green on
LED green ON
nexus> tick
System tick: 12345 ms
nexus> button
User button: RELEASED
Key Code Sections¶
Command Handler:
static int cmd_led(int argc, char* argv[]) {
if (argc < 3) {
shell_printf("Usage: led <color> <on|off|toggle>\n");
return 1;
}
const char* color = argv[1];
const char* action = argv[2];
/* Determine which LED and perform action */
if (strcmp(action, "on") == 0) {
hal_gpio_write(port, pin, HAL_GPIO_LEVEL_HIGH);
shell_printf("LED %s ON\n", color);
}
return 0;
}
Command Registration:
static const shell_command_t cmd_led_def = {
.name = "led",
.handler = cmd_led,
.help = "Control LEDs on the board",
.usage = "led <color> <on|off|toggle>",
.completion = led_color_completion
};
/* Register command */
shell_register_command(&cmd_led_def);
Shell Initialization:
/* Configure shell */
shell_config_t config = {
.prompt = "nexus> ",
.cmd_buffer_size = 128,
.history_depth = 16,
.max_commands = 32
};
/* Initialize shell */
shell_init(&config);
/* Set UART backend */
shell_set_backend(&shell_uart_backend);
/* Register commands */
shell_register_builtin_commands();
shell_register_command(&cmd_led_def);
Learning Outcomes¶
After studying this example, you will understand:
How to initialize the Shell framework
How to register custom commands
How to parse command arguments
How to implement command handlers
How to use UART for interactive CLI
How to provide command completion
How to integrate shell with your application
Related Documentation¶
Shell Framework - Shell framework user guide
UART Communication Tutorial - UART communication tutorial
Building All Examples¶
To build all examples at once:
# Configure
CMake -B build-stm32f4 \
-DCMAKE_TOOLCHAIN_FILE=CMake/toolchains/arm-none-eabi.CMake \
-DNEXUS_PLATFORM=stm32f4
# Build all examples
CMake --build build-stm32f4 --target all
Example binaries will be located in:
build-stm32f4/applications/blinky/blinky.elfbuild-stm32f4/applications/config_demo/config_demo.elfbuild-stm32f4/applications/freertos_demo/freertos_demo.elfbuild-stm32f4/applications/shell_demo/shell_demo.elf
Modifying Examples¶
All examples are designed to be easily modified and extended:
Copy the Example: Copy the example directory to create your own application
Modify CMakeLists.txt: Update project name and dependencies
Modify main.c: Add your custom functionality
Build and Test: Build and flash to your hardware
Example: Creating a Custom Application from Blinky¶
# Copy blinky example
cp -r applications/blinky applications/my_app
# Edit CMakeLists.txt
# Change: project(blinky C)
# To: project(my_app C)
# Edit main.c with your custom code
# Build
CMake --build build-stm32f4 --target my_app
Troubleshooting¶
Example doesn’t build:
Ensure you have the correct toolchain installed
Check that the platform is set correctly (
-DNEXUS_PLATFORM=stm32f4)Verify all dependencies are available
Example doesn’t run after flashing:
Check that you flashed the correct .elf file
Verify the board is powered correctly
Try resetting the board
Check LED indicators for error states
UART examples show no output:
Verify UART wiring (TX/RX crossed correctly)
Check baud rate matches (115200)
Ensure correct COM port is selected in terminal
Try a different USB-to-Serial adapter
FreeRTOS example crashes:
Increase task stack sizes if needed
Check for stack overflow
Verify FreeRTOS is configured correctly
Next Steps¶
Try modifying the examples to add your own features
Combine concepts from multiple examples
Create your own application based on these examples
Explore the Hardware Abstraction Layer (HAL) and OS Abstraction Layer (OSAL) for more advanced features