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 grisp pack command #85

Merged
merged 2 commits into from
Sep 6, 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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ logs
_build
.idea
rebar3.crashdump
.tool-versions
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,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)
- New pack command to generate GRiSP 2 software update package: [#85](https://github.com/grisp/rebar3_grisp/pull/85)

### Changed

Expand Down
123 changes: 104 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,28 @@ rebar3 grisp deploy --tar
```


### Generate GRiSP 2 Firmwares
### Configuration

`rebar.config`:

```erlang
{grisp, [
{otp, [{version, "22.0"}]},
{deploy, [
% Path to put deployed release in
{destination, "/path/to/destination"},

% Shell script to run before deploying begins
{pre_script, "rm -rf /path/to/destination/*"},

% Shell script to run after deploying has finished
{post_script, "umount /path/to/destination"}
]}
]}.
```


## 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:
Expand Down Expand Up @@ -210,7 +231,7 @@ generation of the software bundle even if one already exists in `_grisp/deploy`:
rebar3 grisp firmware --bootloader --image --force --force-bundle


#### Firmware Update
### Firmware Update

Description of the variables in the commands that will follow:
- **`${RELNAME}`**: The relx release names used when generating the firmware.
Expand Down Expand Up @@ -320,9 +341,9 @@ To reset only the bootloader of the board:
- Reset the GRiSP board again.


#### Cautions
### Cautions

##### With truncated image firmwares
#### 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
Expand All @@ -339,7 +360,7 @@ To change the current active system partition to the first one:
$ state -s


##### With writing system firmware on inactive system partition
#### 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.
Expand All @@ -348,25 +369,89 @@ system is `/dev/mmc1.1`. See [the caution about truncated images firmware](#with
for details on how to consult and change the current active system partition.


### Configuration
## Build Software Update Package

To create a GRiSP software update package, use the 'pack' command:

$ rebar3 grisp pack

It creates a software update package under `_grisp/update`.

To include the bootloader in the generate update package, add the option
`-b/--with-bootloader`:

$ rebar3 grisp pack -b

Note that a toolchain is required for building the bootloader firmware, see the
`deploy` command for more information on how to configure the toolchain.

To force the recreation of the bundle and firmware(s) use the option
`-F/--force-firmware`:

$ rebar3 grisp pack -F

To generate a signed package, use the `-k/--key` option:

$ rebar3 grisp pack --key private_key.pem


### Updating a GRiSP Board

To be able to update a GRiSP board using a software update package, the software
running on the board must have the `grisp_updater_grisp2` dependency in
`rebar.config`:

```erlang
{grisp, [
{otp, [{version, "22.0"}]},
{deploy, [
% Path to put deployed release in
{destination, "/path/to/destination"},
{deps, [grisp_updater_grisp2]}.

% Shell script to run before deploying begins
{pre_script, "rm -rf /path/to/destination/*"},
`grisp_updater` needs to be configured in `sys.config` (or equivalent):

{grisp_updater, [
{signature_check, true},
{signature_certificates, {priv, my_app, "certificates/updates"}},
{system, {grisp_updater_grisp2, #{}}},
{sources, [
{grisp_updater_tarball, #{}},
{grisp_updater_http, #{
backend => {grisp_updater_grisp2, #{}}
}}
]}
]},

If `signature_check` is set to `true` the software package must be signed using
the `-k/--key` option, and the public key must be available in the directory
configured by `signature_certificates`.

When these conditions are met, you can follow these step to perform a A/B
software update of a GRiSP board:

- Unpack the software update package in some local directory:

**`any`** `$ mkdir -p releases/${RELNAME}/${RELVSN}`
**`any`** `$ tar -C releases/${RELNAME}/${RELVSN} -xvf _grisp/update/grisp2.${REL_NAME}".${RELVSN}.${PROFILE}.tar -xvf`

- Start a local HTTP server to serve the package:

**`any`** `$ http-server ./releases -p 8000`

- Open a serial console to the GRiSP board:

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

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

- On the GRiSP2 console, start the update process:

**`GRiSP`** `$ grisp_updater:update(<<"http://${HOST_IP}:8000/${RELNAME}/${RELVSN}">>).`

- Reset the GRiSP2 board using the onboard reset button.

- Validate the new software version on the GRiSP2 console:

**`GRiSP`** `$ grisp_updater:validate().`

Note that the update process will only show progress information if the log
level is at least `INFO`.

% Shell script to run after deploying has finished
{post_script, "umount /path/to/destination"}
]}
]}.
```

## Listing Packages

Expand Down
45 changes: 33 additions & 12 deletions rebar.lock
Original file line number Diff line number Diff line change
@@ -1,41 +1,62 @@
{"1.2.0",
[{<<"bbmustache">>,{pkg,<<"bbmustache">>,<<"1.12.2">>},1},
{<<"certifi">>,{pkg,<<"certifi">>,<<"2.12.0">>},2},
{<<"grid">>,{pkg,<<"grid">>,<<"0.1.0">>},0},
{<<"grisp_tools">>,{pkg,<<"grisp_tools">>,<<"2.6.1">>},0},
{<<"hackney">>,{pkg,<<"hackney">>,<<"1.18.2">>},1},
{<<"edifa">>,{pkg,<<"edifa">>,<<"1.0.0">>},1},
{<<"erlexec">>,{pkg,<<"erlexec">>,<<"2.0.7">>},2},
{<<"grid">>,{pkg,<<"grid">>,<<"0.2.1">>},0},
{<<"grisp_tools">>,{pkg,<<"grisp_tools">>,<<"2.7.0">>},0},
{<<"grisp_update_packager">>,{pkg,<<"grisp_update_packager">>,<<"1.0.0">>},1},
{<<"hackney">>,{pkg,<<"hackney">>,<<"1.20.1">>},1},
{<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},2},
{<<"mapz">>,{pkg,<<"mapz">>,<<"2.4.0">>},1},
{<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2},
{<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.3.0">>},2},
{<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.4.1">>},2},
{<<"quickrand">>,{pkg,<<"quickrand">>,<<"2.0.7">>},3},
{<<"ssl_verify_fun">>,{pkg,<<"ssl_verify_fun">>,<<"1.1.7">>},2},
{<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}]}.
{<<"termseal">>,{pkg,<<"termseal">>,<<"0.1.1">>},2},
{<<"textual">>,{pkg,<<"textual">>,<<"0.1.1">>},1},
{<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2},
{<<"uuid">>,{pkg,<<"uuid_erl">>,<<"2.0.7">>},2}]}.
[
{pkg_hash,[
{<<"bbmustache">>, <<"0CABDCE0DB9FE6D3318131174B9F2B351328A4C0AFBEB3E6E99BB0E02E9B621D">>},
{<<"certifi">>, <<"2D1CCA2EC95F59643862AF91F001478C9863C2AC9CB6E2F89780BFD8DE987329">>},
{<<"grid">>, <<"880F3D2E5B4E9B3B93FDE2BC93F11F6CD6DE82BE886D3AF026C2D6A17C762907">>},
{<<"grisp_tools">>, <<"492F579EE450C7618EDB118A5BBC3F8FE00EC0073305246B80C444C1B176EE8C">>},
{<<"hackney">>, <<"D7FF544DDAE5E1CB49E9CF7FA4E356D7F41B283989A1C304BFC47A8CC1CF966F">>},
{<<"edifa">>, <<"0F1A01A0C79B7135F334B3FCEEB624F0574C5ED3E4554B06C8664AADA6A339C8">>},
{<<"erlexec">>, <<"76D0BC7487929741B5BB9F74DA2AF5DAF1492134733CF9A05C7AAA278B6934C5">>},
{<<"grid">>, <<"4DCBF6155AB24131CB493D417F28093F019197ED7401F28BF82FF60E2C9B0D2C">>},
{<<"grisp_tools">>, <<"2FE6F2CDDB18D7D207CAAAF2ADEDBE0D2533163469D27DDFC5B9AF05F5E41167">>},
{<<"grisp_update_packager">>, <<"0532CCD0955398FAC4E1DE90FE85DB941CA609A2F4E066CFFE01ECE41DCCE119">>},
{<<"hackney">>, <<"8D97AEC62DDDDD757D128BFD1DF6C5861093419F8F7A4223823537BAD5D064E2">>},
{<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>},
{<<"mapz">>, <<"77A8E38B69BAB16C5D3EBD44E6C619F8AF1F1598B0CAAE301D266605A0865756">>},
{<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>},
{<<"mimerl">>, <<"D0CD9FC04B9061F82490F6581E0128379830E78535E017F7780F37FEA7545726">>},
{<<"parse_trans">>, <<"6E6AA8167CB44CC8F39441D05193BE6E6F4E7C2946CB2759F015F8C56B76E5FF">>},
{<<"quickrand">>, <<"D2BD76676A446E6A058D678444B7FDA1387B813710D1AF6D6E29BB92186C8820">>},
{<<"ssl_verify_fun">>, <<"354C321CF377240C7B8716899E182CE4890C5938111A1296ADD3EC74CF1715DF">>},
{<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]},
{<<"termseal">>, <<"C9D93D4FF638EE99F9377D3438FC7AD132D2901EBBAF10C54F8DEA1D7E24D61C">>},
{<<"textual">>, <<"42D6AFE1E58F128E607C237EC213CD3DD69B780A3527039B2A90CA6600456B3C">>},
{<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>},
{<<"uuid">>, <<"B2078D2CC814F53AFA52D36C91E08962C7E7373585C623F4C0EA6DFB04B2AF94">>}]},
{pkg_hash_ext,[
{<<"bbmustache">>, <<"688B33A4D5CC2D51F575ADF0B3683FC40A38314A2F150906EDCFC77F5B577B3B">>},
{<<"certifi">>, <<"EE68D85DF22E554040CDB4BE100F33873AC6051387BAF6A8F6CE82272340FF1C">>},
{<<"grid">>, <<"E71751225A9DFF8C7C96551CC181C0FDD8D8C666D3C2FE44A832D6F8B7BE0013">>},
{<<"grisp_tools">>, <<"7642DE1A466B92AE70C0924605211AD126F65B0F2BFC56069FA996C5CCC78104">>},
{<<"hackney">>, <<"AF94D5C9F97857DB257090A4A10E5426ECB6F4918AA5CC666798566AE14B65FD">>},
{<<"edifa">>, <<"A1E010561E7D236A24C668D95626BE2BFE082ED0331CE1E6798BE0CD43F59A7B">>},
{<<"erlexec">>, <<"AF2DD940BB8E32F5AA40A65CB455DCAA18F5334FD3507E9BFD14A021E9630897">>},
{<<"grid">>, <<"C8EA819A0E40631BECE3149FBA7D306DF6CF8BC35358089878F05B20E6D87D4C">>},
{<<"grisp_tools">>, <<"7B40D67BF53B950C323E92DC8860252052D776A527FC2F4CC9DBEDDF0CFFE949">>},
{<<"grisp_update_packager">>, <<"47BFDF6FADBED4B8342205A812198CF913E0223A98A775CAAE5D2FB5D5CF751C">>},
{<<"hackney">>, <<"FE9094E5F1A2A2C0A7D10918FEE36BFEC0EC2A979994CFF8CFE8058CD9AF38E3">>},
{<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>},
{<<"mapz">>, <<"4B68DF5CF0522E0D6545DF7B681BC052865CDB78405AD4CC9C55FE45EE7B25BE">>},
{<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>},
{<<"mimerl">>, <<"A1E15A50D1887217DE95F0B9B0793E32853F7C258A5CD227650889B38839FE9D">>},
{<<"parse_trans">>, <<"620A406CE75DADA827B82E453C19CF06776BE266F5A67CFF34E1EF2CBB60E49A">>},
{<<"quickrand">>, <<"B8ACBF89A224BC217C3070CA8BEBC6EB236DBE7F9767993B274084EA044D35F0">>},
{<<"ssl_verify_fun">>, <<"FE4C190E8F37401D30167C8C405EDA19469F34577987C76DDE613E838BBC67F8">>},
{<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]}
{<<"termseal">>, <<"466280936214AF1894FC431642E83341B7D13580A3F3485820A2D300C5CAEB49">>},
{<<"textual">>, <<"28C1AE5DE77D3A13C9101DD64204C87069232149C2B924762F43D75730516CE9">>},
{<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>},
{<<"uuid">>, <<"4E4C5CA3461DC47C5E157ED42AA3981A053B7A186792AF972A27B14A9489324E">>}]}
].
3 changes: 2 additions & 1 deletion src/rebar3_grisp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ init(State) ->
rebar3_grisp_package,
rebar3_grisp_version,
rebar3_grisp_report,
rebar3_grisp_firmware
rebar3_grisp_firmware,
rebar3_grisp_pack
]).
8 changes: 4 additions & 4 deletions src/rebar3_grisp_firmware.erl
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ init(State) ->
"If no bundle file is specified, it will be generated by "
"calling 'rebar3 grisp deploy' with the optional release name "
"and version. As for the deploy command, options passed after "
"'--' are sent to the Rebar 3 release task.\n"
"'--' are sent to the rebar 3 release task.\n"
}
]),
{ok, rebar_state:add_provider(State, Provider)}.
Expand Down Expand Up @@ -283,7 +283,7 @@ event([firmware, prepare, _, {error, not_a_file, Path}]) ->
event([firmware, build_firmware, create_image]) ->
console("* Creating disk image...");
event([firmware, build_firmware, create_image, {error, Reason}]) ->
abort_message("Failed to create firmware image file; ~s", Reason);
abort_message("Failed to create firmware image file: ~s", Reason);
event([firmware, build_firmware, copy_bootloader]) ->
console("* Writing bootloader...");
event([firmware, build_firmware, copy_bootloader, {error, Reason}]) ->
Expand Down Expand Up @@ -346,9 +346,9 @@ event(Event) ->
debug("[rebar3_grisp] ~p", [Event]),
case lists:last(Event) of
{error, Reason, Info} when is_binary(Info) ->
abort("Unexpected 1 ~p error: ~s", [Reason, Info]);
abort("Unexpected ~p error: ~s", [Reason, Info]);
{error, Reason, Info} ->
abort("Unexpected 2 ~p error: ~p", [Reason, Info]);
abort("Unexpected ~p error: ~p", [Reason, Info]);
{error, Reason} ->
abort("Unexpected ~p error", [Reason]);
_ -> ok
Expand Down
Loading
Loading