pureboot.py (Python stdlib only): images as raw binary or Intel HEX, flash and EEPROM programming with read-back verify, erase composites, fuse and info readout, activation-timeout configuration, and the tinies' reset-vector surgery — the trampoline word below the loader, page 0 written last. The test spawns a simavr device (pureboot_device.c) — the mega's USART as a pty; on the tinies a cycle-timed GPIO<->pty bridge for the polled software UART plus the NVM module simavr's tiny cores lack (their SPM opcode ioctls into a void and silently does nothing) — and drives it with the real tool: knock from reset (erased-flash walk on the tinies), program and verify both memories, timeout write, session reconnect, an external reset through the patched vector, hand-over, and the fixture application's banner. Results are cross-checked against ground-truth memory dumps and an independent decode of the surgery's rjmp words, red-verified against a sabotaged encoder. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
52 lines
1.2 KiB
C++
52 lines
1.2 KiB
C++
// Test-fixture application for the pureboot protocol test: prints "APP" on
|
|
// the chip's serial link (the same link the loader uses) and idles — the
|
|
// proof that the loader's hand-over, and on the tinies the host's
|
|
// reset-vector surgery, actually launched it. Linked normally (crt, vectors
|
|
// at 0); on the tinies its reset vector is the rjmp the host re-homes.
|
|
#include <libavr/libavr.hpp>
|
|
|
|
using namespace avr::literals;
|
|
|
|
namespace {
|
|
|
|
consteval avr::hertz_t clock()
|
|
{
|
|
if (avr::hw::db.name == "ATtiny13A")
|
|
return 9.6_MHz;
|
|
if (avr::hw::db.name == "ATtiny85")
|
|
return 8_MHz;
|
|
return 16_MHz;
|
|
}
|
|
|
|
using dev = avr::device<{.clock = clock()}>;
|
|
|
|
template <avr::hertz_t C, bool Hardware = avr::hw::db.has_reg("UDR0")>
|
|
struct link {
|
|
using tx_t = avr::uart::usart0<C, {.baud = 115200_Bd, .max_baud_error = 2.5_pct}>;
|
|
static void tx(char c)
|
|
{
|
|
tx_t::write(static_cast<std::uint8_t>(c));
|
|
}
|
|
};
|
|
|
|
template <avr::hertz_t C>
|
|
struct link<C, false> {
|
|
using tx_t = avr::uart::software_tx<C, avr::pb1, 57600_Bd>;
|
|
static void tx(char c)
|
|
{
|
|
tx_t::write(static_cast<std::uint8_t>(c));
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
|
|
int main()
|
|
{
|
|
avr::init<typename link<dev::clock>::tx_t>();
|
|
link<dev::clock>::tx('A');
|
|
link<dev::clock>::tx('P');
|
|
link<dev::clock>::tx('P');
|
|
while (true) {
|
|
}
|
|
}
|