ide: the Atmel Studio solution master has, on the libavr port
master carries bootloader.atsln, so main does too. Two projects, because a .cppproj is one binary at one flag set and this build has hundreds: the stock 328P pureboot loader (USART0 at 115200 on a 16 MHz crystal), and the tsb_asm tier that occupies the same 512-byte section master's own tsb project targeted. Both come out byte-identical to the Ninja build — 404 B and 510 B of .text — in both configurations. Debug keeps -Os and adds only -gdwarf-4. A loader's section is a correctness bound, and -Og builds this source to 590 B: the link at 0x7e00 accepts that without a diagnostic, 78 bytes past flash end, where rcall/rjmp wrap modulo flash size and the image dies just after activation. Debug info costs no flash, so the optimisation level stays where correctness needs it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
78
ide/README.md
Normal file
78
ide/README.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Atmel Studio
|
||||
|
||||
`master` carries `bootloader.atsln`, so this branch does too: `ide/bootloader.atsln`
|
||||
builds the loaders from the same sources Ninja does, to a **byte-identical
|
||||
`.text`** — 404 B for the 328P pureboot loader, 510 B for the `tsb_asm` tier in
|
||||
its 512-byte section. CMake remains the build system; the solution is here so the
|
||||
port opens in Studio as its predecessor did.
|
||||
|
||||
## The two projects, and why two
|
||||
|
||||
pureboot is a chip × backend × clock × baud matrix — `pureboot_add_loader()`
|
||||
resolves a deployment into compile definitions — and a `.cppproj` is one binary
|
||||
at one set of flags, so a project can only ever be one point of it. `pureboot`
|
||||
is that point: the stock 328P deployment, USART0 at 115200 on a 16 MHz crystal,
|
||||
an 8-second activation window. `tsb_asm` is the TinySafeBoot tier that occupies
|
||||
the same 512-byte section `master`'s `tsb` project targeted.
|
||||
|
||||
The other three tsb tiers (`tsb_pure`, `tsb_tricks`, `tsb_policy`) are not here.
|
||||
They differ from `tsb_asm` in their source file, their section size, and — for
|
||||
`tsb_policy` — two loop flags; nothing about that is a Studio concern, and what
|
||||
they exist to demonstrate is a size gradient only the CMake size tests measure.
|
||||
Adding one is a copy of `tsb_asm/tsb_asm.cppproj` in its own directory, with its
|
||||
name, its GUID, its source path and its `--section-start` changed (`0x7c00` for
|
||||
the 1 KiB tiers), plus four lines in the solution.
|
||||
|
||||
`avrdevice` is a project property, so each project gets its own directory:
|
||||
Studio builds into `<project dir>/<Configuration>` whatever `OutputDirectory`
|
||||
says, and two projects sharing a directory would share one object file.
|
||||
|
||||
## Debug keeps `-Os`
|
||||
|
||||
Both configurations compile at `-Os`; Debug adds only `-gdwarf-4`. The `.text`
|
||||
is therefore identical in both, which is the point — a loader's section is a
|
||||
**correctness** bound and not a budget. `-Og` builds this same source to 590 B,
|
||||
and linking it at `--section-start=.text=0x7e00` on a 32 KiB part puts 78 bytes
|
||||
past flash end **without a diagnostic**: `rcall`/`rjmp` targets there wrap
|
||||
modulo flash size, so the image dies right after activation. A debug
|
||||
configuration that silently produces that is worse than none, and DWARF costs no
|
||||
flash, so the optimisation level stays where correctness needs it.
|
||||
|
||||
## What Studio needs from the machine
|
||||
|
||||
libavr checked out **beside this repo**, found at
|
||||
`$(MSBuildProjectDirectory)\..\..\..\libavr\include` — anchored to the project,
|
||||
because a plain relative path resolves against the generated makefile's
|
||||
directory (the configuration's output directory), not the project's. There is no
|
||||
`LIBAVR_ROOT` escape hatch: a variable exported in a shell is invisible to Studio
|
||||
launched from the Start menu, and the failure reads as a missing
|
||||
`libavr/libavr.hpp`. Pinning libavr as a submodule is the better answer and is on
|
||||
libavr's task list.
|
||||
|
||||
A GCC 16.1 toolchain registered as flavour `avr-g++-16.1.0`, nothing older
|
||||
reaching `-std=c++26`.
|
||||
|
||||
## Generating and gating
|
||||
|
||||
One generated file is required before a project will load at all, and one command
|
||||
per project checks the flags have not drifted (both from libavr's
|
||||
`tools/atmelstudio/`):
|
||||
|
||||
```sh
|
||||
for name in pureboot tsb_asm; do
|
||||
python ../libavr/tools/atmelstudio/componentinfo.py \
|
||||
"ide/$name/$name.componentinfo.xml" --device ATmega328P
|
||||
python ../libavr/tools/atmelstudio/check-flags.py \
|
||||
--solution ide/bootloader.atsln --project "$name" --target "$name" \
|
||||
--compile-commands build/atmega328p-generated/compile_commands.json \
|
||||
--log "build/as-$name.log"
|
||||
done
|
||||
```
|
||||
|
||||
`--project` because one reference describes one binary; `--target` because
|
||||
`pureboot.cpp` is compiled by every point of the size matrix and the flags
|
||||
differ per point, so the basename alone does not name a reference. Release is
|
||||
what the gate compares — the presets define no debug build, and Debug differs
|
||||
from Release only in `-gdwarf-4`.
|
||||
|
||||
Legacy (the yazoalfa-era submodules) stays on `master`.
|
||||
Reference in New Issue
Block a user