Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ Hold any button during startup to activate the Wi-Fi hotspot. Connect to it with

### Build fails

If the build fails due to memory limits, try disabling features you don’t plan to use in the [`.env`](https://github.com/VIPnytt/Frekvens/blob/main/.env). The [OTA](https://github.com/VIPnytt/Frekvens/wiki/Extensions#%EF%B8%8F-ota) extension is by far the largest one, and therefore a good first candidate to remove in order to free up memory for other features.
If the build fails due to size limits, try disabling features you don’t plan to use in the [`.env`](https://github.com/VIPnytt/Frekvens/blob/main/.env). The [OTA](https://github.com/VIPnytt/Frekvens/wiki/Extensions#%EF%B8%8F-ota) extension is by far the largest one, and therefore a good first candidate to remove in order to free up space for other features.

### Where is the web UI?

Expand Down
10 changes: 5 additions & 5 deletions partitions/2MB_no_ota.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
littlefs, data, littlefs, 0xE000, 0x10000,
otadata, data, ota, 0x1E000, 0x2000,
app0, app, ota_0, 0x20000, 0x1E0000,
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
littlefs, data, littlefs, 0xE000, 0x10000,
otadata, data, ota, 0x1E000, 0x2000,
app0, app, ota_0, 0x20000, 0x1E0000,
5 changes: 5 additions & 0 deletions partitions/2MB_no_ota_rev2.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
littlefs, data, littlefs, 0xE000, 0x20000,
otadata, data, ota, 0x2E000, 0x2000,
app0, app, ota_0, 0x30000, 0x1D0000,
7 changes: 7 additions & 0 deletions partitions/4MB_rev2.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x8000,
coredump, data, coredump, 0x11000, 0xD000,
littlefs, data, littlefs, 0x1E000, 0x20000,
otadata, data, ota, 0x3E000, 0x2000,
app0, app, ota_0, 0x40000, 0x1E0000,
app1, app, ota_1, 0x220000, 0x1E0000,
56 changes: 32 additions & 24 deletions partitions/README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
# 💾 Partition tables

This directory contains predefined partition tables for different ESP32 flash sizes.
Partition tables for ESP32 boards with different flash sizes. Choose a layout matching your board, or let the build system select the best fit automatically.

> [!NOTE]
> ESP32 boards come with varying flash memory sizes. Newer models often include 8 MB, while most older boards have 4 MB. Boards with 2 MB, 16 MB, or 32 MB flash also exist.
## 📦 Predefined layouts

Use one of the predefined layouts below to match your board’s flash size:

| Flash size | File | Feature capacity | OTA updates |
| ---------- | ----------------- | ----------------------- | ------------------ |
| 2 MB | `2MB_no_ota.csv` | :ballot_box_with_check: | :x: |
| 4 MB | `4MB_no_ota.csv` | :white_check_mark: | :x: |
| 4 MB | `4MB.csv` | :ballot_box_with_check: | :white_check_mark: |
| 8 MB | `8MB.csv` | :white_check_mark: | :white_check_mark: |
| 16 MB | `16MB.csv` | :white_check_mark: | :white_check_mark: |
| 32 MB | `32MB.csv` | :white_check_mark: | :white_check_mark: |
| Flash size | File | Feature capacity | OTA updates |
| ---------- | ---------------------- | ----------------------- | ------------------ |
| 2 MB | `2MB_no_ota_rev2.csv` | :ballot_box_with_check: | :x: |
| 4 MB | `4MB_no_ota.csv` | :white_check_mark: | :x: |
| 4 MB | `4MB_rev2.csv` | :ballot_box_with_check: | :white_check_mark: |
| 8 MB | `8MB.csv` | :white_check_mark: | :white_check_mark: |
| 16 MB | `16MB.csv` | :white_check_mark: | :white_check_mark: |
| 32 MB | `32MB.csv` | :white_check_mark: | :white_check_mark: |

**Legend:**

Expand All @@ -25,25 +22,34 @@ Use one of the predefined layouts below to match your board’s flash size:
:x: — not available

> [!TIP]
> Disable unneeded features in the [.env](https://github.com/VIPnytt/Frekvens/blob/main/.env) config file if the build is too large to fit.
> Disable unneeded features in the [.env](https://github.com/VIPnytt/Frekvens/blob/main/.env) config file if the build is too large to fit. OTA support requires space for two firmware images, so disabling OTA is often the most effective option on 4 MB boards.

### Legacy layouts

| Flash size | File |
| ---------- | ----------------- |
| 2 MB | `2MB_no_ota.csv` |
| 4 MB | `4MB.csv` |

## 2️⃣ 2 MB flash boards
These layouts are kept for backward compatibility, but are no longer recommended for new flashes. They were replaced in v2.5.0 by revised layouts with a better balance between firmware and filesystem space.

The `2MB_no_ota.csv` layout provides almost the same firmware capacity as `4MB.csv`, at the cost of [OTA](https://github.com/VIPnytt/Frekvens/wiki/Extensions#%EF%B8%8F-ota) support.
## 2️⃣ 2 MB flash memory

Boards with only 2 MB flash memory have very limited space, so only a minimal feature set with no OTA-capability is possible.

Configure in [platformio.ini](https://github.com/VIPnytt/Frekvens/blob/main/platformio.ini):

```ini
board_build.partitions = partitions/2MB_no_ota_fs.csv
board_build.partitions = partitions/2MB_no_ota_rev2.csv
```

## 4️⃣ 4 MB flash boards
## 4️⃣ 4 MB flash memory

Depending on configuration, there’s two alternatives.
There are two main options, depending on whether OTA updates are desired.

### No OTA

The `4MB_no_ota.csv` layout provides the same firmware capacity as `8MB.csv`, at the cost of the [OTA](https://github.com/VIPnytt/Frekvens/wiki/Extensions#%EF%B8%8F-ota) ability.
The 4 MB flash layout without OTA support is recommended for users who want the full feature set and are comfortable with manual updates.

Configure in [platformio.ini](https://github.com/VIPnytt/Frekvens/blob/main/platformio.ini):

Expand All @@ -53,17 +59,17 @@ board_build.partitions = partitions/4MB_no_ota.csv

### With OTA

The `4MB.csv` layout provides a flexible configuration with [OTA](https://github.com/VIPnytt/Frekvens/wiki/Extensions#%EF%B8%8F-ota) updates, [web app](https://github.com/VIPnytt/Frekvens/wiki/Extensions#-web-app) access, and a limited firmware capacity.
The 4 MB flash layout with OTA support provides a limited feature set, but allows for convenient over-the-air updates. Recommended for users who prioritize ease of updates and are willing to accept some limitations in features.

Configure in [platformio.ini](https://github.com/VIPnytt/Frekvens/blob/main/platformio.ini):

```ini
board_build.partitions = partitions/4MB.csv
board_build.partitions = partitions/4MB_rev2.csv
```

## 8️⃣ 8 MB, 16 MB, and 32 MB flash boards
## 8️⃣ 8 MB+ flash memory

These provides a comfortable and flexible configuration without any compromises.
These layouts all include OTA support and provide a comfortable, flexible configuration without compromises.

Configure in [platformio.ini](https://github.com/VIPnytt/Frekvens/blob/main/platformio.ini):

Expand All @@ -78,3 +84,5 @@ board_build.partitions = partitions/16MB.csv
```ini
board_build.partitions = partitions/32MB.csv
```

Boards with more than 32 MB flash memory should use the 32 MB layout.
30 changes: 22 additions & 8 deletions scripts/src/components/Deprecated.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


class Deprecated:
MIGRATIONS: list[tuple[str, str, str, str]] = [
FEATURES: list[tuple[str, str, str, str]] = [
("MODE_ARTNET", "Art-Net", Stream.ENV_OPTION, Stream.NAME),
("MODE_BOLDCLOCK", "Bold clock", Clock.ENV_OPTION, Clock.NAME),
("MODE_DISTRIBUTEDDISPLAYPROTOCOL", "Distributed Display Protocol", Stream.ENV_OPTION, Stream.NAME),
Expand Down Expand Up @@ -45,7 +45,7 @@ def initialize(self) -> None:
self._platformio_ini()

def _env(self) -> None:
for old_option, old_name, new_option, new_name in self.MIGRATIONS:
for old_option, old_name, new_option, new_name in self.FEATURES:
if old_option in self.project.dotenv:
if new_option == Weather.ENV_OPTION:
weather_option = f"WEATHER_{old_option.removeprefix('MODE_')}"
Expand All @@ -71,15 +71,29 @@ def _env(self) -> None:
del self.project.dotenv[old_option]

def _platformio_ini(self) -> None:
option = "board_build.embed_files"
path = "firmware/embed/x509_crt_bundle.bin"
paths = self.project.env.GetProjectOption(option, None)
if paths and ((isinstance(paths, list) and path in paths) or (isinstance(paths, str) and paths == path)):
logging.warning("'%s = %s' is deprecated and should be removed from platformio.ini.", option, path)
_path = pathlib.Path(path)
embed_option = "board_build.embed_files"
embed_path = "firmware/embed/x509_crt_bundle.bin"
embed_paths = self.project.env.GetProjectOption(embed_option, None)
if embed_paths and (
(isinstance(embed_paths, list) and embed_path in embed_paths)
or (isinstance(embed_paths, str) and embed_paths == embed_path)
):
logging.warning(
"'%s = %s' is deprecated and should be removed from platformio.ini.", embed_option, embed_path
)
_path = pathlib.Path(embed_path)
if not _path.exists():
_path.parent.mkdir(parents=True, exist_ok=True)
_path.write_bytes(b"\x00")
partition_table = self.project.env.GetProjectOption("board_build.partitions", None)
if "partitions/2MB_no_ota.csv" == partition_table:
logging.warning(
"The '2MB_no_ota.csv' partition table is deprecated, please migrate to the newer '2MB_no_ota_rev2.csv' table"
)
elif "partitions/4MB.csv" == partition_table:
logging.warning(
"The '4MB.csv' partition table is deprecated, please migrate to the newer '4MB_rev2.csv' table"
)

@staticmethod
def clean() -> None:
Expand Down
16 changes: 7 additions & 9 deletions scripts/src/components/Partition.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,20 @@ def _get_flash_size(self) -> str:
return size if size else self.project.env.BoardConfig().get("upload.flash_size")

def _lookup_table(self, flash_size: str) -> pathlib.Path | None:
if flash_size in [
"2MB",
]:
return self.path / f"{flash_size}_no_ota.csv"
elif flash_size in [
"4MB",
]:
if flash_size == "2MB":
return self.path / "2MB_no_ota_rev2.csv"
elif flash_size == "4MB":
return (
self.path / f"{flash_size}.csv"
self.path / "4MB_rev2.csv"
if Ota.ENV_OPTION in self.project.dotenv and self.project.dotenv[Ota.ENV_OPTION] == "true"
else self.path / f"{flash_size}_no_ota.csv"
else self.path / "4MB_no_ota.csv"
)
elif flash_size in [
"8MB",
"16MB",
"32MB",
]:
return self.path / f"{flash_size}.csv"
elif flash_size.endswith("MB") and int(flash_size[:-2]) >= 32:
return self.path / "32MB.csv"
return None
7 changes: 2 additions & 5 deletions scripts/src/extensions/Ota.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import hashlib
import logging
import typing
import warnings

if typing.TYPE_CHECKING:
from ..Frekvens import Frekvens
Expand All @@ -23,10 +23,7 @@ def configure(self) -> None:
def validate(self) -> None:
if "no_ota" in str(self.project.partition.table):
if self.ENV_OPTION in self.project.dotenv and self.project.dotenv[self.ENV_OPTION] != "false":
warnings.warn(
f"{self.ENV_OPTION}: Partition table does not support OTA updates.",
UserWarning,
)
logging.error(f"{self.ENV_OPTION}: Partition table does not support {self.NAME} updates.")
else:
self.project.dotenv[self.ENV_OPTION] = "false"
self.project.ota = None
Expand Down
6 changes: 2 additions & 4 deletions scripts/src/extensions/WebApp.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import dotenv
import gzip
import logging
import nodejs_wheel
import os
import pathlib
Expand Down Expand Up @@ -28,10 +29,7 @@ def validate(self) -> None:
self.project.webapp = None
elif "no_fs" in str(self.project.partition.table):
if self.ENV_OPTION in self.project.dotenv and self.project.dotenv[self.ENV_OPTION] == "true":
warnings.warn(
f"{self.ENV_OPTION}: Partition table has no filesystem support.",
UserWarning,
)
logging.error(f"{self.ENV_OPTION}: Partition table has no filesystem support.")
elif WebSocket.ENV_OPTION not in self.project.dotenv or self.project.dotenv[WebSocket.ENV_OPTION] == "false":
warnings.warn(
f"{WebSocket.ENV_OPTION}: {WebSocket.NAME} is required by {self.NAME}.",
Expand Down
Loading