Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add firmware command #83

Merged
merged 2 commits into from
Sep 2, 2024
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- New `-t/--tar` option to the deploy command to save a grisp release tarball in
the `_grisp/deploy` directory.
- New firmware command to generate GRiSP 2 binary firmwares: [#83](https://github.com/grisp/rebar3_grisp/pull/83)

### Changed

Expand Down
13 changes: 1 addition & 12 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -175,18 +175,7 @@

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright {yyyy} {name of copyright owner}
Copyright 2017 Peer Stritzinger GmbH <[email protected]>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
180 changes: 180 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,186 @@ all the files will be bundled in a a tarball under `_grisp/deploy`:
rebar3 grisp deploy --tar
```


### Generate GRiSP 2 Firmwares

The `firmware` command generates binary files that can be written on GRiSP 2
eMMC. There is three types of firmware that can be generated:

- **System Firmware**:
The system firmware is the content of a system partition on the eMMC.
When using A/B software update, the system firmware can be written either
on the first or the second system partition. By default, the command will
generate a system firmware under `_grisp/firmware` but it can be disabled with
the option `-b false` or `--system false`.
- **eMMC Image Firmware**:
The eMMC image firmware is a full image containing the bootloader, the
partition table and the system partitions. It is meant to be written on the
GRiSP 2 board to reset it completely with the new software. If the image is
truncated (it is by default), the image only contains the first system
partition. It means that when writing the firmware to the eMMC, the second
system partition will be untouched. To generate an eMMC image firmware under
`_grisp/firmware`, add the option `-i` or `--image`, to disable truncating
so the image contains both system partitions, uses the option `-t false` or
`--truncate false`.
- **Bootloader Firmware**:
The bootloader firmware contains only the bootloader and the partition table.
To generate it under `_grisp/firmware`, add the option `-b` or `--bootloader`.

e.g.

Generate a system firmware for the default release:

rebar3 grisp firmware

Generate a system firmware for a specific release:

rebar3 grisp firmware --relname myapp --relvsn 1.2.3

Generate all firmwares, forcing existing files to be overwritten and forcing the
generation of the software bundle even if one already exists in `_grisp/deploy`:

rebar3 grisp firmware --bootloader --image --force --force-bundle


#### Firmware Update

Description of the variables in the commands that will follow:
- **`${RELNAME}`**: The relx release names used when generating the firmware.
- **`${RELVSN}`**: The relx release version used when generating the firmware.
- **`${USER}`**: The username of the account running the command.
- **`${GRISP_BOARD_SERIAL}`**: The serial number of the GRiSP 2 board.

To write a system firmware to a GRiSP 2 board:

- Copy the firmware to the SD card:

**`macOS`** `$ cp _grisp/firmware/grisp2.${RELNAME}.${RELVSN}.sys.gz /Volumes/GRISP`

**`Linux`** `$ cp _grisp/firmware/grisp2.${RELNAME}.${RELVSN}.sys.gz /media/${USER}/GRISP`

- Unmount the SD card:

**`macOS`** `$ diskutil umount /Volumes/GRISP`

**`Linux`** `$ umount /media/${USER}/GRISP`

- Open a serial console to the GRiSP board:

**`macOS`** `$ screen /dev/tty.usbserial-0${GRISP_BOARD_SERIAL}1 115200`

**`Linux`** `$ screen /dev/ttyUSB1 115200`

- Insert the SD card in the GRiSP 2 board.
- Reset the board using the onboard reset button.
- Enter into barebox console mode by pressing any key before 3 seconds.
- Consult the current active system partition:

**`Barebox`** `$ echo $state.bootstate.active_system`

- Write the firmware. If the current active system is `0`, use device
`/dev/mmc1.0`, if it is `1` use device `/dev/mmc1.1`:

**`Barebox`** `$ uncompress /mnt/mmc/grisp2.${RELNAME}.${RELVSN}.sys.gz /dev/mmc1.0`

- Remove the SD card.
- Reset the GRiSP board again.

To reset a GRiSP 2 board eMMC, either with a truncated or full image firmware:

- Copy the firmware to the SD card:

**`macOS`** `$ cp _grisp/firmware/grisp2.${RELNAME}.${RELVSN}.emmc.gz /Volumes/GRISP`

**`Linux`** `$ cp _grisp/firmware/grisp2.${RELNAME}.${RELVSN}.emmc.gz /media/${USER}/GRISP`

- Unmount the SD card:

**`macOS`** `$ diskutil umount /Volumes/GRISP`

**`Linux`** `$ umount /media/${USER}/GRISP`

- Open a serial console to the GRiSP board:

**`macOS`** `$ screen /dev/tty.usbserial-0${GRISP_BOARD_SERIAL}1 115200`

**`Linux`** `$ screen /dev/ttyUSB1 115200`

- Insert the SD card in the GRiSP 2 board.
- Reset the board using the onboard reset button.
- Enter into barebox console mode by pressing any key before 3 seconds.
- Set the current active system partition to the first one:

**`Barebox`** `$ let state.bootstate.active_system=0`

**`Barebox`** `$ state -s`

- Write the firmware:

**`Barebox`** `$ uncompress /mnt/mmc/grisp2.${RELNAME}.${RELVSN}.emmc.gz /dev/mmc1`

- Remove the SD card.
- Reset the GRiSP board again.

To reset only the bootloader of the board:

- Copy the firmware to the SD card:

**`macOS`** `$ cp _grisp/firmware/grisp2.${RELNAME}.${RELVSN}.boot.gz /Volumes/GRISP`

**`Linux`** `$ cp _grisp/firmware/grisp2.${RELNAME}.${RELVSN}.boot.gz /media/${USER}/GRISP`

- Unmount the SD card:

**`macOS`** `$ diskutil umount /Volumes/GRISP`

**`Linux`** `$ umount /media/${USER}/GRISP`

- Open a serial console to the GRiSP board:

**`macOS`** `$ screen /dev/tty.usbserial-0${GRISP_BOARD_SERIAL}1 115200`

**`Linux`** `$ screen /dev/ttyUSB1 115200`

- Insert the SD card in the GRiSP 2 board.
- Reset the board using the onboard reset button.
- Enter into barebox console mode by pressing any key before 3 seconds.
- Write the firmware:

**`Barebox`** `$ uncompress /mnt/mmc/grisp2.${RELNAME}.${RELVSN}.boot.gz /dev/mmc1`

- Remove the SD card.
- Reset the GRiSP board again.


#### Cautions

##### With truncated image firmwares

When writing a truncated eMMC image firmware, only the first system partition is
written. If the active system is the second one, the board will continue to boot
the old software. You will need to manually change the active system partition
in the bootloader console and restart the board.

To consule the current active system partition in the bootloader console:

$ echo $state.bootstate.active_system

To change the current active system partition to the first one:

$ let state.bootstate.active_system=0
$ state -s


##### With writing system firmware on inactive system partition

When writing a system firmware, be sure to do it on the active system
partition or the board will continue to boot the old software.
The device for the first system is `/dev/mmc1.0` and the one for the second
system is `/dev/mmc1.1`. See [the caution about truncated images firmware](#with-truncated-image-firmwares)
for details on how to consult and change the current active system partition.


### Configuration

`rebar.config`:
Expand Down
3 changes: 2 additions & 1 deletion src/rebar3_grisp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ init(State) ->
rebar3_grisp_configure,
rebar3_grisp_package,
rebar3_grisp_version,
rebar3_grisp_report
rebar3_grisp_report,
rebar3_grisp_firmware
]).
30 changes: 9 additions & 21 deletions src/rebar3_grisp_build.erl
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ do(RState) ->
Apps = rebar3_grisp_util:apps(RState),

ProjectRoot = rebar_dir:root_dir(RState),
ToolchainRoot = toolchain_root(Config),
ToolchainRoot = toolchain_root(RState),

Flags = maps:from_list([
{F, rebar3_grisp_util:get(F, Opts, D)}
Expand Down Expand Up @@ -113,28 +113,16 @@ format_error(Reason) ->

%--- Internal ------------------------------------------------------------------

toolchain_root(Config) ->
DockerImg = rebar3_grisp_util:get([build, toolchain, docker], Config, error),
TCDir = rebar3_grisp_util:get([build, toolchain, directory], Config, error),
case os:getenv("GRISP_TOOLCHAIN", TCDir) of
error -> case DockerImg of
error -> abort_no_toolchain();
DockerImage ->
ensure_docker(),
{docker, DockerImage}
end;
Directory ->
{directory, Directory}
end.

ensure_docker() ->
case rebar3_grisp_util:sh("docker info",[return_on_error]) of
{error, _} -> abort("Docker is not available");
{ok, _} -> ok
toolchain_root(RebarState) ->
case rebar3_grisp_util:toolchain_root(RebarState) of
undefined -> abort_no_toolchain();
{docker, _DockerImage} = Result -> Result;
{directory, _Directory} = Result -> Result;
{error, docker_not_found} -> abort("Docker is not available")
end.

abort_no_toolchain() ->
"Please specify the full path to the toolchain directory in your rebar.conf:
abort("Please specify the full path to the toolchain directory in your rebar.conf:
{grisp, [
...,
Expand All @@ -147,7 +135,7 @@ abort_no_toolchain() ->
]}
]}.
Alternatively, you can set the GRISP_TOOLCHAIN environment variable.".
Alternatively, you can set the GRISP_TOOLCHAIN environment variable.").

abort_no_build() ->
abort("There was no build section found in your rebar.conf").
Expand Down
Loading
Loading