Skip to content
Merged
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
10 changes: 6 additions & 4 deletions Harp.Toolkit.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Harp.Toolkit", "src\Harp.Toolkit\Harp.Toolkit.csproj", "{BFC25910-BC44-4792-9CDE-5B3A17D0B157}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Harp.Toolkit.Tests", "src\Harp.Toolkit.Tests\Harp.Toolkit.Tests.csproj", "{1F352150-EC14-445E-873E-24CA0F38BFE9}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{DEE5DD87-39C1-BF34-B639-A387DCCF972B}"
ProjectSection(SolutionItems) = preProject
build\Common.csproj.props = build\Common.csproj.props
Expand All @@ -25,10 +27,10 @@ Global
{BFC25910-BC44-4792-9CDE-5B3A17D0B157}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BFC25910-BC44-4792-9CDE-5B3A17D0B157}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BFC25910-BC44-4792-9CDE-5B3A17D0B157}.Release|Any CPU.Build.0 = Release|Any CPU
{EC58E518-3522-4B04-9A05-DE7F14A51FFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EC58E518-3522-4B04-9A05-DE7F14A51FFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EC58E518-3522-4B04-9A05-DE7F14A51FFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EC58E518-3522-4B04-9A05-DE7F14A51FFA}.Release|Any CPU.Build.0 = Release|Any CPU
{1F352150-EC14-445E-873E-24CA0F38BFE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1F352150-EC14-445E-873E-24CA0F38BFE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1F352150-EC14-445E-873E-24CA0F38BFE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1F352150-EC14-445E-873E-24CA0F38BFE9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
18 changes: 12 additions & 6 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,23 @@ Tool for inspecting, updating and interfacing with Harp devices, with automatic

Each read waits up to 2000 milliseconds for a response. Pass `--timeout` to change that default, or `--timeout -1` to wait indefinitely.

6. To update the device firmware from a local HEX file:
6. To restore the tool at any point, run:

```cmd
dotnet harp.toolkit update --port COM4 Behavior-fw3.2-harp1.13-hw2.0-ass0.hex
dotnet tool restore
```

7. To restore the tool at any point, run:
## Firmware Update

```cmd
dotnet tool restore
```
`harp.toolkit` can write a firmware image to a connected device, checking that the image is compatible before writing anything:

```cmd
dotnet harp.toolkit update --port COM4 Behavior-fw3.3-harp1.15-hw2.0-ass0.hex
```

An update resets the device, so avoid updating firmware that is part of a running experiment, since interrupting an update leaves the device in bootloader mode until one completes successfully.

See [Firmware Update](https://harp-tech.org/toolkit/articles/update.html) for the naming convention used by firmware images, how to recover a device left in bootloader mode, and the available options.

## Code Generation

Expand Down
1 change: 1 addition & 0 deletions docs/articles/toc.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
- name: Introduction
href: ../index.md
- href: update.md
- href: generate.md
- href: verify.md
90 changes: 90 additions & 0 deletions docs/articles/update.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Firmware Update

`harp.toolkit` can write a firmware image to a connected device over its serial port, using the bootloader built into the ATxmega core. The image states the device name and hardware version it targets, and the update checks it is compatible before writing anything.

Devices built on the Pico core are not currently supported. They update through a different process, and their firmware is distributed as `.uf2` images rather than Intel HEX.

> [!Warning]
> An update resets the device, so avoid updating firmware that is part of a running experiment. Interrupting an update leaves the device in bootloader mode, where it stops answering Harp commands until an update completes successfully. This is a fail-safe rather than damage, and [Recovering a device in bootloader mode](#recovering-a-device-in-bootloader-mode) describes the recovery.

## Updating a device

An update needs the serial port and a firmware image.

```ps1
dotnet harp.toolkit update --port COM3 Behavior-fw3.3-harp1.15-hw2.0-ass0.hex
```

The command reads the device name and hardware version, checks that the image is compatible, resets the device into its bootloader, writes the image one page at a time, and then leaves the bootloader so the new firmware starts. Progress is reported as a percentage while the image is written.

A device takes a moment to answer Harp again once an update finishes, measured at a median of about two seconds and occasionally over ten. A tool that reconnects immediately may find the device unresponsive and should retry before treating it as a failure.

#### Firmware image
```ps1
<firmware>
```

Path to the firmware image in Intel HEX format. The file must exist, and its name must follow the convention described in [Firmware image names](#firmware-image-names). This argument is required.

#### Serial port
```ps1
--port <port>
```

Name of the serial port used to communicate with the device. This option is required.

#### Response timeout
```ps1
--timeout <timeout>
```

Time in milliseconds to wait for the device to answer each Harp command. It applies while the update reads the device identity and requests the reset. The default is 2000, and `-1` waits indefinitely. Increase it if the device is slow to answer, for example immediately after an earlier update. It does not affect the bootloader protocol, which uses its own timeout.

### Exit code

The command exits 0 once the image is written and the device has left the bootloader, and 1 otherwise. Every failure is reported as a message rather than a stack trace. A failure after the device has been reset also reports the percentage reached.

## Firmware image names

The update reads the device and version information from the file name, not from the contents of the image. The name must follow this convention:

```
<device>-fw<firmware>-harp<core>-hw<hardware>-ass<assembly>.hex
```

`<device>` is the device name reported by `R_DEVICE_NAME`. `<firmware>`, `<core>` and `<hardware>` are two-part versions, and `<assembly>` is the board assembly number. A preview build adds a `-preview<number>` suffix.

An image built for a range of hardware revisions states `x` in place of a hardware version component. For example, `hw1.x` marks an image that is valid for every revision of hardware 1.

The update refuses an image when the device name does not match the connected device, or when the device does not satisfy the hardware version. The message names both sides, so the mismatch is visible without opening the file.

## Recovering a device in bootloader mode

The bootloader records that a page was written, and stays in control until an update completes. That record survives a power cycle. A disconnected cable or a closed terminal can therefore leave the device in bootloader mode, without going back to the firmware it had before.

A device in that state does not answer Harp commands, so an ordinary update cannot read its identity and cannot reach it. The update detects the condition and reports it:

```
The device on the serial port COM3 specified with --port did not respond in time. The device
is in bootloader mode, left there by an interrupted update. Re-run with --force, which skips
the compatibility check when the device cannot answer.
```

Repeat the update with `--force` to recover the device.

```ps1
dotnet harp.toolkit update --port COM3 --force Behavior-fw3.3-harp1.15-hw2.0-ass0.hex
```

If the forced update does not reach the device either, power cycle it first and repeat. A partial page in the receive buffer holds the bootloader until it is reset.

#### Force an update
```ps1
--force
```

Writes the image without the compatibility check.

The flag covers two situations that cannot be separated. A device in bootloader mode reports no identity, so there is nothing to check the image against. Recovering a device in that state therefore requires this flag.

The other use is firmware development. Do not use the flag only because an update was refused. The flag removes the only check that prevents an update with an image targeting a different device. If an image names a different device, it is usually the wrong image.
3 changes: 3 additions & 0 deletions src/Harp.Toolkit.Tests/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;

[assembly: Parallelize]
Loading
Loading