Compare commits

...
1 Commits
2 changed files with 57 additions and 146 deletions

No files matched your search

+46 -110
View File
@@ -3,130 +3,66 @@
Это личный форк оригинальной прошивки **MeshCore**:
- **оригинал (upstream):** https://github.com/meshcore-dev/MeshCore
- **этот форк:** https://git.meshinfo.ru/shade/MeshCore (рабочая ветка `main`)
- **этот форк:** https://git.meshinfo.ru/shade/MeshCore
- **готовые прошивки:** https://meshinfo.ru/flasher/
За основу взята оригинальная прошивка: архитектура, протокол, роли узлов, примеры
приложений и большинство вариантов плат остаются как в оригинале. Форк добавляет
доработки под свои устройства — Heltec T096, ProMicro (SSD1306/SH1106), Heltec v3 и
heltec_v4, LilyGo T-Deck и T-Echo Card, Heltec T114/T190, ThinkNode M9, Meshadventurer
на E22. Ниже перечислено, чем форк отличается от upstream.
Синхронизация с оригиналом:
```bash
git remote add upstream https://github.com/meshcore-dev/MeshCore
git fetch upstream
git merge upstream/main # правки для upstream отправляются в ветку dev
```
Архитектура, протокол, роли узлов и большинство вариантов плат — как в оригинале.
Форк добавляет доработки под свои устройства: Heltec T096, ProMicro (SSD1306 и SH1106),
Heltec v3 и v4, LilyGo T-Deck и T-Echo Card, Heltec T114 и T190, ThinkNode M9,
Meshadventurer на E22. Ниже — что именно отличается от оригинала.
## Отличия от оригинальной прошивки
> Раздел живой: он дополняется с каждой доработкой форка. Если правка меняет поведение,
> которое есть в upstream, это отмечается — чтобы при обновлении из оригинала было видно,
> что нельзя затирать автоматическим мержем.
### Дисплеи
- **Драйвер выбирается значением `DISPLAY_CLASS`** ([`src/helpers/ui/DisplaySelect.h`](./src/helpers/ui/DisplaySelect.h)):
панель меняется в `platformio.ini` варианта, а не правкой `target.h`. Добавлен
**свой драйвер `SH1106Display`** (в оригинале его нет) и сборка
`ProMicro_SH1106_companion_radio_ble` — та же плата, но с SH1106 вместо SSD1306.
- **Русский язык на дисплеях (`-D OLED_RU=1`).** Строка UTF-8 проходит через
`DisplayDriver::translateUTF8ToBlocks()` (UTF-8 → CP1251) и рисуется шрифтом
[`glcdfont6x8.h`](./src/helpers/ui/glcdfont6x8.h) с картой CP1251. Поддержаны
`SSD1306Display`, `SH1106Display`, `ST7735Display`, `ST7789LCDDisplay`, а также
`ST7789Display` (Heltec T114/T190, ThinkNode M9): для него кириллицы в шрифтах не было,
поэтому сгенерированы `ArialMT_Plain_16_RU` / `ArialMT_Plain_24_RU` и отключён встроенный
UTF-8-декодер библиотеки `OLEDDisplay`.
- **Темы цветных TFT переключаются в рантайме, без пересборки.** Пять палитр
(`amber`, `teal`, `signal`, `neon`, `classic`) лежат в общей таблице
[`src/helpers/ui/ColorThemes.h`](./src/helpers/ui/ColorThemes.h) и работают и на ST7735,
и на ST7789LCD. В `ui-new` есть страница `THEME`: живой предпросмотр, образцы цветов.
**Тема сохраняется только длинным нажатием** на выбранной строке (попап `theme <имя> OK`);
короткое и двойное нажатие лишь показывают тему, а выход из меню (в том числе по таймауту)
возвращает ту, что записана в prefs — предпросмотр ничего не подменяет. По умолчанию —
янтарь на Heltec T096 и официальная светлая схема MeshCore на остальных платах
(как в upstream).
- **Индикатор страниц** в `ui-new` строится на `warning_txt` / `secondary_txt`: в upstream
цвета брались из `title_bkg`, из-за чего на тёмных темах активная точка сливалась с фоном.
- **Поддерживаемые панели:** SSD1306, SH1106 (свой драйвер, в оригинале его нет —
есть отдельная сборка ProMicro под SH1106), ST7735, ST7789 (в двух вариантах).
- **Русский язык в интерфейсе** (`OLED_RU`): пункты меню, названия страниц, имена
узлов и сообщения. Работает на всех поддерживаемых дисплеях, включая Heltec T114,
T190 и ThinkNode M9.
- **Темы цветных TFT** (пять палитр) переключаются прямо с устройства, без пересборки:
страница `THEME` с живым предпросмотром и образцами цветов. Тема сохраняется длинным
нажатием на выбранной строке и переживает перезагрузку, а короткое нажатие только
показывает вариант, ничего не меняя. По умолчанию — янтарная тема на T096 и светлая
классическая на остальных платах.
### Стартовый экран
- Показывает версию **MeshCore** (`v1.17.1` — из исходников), строку **`MESHINFO v0.1.1`**
(версия форка) и сайт **`meshinfo.ru`**. Дата сборки с экрана убрана — она только путала,
потому что рядом стояла версия.
- Версия форка передаётся отдельным макросом `MESHINFO_VERSION` (`build.sh`), поэтому
`FIRMWARE_VERSION` остаётся версией MeshCore: её же отдаёт приложению команда версии
и она попадает в стартовый экран. Так на устройстве видно и базу, и форк.
- Правка сделана во всех стартовых экранах: `companion_radio/ui-new`, а также в `UITask.cpp`
у `simple_repeater`, `simple_room_server` и `simple_sensor`.
- Показывает версию MeshCore, версию форка (`MESHINFO v0.1.1`) и сайт `meshinfo.ru`.
Дата сборки с экрана убрана — рядом с версиями она только путала.
### Интерфейс (companion_radio / ui-new)
### Интерфейс (прошивка companion)
- **Настройка радио прямо с устройства** — страница RADIO, длинное нажатие: частота,
ширина полосы, SF, CR и мощность передатчика. Частота правится **по разрядам** (как в
PosadMesh): целые МГц меняются шагом 1 МГц, а килогерцы — по символам (сотни, десятки,
единицы). Короткое и двойное нажатие меняют активный разряд на ±1, длинное — переводит
на следующий разряд, а после единиц кГц возвращает к списку; активный разряд показан
инверсией. Значения применяются к радио сразу, в память пишутся по пункту `Save & exit`;
через 5 минут простоя меню закрывается без сохранения и экран гаснет, а пока меню открыто —
входящие сообщения не всплывают поверх него.
- **Меню уведомлений** (длинное нажатие на первом экране): `Popups`, `Wake screen`
(запретить автовключение дисплея по входящему сообщению; по кнопке экран работает),
`Alerts` (звук+вибрация / только звук / только вибрация / выключено), `Channels`
(для каждого канала свой режим: `popup` / `silent` / `off`), `Quiet hours` с часовым
поясом, `Unread` для накопленных сообщений.
Режимы канала живут в `NodePrefs::ch_mode` (2 бита на канал, до 40 каналов),
тихие часы — в `NodePrefs::isQuietNow()`, «тихая» доставка — через
`AbstractUITask::newMsgSilent()`. В тихие часы глушатся звук, вибрация и всплытия для
каналов, личных сообщений и уведомлений о новых контактах, но сообщения не теряются.
- **Страница POWER** (последняя в списке страниц; длинное нажатие — вход в меню) — питание,
батарея и перезагрузка. Раньше этот пункт назывался `Hibernation` и сразу выключал устройство.
На самой странице крупно нарисованы батарея с заливкой по заряду, процент и напряжение.
- `Battery` — что показывать рядом с иконкой батареи в статус-баре: `Volt` (напряжение,
`4.05V`), `Perc` (процент) или `Off` (индикатор скрыт). Длинное нажатие переключает
значение; применяется и сохраняется сразу. Иконка батареи стала компактнее (18×9).
- `ADC corr` — коррекция АЦП батареи. Показывается **тот множитель, который действует
сейчас**: значение из настроек, иначе — из платы, иначе базовый `ADC_MULTIPLIER` варианта
(то есть правка начинается не с нуля, а с реального значения прошивки). Длинное нажатие
открывает правку, где короткое нажатие даёт `+0.01`, двойное `-0.01`, а длинное возвращает
в меню. Значение применяется к плате и сохраняется сразу, а при следующем включении
подхватывается из prefs. Шаг `0.01` — это ~1 % напряжения, то есть подстройка «на глаз»
по показанию на экране.
Напряжение читается серией отсчётов с усреднением и сглаживается между кадрами, поэтому
цифра на экране не дрожит (на T096 вдобавок убрана переустановка `analogReference()`
перед каждым замером — первое чтение после неё отдавало мусор).
- `Reboot/Shut` — подменю из трёх пунктов: `Reboot`, `Shutdown`, `Back`; длинное нажатие
выполняет выбранное.
- `Back` — выход из меню. Сохранять ничего не нужно: всё сохраняется в момент изменения,
через 5 минут простоя меню закрывается само.
- Коррекция работает на платах, где борд её поддерживает (`Heltec V4`, `V4 R8`, `Heltec
T096`, `promicro`, `Heltec RC32`, `Meshnology W12`); на остальных при попытке правки
выводится `ADC not supported`.
### Сборка и CI
- **Сборка прошивок на своём Gitea** ([`.gitea/workflows/firmware.yml`](./.gitea/workflows/firmware.yml),
[`ci/build-firmwares.sh`](./ci/build-firmwares.sh)): workflow собирает выбранный набор устройств
через `build.sh`, поэтому версия, `merge-bin` для ESP32 и `.uf2` для nRF52 получаются такими же,
как при локальной сборке. Запускается **только вручную** (Actions → Firmware build → Run workflow);
автоматических сборок по push и тегам нет. Как поднять раннер — [`ci/README.md`](./ci/README.md).
- **Локальная сборка с публикацией релиза** ([`ci/build-local.ps1`](./ci/build-local.ps1)):
набор прошивок собирается на своей машине (тот же `build.sh` через Git Bash), а готовые
файлы прикрепляются к релизу Gitea — сервер только принимает их и не тратит CPU на сборку.
Это основной способ выпустить прошивки: на VPS всего одно ядро.
- **Прошивальщик на сайте** (<https://meshinfo.ru/flasher/>): список прошивок страница берёт
из своего `index.json`, где имена файлов разобраны на плату, роль, чип и формат. После
публикации релиза манифест пересобирается скриптом
[`ci/update-flasher.ps1`](./ci/update-flasher.ps1): он выкладывает его на сервер, делает
бэкап предыдущего и проверяет, что страница и файлы доступны. При `-Publish` это делается
автоматически.
- **Настройка радио с устройства** — страница RADIO (длинное нажатие): частота, ширина
полосы, SF, CR и мощность передатчика. Частота правится по разрядам: целые МГц шагом
1 МГц, килогерцы — по символам (сотни, десятки, единицы), активный разряд подсвечен.
Значения применяются сразу, в память записываются по пункту `Save & exit`; через
5 минут простоя меню закрывается само, а пока оно открыто — входящие сообщения
не всплывают поверх.
- **Меню уведомлений** (длинное нажатие на первом экране): `Popups` — всплывать ли
на входящее, `Wake screen` — зажигать ли экран, `Alerts` — звук и вибрация
(вместе / только звук / только вибрация / выключено), `Channels` — режим для каждого
канала (`popup` / `silent` / `off`), `Quiet hours` с часовым поясом и `Unread`
для накопленных сообщений. В тихие часы звук, вибрация и всплытия отключены,
но сообщения не теряются.
- **Страница POWER** — питание и батарея. Раньше это был пункт `Hibernation`,
который просто выключал устройство.
- Крупно показаны заряд батареи, процент и напряжение.
- `Battery` — что показывать в статус-баре рядом с иконкой: напряжение (`Volt`),
процент (`Perc`) или ничего (`Off`).
- `ADC corr` — подстройка измеряемого напряжения: `+0.01` коротким нажатием,
`-0.01` двойным, отсчёт идёт от текущего значения. Работает на платах, которые
её поддерживают: Heltec V4 и V4 R8, Heltec T096, ProMicro, Heltec RC32,
Meshnology W12.
- `Reboot/Shut` — подменю `Reboot`, `Shutdown`, `Back`.
### Варианты плат
- Свои варианты: `generic-e22` (E22-900M30S / E22-400M30S), `meshadventurer`
(SX1262 / SX1268 и E22P 433M30S / 868M30S), `thinknode_m9`, `gat562_*`,
а также сборка ProMicro под SH1106.
- Свои варианты: `generic-e22` (E22-900M30S и E22-400M30S), `meshadventurer`
(SX1262 / SX1268 и E22P 433M30S / 868M30S), `thinknode_m9`, `gat562_*`, а также
сборка ProMicro под SH1106.
- В набор сборки входят 26 прошивок: 15 companion, 8 репетитеров и 3 room server /
sensor. Как собрать и опубликовать — [`ci/README.md`](./ci/README.md).
---
+11 -36
View File
@@ -22,9 +22,8 @@ apt-get update
apt-get install -y git python3 python3-venv python3-pip curl ca-certificates build-essential
```
- **`python3-pip` обязателен.** Без него `python3 -m venv` создаёт окружение **без pip**
(в `bin/` только симлинки python), и шаг установки PlatformIO падает с
`No such file or directory`. Если venv уже создан без pip, workflow пересоздаст его сам.
- **`python3-pip` обязателен:** без него `python3 -m venv` создаёт окружение без pip,
и шаг установки PlatformIO падает. Готовое окружение workflow пересоздаст сам.
- Свободного места нужно **5 ГБ**: тулчейны PlatformIO занимают ~800 МБ на одну платформу,
а при сборке и ESP32, и nRF52 — заметно больше.
- **Swap желателен.** На VPS с 2 ГБ RAM линковка ESP32 упирается в память:
@@ -40,12 +39,9 @@ apt-get install -y git python3 python3-venv python3-pip curl ca-certificates bui
```ini
[actions]
ENABLED = true
# Gitea 1.27 принимает значение github или gitea, но НЕ ссылку:
# "https://github.com" даёт ошибку DEFAULT_ACTIONS_URL does not support ...
# значение — github или gitea (ссылка не поддерживается)
DEFAULT_ACTIONS_URL = github
# Искать workflow только в .gitea/workflows: иначе Gitea подхватит upstream-файлы
# из .github/workflows, а у них триггер push — на каждый push запустится сборка
# сотен env и деплой Pages.
# workflow ищем только здесь, чтобы не подхватывались upstream-файлы
WORKFLOW_DIRS = .gitea/workflows
```
@@ -58,7 +54,6 @@ WORKFLOW_DIRS = .gitea/workflows
useradd --create-home --home-dir /var/lib/act-runner --shell /bin/bash act-runner
# актуальный релиз: https://gitea.com/gitea/runner/releases
# (проект переименован: раньше act_runner, теперь Gitea Runner; на момент настройки — v5.0.0)
curl -fsSL -o /usr/local/bin/gitea-runner \
https://gitea.com/gitea/runner/releases/download/v5.0.0/gitea-runner-5.0.0-linux-amd64
chmod +x /usr/local/bin/gitea-runner
@@ -69,8 +64,8 @@ cp ci/act_runner/config.yaml /var/lib/act-runner/config.yaml
chown act-runner:act-runner /var/lib/act-runner/config.yaml
```
**Токен — обязательно со scope репозитория.** Без `--scope` раннер становится глобальным
и начинает брать задачи **всех** репозиториев инстанса (в том числе чужие stale-bot):
**Токен — обязательно со scope репозитория**: без `--scope` раннер становится глобальным
и начинает брать задачи всех репозиториев инстанса:
```bash
# от имени пользователя Gitea (CLI не работает под root)
@@ -105,8 +100,6 @@ journalctl -u gitea-runner -f # ждём "declare successfully"
cd ci/act_runner && cp .env.example .env && nano .env && docker compose up -d
```
В свежих версиях образ называется `gitea/runner` (раньше `gitea/act_runner`).
## 4. Запуск сборки
Workflow запускается **только вручную** — автоматических сборок по push и тегам нет
@@ -149,9 +142,8 @@ $env:GITEA_TOKEN = '<токен с правом write:repository>'
.\ci\build-local.ps1 -Version v1.0.0 -SkipBuild -Publish -Public -Tag v1.0.0
```
Скрипт находит Git Bash и PlatformIO, подставляет рабочий `python3` (в Git Bash это
заглушка Microsoft Store — из-за неё `build.sh` не может определить платформу env),
чистит `out/` перед сборкой, а с `-Publish` создаёт тег и релиз, прикрепляя к нему файлы
Скрипт находит Git Bash и PlatformIO, подставляет рабочий `python3`, чистит `out/`
перед сборкой, а с `-Publish` создаёт тег и релиз, прикрепляя к нему файлы
(`-Public` публикует сразу, без флага создаётся черновик). Токен нужен только для
публикации: сама сборка работает без него.
@@ -200,26 +192,9 @@ Gitea). Имена файлов в манифесте разобраны на п
## 7. Время и ресурсы
- Сервер с **1 CPU / 2 ГБ RAM** полный набор собирает долго (первый прогон — часы),
и на время сборки Gitea с Postgres на той же машине заметно тормозят. Поэтому рабочий
вариант — собирать полный набор локально (`ci/build-local.ps1`), а в Gitea запускать
вручную только те env, которые нужно проверить.
- Сервер с **1 CPU / 2 ГБ RAM** полный набор собирает часами, поэтому рабочий вариант —
собирать полный набор локально (`ci/build-local.ps1`), а в Gitea запускать вручную
только те env, которые нужно проверить.
- Первая сборка качает тулчейны (nRF52: framework + CMSIS + gcc-arm ≈ 660 МБ;
ESP32 — ещё столько же), дальше работает кэш `~/.platformio`.
- `capacity: 1` в `config.yaml` — одна сборка за раз.
## 8. Грабли, на которые уже наступали
| Симптом | Причина и решение |
|---|---|
| `.../bin/pip: No such file or directory` | venv создан без pip — нет `python3-pip`; поставить пакет, venv пересоздать |
| `DEFAULT_ACTIONS_URL does not support "https://github.com"` | в Gitea 1.27 значение — `github`, не ссылка |
| раннер берёт задачи чужих репозиториев | токен выдан без `--scope owner/repo` |
| `registration file not found` в цикле рестартов | раннер запущен до регистрации: сначала `register`, потом сервис |
| `E: Could not get lock /var/lib/dpkg/lock-frontend` | работает unattended-upgrades; подождать либо остановить `apt-daily.timer` |
| на push запускается сборка сотен env | не выставлен `WORKFLOW_DIRS = .gitea/workflows` |
| сборка запускается на каждый push, хотя в workflow стоит `paths-ignore` | Gitea этот фильтр не применяет; автосборок нет — workflow запускается только вручную |
| `405 Method Not Allowed` при создании тега | в Gitea тег создаётся через `POST /repos/{owner}/{repo}/tags`, у `/git/refs` метода POST нет |
| `python3: command not found` или пустой вывод в Git Bash | это заглушка Microsoft Store; задайте `PYTHON3=/c/.../python.exe` (это делает `ci/build-local.ps1`) |
| в `out/` оказались файлы только последней платы | `build.sh` при каждом запуске делает `rm -rf out`; `ci/build-firmwares.sh` копит результат в `dist/` и в конце складывает всё в `out/` |
| нужно опубликовать уже собранное, без пересборки | `ci/build-local.ps1 -SkipBuild -Publish -Tag <тег>` |