basic

Example of the component igrr/hotreload v0.3.1
# Basic Hot Reload Example

This example demonstrates the ESP-IDF hot reload component with:
- A simple reloadable component with runtime-updatable functions
- HTTP server for over-the-air code updates

## Project Structure

```
basic/
├── main/
│   └── hotreload.c           # Application entry point
├── components/
│   └── reloadable/           # Reloadable component
│       ├── reloadable.c      # Functions that can be updated at runtime
│       ├── include/
│       │   └── reloadable.h  # Public API
│       └── CMakeLists.txt    # Uses hotreload_setup()
├── partitions.csv            # Partition table with hotreload partition
└── sdkconfig.defaults        # Default configuration
```

## Building and Running

### Prerequisites

- ESP-IDF v5.0 or later
- ESP development board

### Build and Flash

```bash
cd examples/basic
idf.py set-target esp32
idf.py build flash monitor
```

### Expected Output

```
========================================
   ESP-IDF Hot Reload Example
========================================

I (xxx) hotreload_example: Connecting to network...
I (xxx) hotreload_example: Connected!
I (xxx) hotreload_example: Loading reloadable module...
I (xxx) hotreload_example: Module loaded successfully!
Hello, World, from v5.x.x! 0
I (xxx) hotreload_example: Hot reload server running on port 8080
I (xxx) hotreload_example: To update code: idf.py reload --url http://<device-ip>:8080
I (xxx) hotreload_example: To watch and auto-reload: idf.py watch --url http://<device-ip>:8080
```

## Updating Code at Runtime

### Method 1: Using idf.py watch (Recommended)

The easiest way to update code is with the `idf.py watch` command, which watches for file changes and automatically rebuilds and uploads:

```bash
idf.py watch --url http://<device-ip>:8080
```

Now simply edit `reloadable.c` and save - the changes will be automatically built and uploaded!

### Method 2: Using idf.py reload

For manual rebuilds, use the `idf.py reload` command:

```bash
# Modify reloadable.c, then:
idf.py reload --url http://<device-ip>:8080
```

This will rebuild and upload the new code once.

### Method 3: Flash Directly

Flash just the reloadable partition (requires physical connection):

```bash
idf.py build hotreload-flash
```

### Method 4: HTTP Upload with curl

```bash
# Build first
idf.py build

# Upload and reload
curl -X POST --data-binary @build/esp-idf/reloadable/reloadable_stripped.so \
    http://<device-ip>:8080/upload-and-reload
```

## How It Works

### Reloadable Component

The `components/reloadable/` directory contains code that can be updated at runtime:

```c
// reloadable.c
static const char *reloadable_greeting = "Hello";

void reloadable_hello(const char *name)
{
    printf("%s, %s!\n", reloadable_greeting, name);
}
```

Try changing `"Hello"` to `"Goodbye"` and running `idf.py reload` to see the change take effect!

The `CMakeLists.txt` uses `hotreload_setup()` to:
1. Build this code as a position-independent shared library
2. Generate stubs and symbol table for the main app
3. Create a flashable ELF for the hotreload partition

### Main Application

The main app loads and calls the reloadable code:

```c
#include "hotreload.h"
#include "reloadable.h"

void app_main(void)
{
    // Initialize WiFi...

    // Load reloadable ELF from flash
    hotreload_config_t config = HOTRELOAD_CONFIG_DEFAULT();
    hotreload_load(&config);

    // Call through generated stubs
    reloadable_hello("World");

    // Start HTTP server for OTA updates
    hotreload_server_config_t server_config = HOTRELOAD_SERVER_CONFIG_DEFAULT();
    hotreload_server_start(&server_config);
}
```

### Partition Table

The `partitions.csv` defines a 512KB partition for reloadable code:

```csv
hotreload,  app,  0x40,  ,  512k,
```

## Configuration

Key settings in `sdkconfig.defaults`:

```ini
# Custom partition table with hotreload partition
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"

# Network configuration (adjust for your setup)
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
CONFIG_EXAMPLE_USE_OPENETH=y
```

For WiFi, use `idf.py menuconfig` to set your SSID and password under "Example Connection Configuration".

## Troubleshooting

### Build Errors

If you see "No 'hotreload' partition found":
- Ensure `partitions.csv` is configured in menuconfig
- Run `idf.py fullclean && idf.py build`

### Load Failures

If `hotreload_load()` fails:
- Check that the hotreload partition was flashed
- Verify the ELF is valid with `readelf -h build/esp-idf/reloadable/reloadable_stripped.so`

### HTTP Server Not Responding

- Ensure networking is properly initialized
- Check firewall settings
- Verify the device IP address in the serial monitor output

To create a project from this example, run:

idf.py create-project-from-example "igrr/hotreload=0.3.1:basic"

or download archive (~5.79 KB)