diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..eb06c33 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,27 @@ +PROJECT_NAME = "templates" +PROJECT_BRIEF = "Переносимые библиотеки и правила интеграции" +OUTPUT_DIRECTORY = .codex-build/doxygen +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = Russian +INPUT = README.md NEW_PROJECT.md CONTRIBUTING.md doc/submodules.dox c python +FILE_PATTERNS = *.h *.c *.dox *.md +RECURSIVE = YES +USE_MDFILE_AS_MAINPAGE = README.md +MARKDOWN_SUPPORT = YES +AUTOLINK_SUPPORT = YES +EXTRACT_ALL = NO +EXTRACT_STATIC = NO +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_FROM_PATH = . +GENERATE_HTML = YES +HTML_OUTPUT = html +GENERATE_TREEVIEW = YES +DISABLE_INDEX = NO +GENERATE_LATEX = NO +QUIET = YES +WARNINGS = YES +WARN_IF_UNDOCUMENTED = NO +WARN_IF_DOC_ERROR = YES +WARN_AS_ERROR = FAIL_ON_WARNINGS +HAVE_DOT = NO diff --git a/NEW_PROJECT.md b/NEW_PROJECT.md index e6137d3..c3aeb12 100644 --- a/NEW_PROJECT.md +++ b/NEW_PROJECT.md @@ -120,3 +120,188 @@ USB gs_usb и конкретной разводки адаптера; перен Так новый проект не является копией старого: он использует общие ядра одной версии, а аппаратные отличия видны в одном небольшом каталоге `port/`. + +## Слияние и обновление `templates` как Git submodule + +### Что именно хранит основной проект + +Основной проект не хранит содержимое `lib/templates` в своей истории. Вместо +этого он хранит **gitlink** — ссылку на один конкретный commit репозитория +`templates`. Поэтому при работе есть два независимых уровня истории: + +1. изменения библиотек сливаются и публикуются в репозитории `templates`; +2. основной проект отдельным коммитом переводит gitlink на проверенную ревизию + `templates`. + +Обычный `git merge` в основном проекте не переносит исходники между ветками +`templates` и не создаёт merge-коммит внутри сабмодуля. Он может только выбрать +одну из уже существующих ссылок на commit. Если ссылки разошлись, сначала нужно +получить общий commit в самом `templates`, а затем зафиксировать его в основном +проекте. + +Текущую зафиксированную ревизию удобно смотреть из корня основного проекта: + +```bash +git submodule status lib/templates +git diff --submodule=log +``` + +Символ `-` перед SHA в `git submodule status` означает, что сабмодуль ещё не +инициализирован; `+` — что рабочая копия сабмодуля находится не на том commit, +который записан в основном проекте; `U` — конфликт gitlink. + +### Клонирование проекта и переключение его веток + +Новый клон лучше сразу создавать вместе с сабмодулями: + +```bash +git clone --recurse-submodules +cd <основной-проект> +``` + +Если проект уже клонирован: + +```bash +git submodule update --init --recursive +``` + +После `git switch`, `git checkout`, `git pull` или завершения слияния основной +проект может начать ссылаться на другую ревизию `templates`. Рабочее дерево +сабмодуля следует явно привести к записанному состоянию: + +```bash +git submodule update --init --recursive +``` + +Это нормальный и воспроизводимый режим: внутри `lib/templates` обычно будет +detached HEAD, потому что проект фиксирует commit, а не ветку. Не следует делать +там `git pull`, пока не выбрана рабочая ветка и не понятно, какую ревизию должен +получить основной проект. + +### Обычное обновление проекта на новую версию `templates` + +Сначала изменение должно быть проверено, закоммичено, отправлено и слито в +целевую ветку самого репозитория `templates`. После этого из корня основного +проекта выполняется: + +```bash +git -C lib/templates fetch origin +git -C lib/templates switch --detach origin/master +git add lib/templates +git diff --cached --submodule=log +git commit -m "build(templates): обновить общие библиотеки" +``` + +Перед коммитом нужно собрать основной проект и прогнать его тесты: успешные +тесты в `templates` подтверждают работу библиотеки, но не проверяют конкретный +порт, настройки платы и интеграцию приложения. + +Коммит основного проекта содержит только переход со старого SHA сабмодуля на +новый. Случайные незакоммиченные файлы внутри `lib/templates` в него не входят. +Проверить оба уровня перед фиксацией можно так: + +```bash +git status +git -C lib/templates status +git diff --submodule=log +``` + +Не нужно обновлять сабмодуль на последний `master` автоматически при каждой +сборке. Зафиксированный SHA нужен именно для того, чтобы одна и та же версия +проекта всегда собиралась с одной и той же версией библиотек. + +### Если библиотеку правят из рабочего дерева основного проекта + +Нельзя коммитить изменение, оставаясь на detached HEAD: такой commit легко +потерять при следующем `git submodule update`. Сначала внутри сабмодуля создаётся +обычная ветка: + +```bash +git -C lib/templates fetch origin +git -C lib/templates switch -c feat/<имя> origin/master +``` + +Затем изменения коммитятся и отправляются именно в репозиторий `templates`: + +```bash +git -C lib/templates add <файлы> +git -C lib/templates commit -m "feat(<библиотека>): <описание>" +git -C lib/templates push -u origin feat/<имя> +``` + +После проверки ветка сливается в `master` репозитория `templates`. Только после +публикации итогового commit основной проект обновляет свой gitlink по процедуре +из предыдущего раздела. Не следует отправлять в общий основной проект ссылку на +commit сабмодуля, которого ещё нет на сервере: остальные разработчики и CI не +смогут его получить. + +### Что происходит при слиянии веток основного проекта + +Возможны три ситуации: + +1. Gitlink изменён только в одной ветке. Git обычно принимает эту ревизию + автоматически. После merge нужно выполнить `git submodule update` и тесты. +2. Обе ветки указывают на разные commits, но один commit `templates` является + предком другого. Следует выбрать более новый проверенный commit, выполнить + `git add lib/templates` и продолжить merge. +3. Обе ветки указывают на расходящиеся commits `templates`. Это настоящий + конфликт истории сабмодуля: выбирать один SHA наугад нельзя, потому что так + потеряются изменения второй ветки. + +При конфликте сначала смотрят, какие ссылки пришли с обеих сторон: + +```bash +git ls-files -u lib/templates +git -C lib/templates fetch origin +git -C lib/templates log --oneline --graph --decorate --all +``` + +Затем в отдельной ветке **репозитория `templates`** объединяют оба commit, +устраняют конфликты исходников, запускают тесты и публикуют результат: + +```bash +git -C lib/templates switch -c merge/<имя> +git -C lib/templates merge +# исправить конфликты и запустить тесты templates +git -C lib/templates add <исправленные-файлы> +git -C lib/templates commit +git -C lib/templates push -u origin merge/<имя> +``` + +Если общий merge-коммит уже существует в `origin/master`, создавать ещё один не +нужно: достаточно выбрать существующий SHA. После получения итогового commit +конфликт завершается на уровне основного проекта: + +```bash +git -C lib/templates switch --detach <итоговый-sha> +git add lib/templates +git diff --cached --submodule=log +git merge --continue +git submodule update --init --recursive +``` + +`git add lib/templates` здесь отмечает разрешённым именно gitlink. Не нужно +удалять каталог, копировать библиотеку поверх него или разрешать конфликт как +обычный текстовый файл. + +### Что должно попасть в merge request основного проекта + +Перед отправкой результата следует проверить: + +1. итоговый commit `templates` доступен в удалённом репозитории; +2. `git -C lib/templates status` не показывает локальных изменений; +3. `git submodule status` не начинается с `+`, `-` или `U`; +4. `git diff --submodule=log <целевая-ветка>...HEAD` показывает ожидаемый набор + commits библиотек; +5. тесты `templates`, сборка основного проекта и проверки на целевой плате + прошли; +6. в основном проекте закоммичены необходимые изменения адаптеров, конфигурации + и сам новый gitlink. + +После получения ветки другой разработчик восстанавливает ровно выбранное +состояние одной командой: + +```bash +git pull +git submodule update --init --recursive +``` diff --git a/README.md b/README.md index e8a609c..af8cf98 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,11 @@ templates/ В ней отдельно описаны граница ядра, ABI, память, три wire format и состояние портов Windows, Android, Linux и MCU. +Обзор всего репозитория, включая слияние при подключении через submodule: +[`doc/index.html`](doc/index.html). Справочник Doxygen собирается командой +`powershell -ExecutionPolicy Bypass -File doc/build-doxygen.ps1` в +`.codex-build/doxygen/html/index.html`. + ## Как подключить к проекту **Сабмодуль** — когда нужна одна конкретная версия и обновление по команде: @@ -78,6 +83,10 @@ git submodule add https://git.rd12.ru/Andrey/templates.git lib/templates git submodule update --init --recursive ``` +Как обновлять зафиксированную ревизию, переносить изменения из проекта и +разрешать конфликт gitlink при слиянии веток, подробно описано в разделе +[`Слияние и обновление templates как Git submodule`](NEW_PROJECT.md#слияние-и-обновление-templates-как-git-submodule). + Дальше в сборку добавляются только нужные каталоги: ``` diff --git a/doc/build-doxygen.ps1 b/doc/build-doxygen.ps1 new file mode 100644 index 0000000..4207978 --- /dev/null +++ b/doc/build-doxygen.ps1 @@ -0,0 +1,28 @@ +[CmdletBinding()] +param() + +$ErrorActionPreference = 'Stop' +$repositoryRoot = Split-Path -Parent $PSScriptRoot +$doxygen = Get-Command doxygen -ErrorAction SilentlyContinue + +if (-not $doxygen) { + throw 'Doxygen не найден в PATH. Установите Doxygen и повторите запуск.' +} + +Push-Location $repositoryRoot +try { + & $doxygen.Source Doxyfile + if ($LASTEXITCODE -ne 0) { + throw "Doxygen завершился с кодом $LASTEXITCODE." + } +} +finally { + Pop-Location +} + +$indexPath = Join-Path $repositoryRoot '.codex-build\doxygen\html\index.html' +if (-not (Test-Path -LiteralPath $indexPath)) { + throw "Doxygen не создал ожидаемый файл: $indexPath" +} + +Write-Host "[DONE] Doxygen HTML: $indexPath" diff --git a/doc/index.html b/doc/index.html index c4861e4..8c58422 100644 --- a/doc/index.html +++ b/doc/index.html @@ -5,11 +5,26 @@ :root{color-scheme:dark;--bg:#07111f;--panel:#0d1b2c;--panel2:#12243a;--line:#263b54;--text:#e8f0f8;--muted:#9eb0c4;--brand:#55d6be;--blue:#8bc5ff;--warn:#fbbf24}*{box-sizing:border-box}body{margin:0;color:var(--text);background:radial-gradient(circle at 85% 5%,#143354 0,transparent 28%),var(--bg);font:15px/1.65 "Segoe UI",Arial,sans-serif}a{color:var(--blue);text-decoration:none}a:hover{text-decoration:underline}code,pre{font-family:Consolas,"Courier New",monospace}code{color:#b8f7e9}pre{overflow:auto;padding:16px;border:1px solid var(--line);border-radius:12px;background:#071521;color:#d6e5f3}.wrap{width:min(1180px,calc(100% - 32px));margin:auto}header{padding:64px 0 30px}.eyebrow{color:var(--brand);font-weight:800;letter-spacing:.12em;text-transform:uppercase;font-size:12px}h1{max-width:800px;margin:12px 0;font-size:clamp(36px,6vw,66px);line-height:1.05;letter-spacing:-.045em}h2{margin:0 0 8px;font-size:28px}h3{margin:0 0 7px;font-size:18px}.lead{max-width:850px;color:var(--muted);font-size:18px}.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-top:28px}.stat{padding:15px 18px;border:1px solid var(--line);border-radius:14px;background:#0d1b2ccc}.stat b{display:block;color:var(--brand);font-size:24px}.stat span,.card p,.head p{color:var(--muted)}.tabbar{position:sticky;top:0;z-index:10;border-block:1px solid var(--line);background:#07111fe8;backdrop-filter:blur(14px)}.tabs{display:flex;gap:6px;padding:10px 0;overflow-x:auto}.tab{border:0;border-radius:9px;padding:10px 15px;color:var(--muted);background:transparent;font:inherit;font-weight:700;white-space:nowrap;cursor:pointer}.tab:hover{color:var(--text);background:var(--panel)}.tab[aria-selected=true]{color:#07111f;background:var(--brand)}main{padding:34px 0 70px}.pane[hidden],.card[hidden]{display:none}.head{display:flex;justify-content:space-between;gap:24px;align-items:end;margin-bottom:22px}.head p{max-width:720px}.grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}.card{min-width:0;padding:20px;border:1px solid var(--line);border-radius:16px;background:linear-gradient(145deg,#12243af0,#0d1b2ceb);box-shadow:0 18px 55px #00000047}.meta,.links{display:flex;flex-wrap:wrap;gap:8px}.meta{margin:14px 0}.tag{padding:3px 8px;border:1px solid #34516f;border-radius:999px;color:#bdd0e3;font-size:12px}.ready{border-color:#277463;color:#82e7d2}.links{padding-top:9px;border-top:1px solid var(--line)}.search{width:min(360px,100%);padding:11px 14px;border:1px solid var(--line);border-radius:10px;outline:0;color:var(--text);background:var(--panel);font:inherit}.search:focus{border-color:var(--brand)}.empty{display:none;padding:32px;text-align:center;color:var(--muted)}.callout{margin:18px 0;padding:17px 19px;border-left:4px solid var(--brand);border-radius:0 12px 12px 0;background:var(--panel)}.warning{border-left-color:var(--warn)}.steps{counter-reset:step;display:grid;gap:12px}.step{position:relative;padding:20px 20px 20px 70px;border:1px solid var(--line);border-radius:14px;background:var(--panel)}.step:before{counter-increment:step;content:counter(step);position:absolute;left:20px;top:20px;display:grid;place-items:center;width:32px;height:32px;border-radius:50%;color:#07111f;background:var(--brand);font-weight:900}table{width:100%;border-collapse:collapse;margin:18px 0}th,td{padding:11px 13px;border:1px solid var(--line);text-align:left;vertical-align:top}th{color:var(--brand);background:var(--panel2)}td{background:#0d1b2cad}footer{padding:25px 0 45px;color:var(--muted);border-top:1px solid var(--line)}@media(max-width:900px){.grid{grid-template-columns:repeat(2,1fr)}.stats{grid-template-columns:repeat(2,1fr)}}@media(max-width:620px){.grid{grid-template-columns:1fr}.head{display:block}.search{margin-top:12px}header{padding-top:40px}}
Embedded library catalog

Переносимые библиотеки без привязки к плате

Единый справочник по репозиторию templates: назначение модулей, границы платформенного кода и практический маршрут переноса на новый микроконтроллер.

11библиотек C99
1Python-пакет
0обязательных HAL/OS
3.9+версия Python
- +

О репозитории

Повторно используемый код прошивок и инструментов. Каждая библиотека подключается отдельно и хранит состояние у вызывающей стороны.

Ядро независимо

В переносимом слое нет заголовков MCU, HAL, регистров, IRQ, ОС и динамической памяти.

Порт узкий

SPI, GPIO, I²C, UART, CAN, Flash и часы передаются через callbacks или небольшой файл порта.

Подключение точечное

В сборку добавляются только исходники выбранной библиотеки, include-каталог и нужный порт.

Главное правило: распиновка, частоты шин и периферия принадлежат плате. Они остаются в board/ или port/, но не попадают в ядро.

Как добавить в проект

Для фиксируемой версии предпочтителен Git submodule:

git submodule add https://git.rd12.ru/Andrey/templates.git lib/templates
 git submodule update --init --recursive

Если изменения регулярно возвращаются в библиотеку, используйте subtree:

git subtree add --prefix lib/templates https://git.rd12.ru/Andrey/templates.git master --squash
 git subtree pull --prefix lib/templates https://git.rd12.ru/Andrey/templates.git master --squash
Не копируйте исходники вручную: копия быстро расходится с источником и перестаёт получать исправления.
+