Skip to content

Commit c679599

Browse files
authored
chore: build on CI (#1)
1 parent 39e557a commit c679599

9 files changed

Lines changed: 235 additions & 2 deletions

File tree

.github/workflows/build.yml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: "Build firmware"
2+
3+
# Run this job on all pushes to master, for pull requests
4+
# as well as tags with a semantic version
5+
on:
6+
push:
7+
branches:
8+
# This avoids having duplicate builds in non-forked PRs
9+
- "master"
10+
tags:
11+
# normal versions
12+
- "v[0-9]+.[0-9]+.[0-9]+"
13+
# pre-releases
14+
- "v[0-9]+.[0-9]+.[0-9]+-**"
15+
pull_request: {}
16+
17+
# Cancel previous PR/branch runs when a new commit is pushed
18+
concurrency:
19+
group: "build-firmware-${{ github.ref }}"
20+
cancel-in-progress: true
21+
22+
jobs:
23+
build:
24+
runs-on: ubuntu-latest
25+
26+
steps:
27+
- name: Checkout repo
28+
uses: actions/checkout@v4
29+
30+
- name: Install Node.js
31+
uses: actions/setup-node@v4
32+
with:
33+
node-version: lts/*
34+
35+
- name: Download Simplicity SDK
36+
run: |
37+
curl -o simplicity_sdk_2024.12.1.zip -L https://github.com/SiliconLabs/simplicity_sdk/releases/download/v2024.12.1-0/simplicity-sdk.zip \
38+
&& unzip -q -d /opt/simplicity_sdk simplicity_sdk_2024.12.1.zip \
39+
&& rm simplicity_sdk_2024.12.1.zip
40+
41+
- name: Download SLC CLI
42+
run: |
43+
curl -O https://www.silabs.com/documents/login/software/slc_cli_linux.zip \
44+
&& unzip -q -d /opt slc_cli_linux.zip \
45+
&& rm slc_cli_linux.zip
46+
47+
# Install Simplicity Commander (unfortunately no stable URL available, this
48+
# is known to be working with Commander_linux_x86_64_1v15p0b1306.tar.bz).
49+
- name: Download Simplicity Commander
50+
run: |
51+
curl -O https://www.silabs.com/documents/login/software/SimplicityCommander-Linux.zip \
52+
&& unzip -q SimplicityCommander-Linux.zip \
53+
&& tar -C /opt -xjf SimplicityCommander-Linux/Commander_linux_x86_64_*.tar.bz \
54+
&& rm -r SimplicityCommander-Linux \
55+
&& rm SimplicityCommander-Linux.zip
56+
57+
# GCC Embedded Toolchain 12.2.rel1 (for Gecko SDK 4.4.0+)
58+
- name: Download Toolchain
59+
run: |
60+
curl -O https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.2.rel1/binrel/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi.tar.xz \
61+
&& tar -C /opt -xf arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi.tar.xz \
62+
&& rm arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi.tar.xz
63+
64+
- name: Build project
65+
run: tools/build.sh
66+
env:
67+
SDK: /opt/simplicity_sdk
68+
SLC: /opt/slc_cli/slc
69+
COMMANDER: /opt/commander/commander
70+
71+
- name: Upload GBL
72+
uses: actions/upload-artifact@v4
73+
with:
74+
name: zwa2_controller.gbl
75+
path: artifact/zwa2_controller.gbl
76+
77+
- name: Copy HEX file
78+
run: cp build/release/nc_controller_ncp.hex artifact/zwa2_controller.hex
79+
80+
- name: Upload HEX
81+
uses: actions/upload-artifact@v4
82+
with:
83+
name: zwa2_controller.hex
84+
path: artifact/zwa2_controller.hex

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ artifact/
77
.settings/
88
.slc_state/
99
sbom/
10+
build/
11+
.env
12+
/*.Makefile
13+
/*.mak

keys/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
These keys are here on purpose. They are meant to prevent accidental flashing with the wrong firmware.

keys/vendor_encrypt.key

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Key randomly generated by 'commander ebl keygen'
2+
TOKEN_MFG_SECURE_BOOTLOADER_KEY: 7F8FE53979B31BC556FCB131AFF42414

keys/vendor_sign.key

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-----BEGIN EC PRIVATE KEY-----
2+
MHcCAQEEIFpaZQjeFqANdLxOMKisgXa+CM83BIdV+mL3Ca8h41qToAoGCCqGSM49
3+
AwEHoUQDQgAEo5DxXcaDxoE2Iyy8CbxfnGqspwIOsg2MUX7E8YpIqKD8VatZqQC1
4+
GZvnuvsbd7zIhobxX/3z/qze7ll4wbYRfQ==
5+
-----END EC PRIVATE KEY-----

nc_controller_ncp.slcp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Silicon Labs Project Configuration Tools: slcp, v0, Component selection file.
1+
# Silicon Labs Project Configuration Tools: slcp, v0, Component selection file.
22
project_name: nc_controller_ncp
33
label: nc_controller_ncp
44
description: |
@@ -127,4 +127,4 @@ ui_hints:
127127
- {path: README.md, focus: true}
128128
post_build:
129129
- {path: nc_controller_ncp.slpb, profile: zwave_ncp_serial_api_controller}
130-
130+

tools/build.sh

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/bin/bash
2+
# Required env variables:
3+
# SLC: Path to SLC-CLI
4+
# SDK: Path to SDK root
5+
# COMMANDER: Path to Simplicity Commander binary
6+
7+
if [ -z "${SLC}" ]; then
8+
echo "ERROR: env variable SLC must be set to SLC-CLI binary"
9+
exit 1
10+
fi
11+
12+
if [ -z "${SDK}" ]; then
13+
echo "ERROR: env variable SDK must be set to SDK root"
14+
exit 1
15+
fi
16+
17+
if [ -z "${COMMANDER}" ]; then
18+
echo "ERROR: env variable COMMANDER must be set to Simplicity Commander binary"
19+
exit 1
20+
fi
21+
22+
POST_BUILD_EXE=tools/mkgbl.sh
23+
PROJ_NAME=nc_controller_ncp
24+
25+
rm -rf build/
26+
rm -f *.Makefile
27+
rm -f *.mak
28+
29+
$SLC signature trust --sdk $SDK
30+
31+
# Find the toolchain if not set
32+
if [ -z "${TOOLCHAIN}" ]; then
33+
TOOLCHAIN=$(find /opt -maxdepth 1 -type d -name "*arm-none-eabi*" | head -n 1)
34+
echo "Found toolchain: $TOOLCHAIN"
35+
fi
36+
37+
$SLC generate \
38+
--project-file $PROJ_NAME.slcp \
39+
--export-destination build/ \
40+
--sdk "$SDK" \
41+
--no-copy \
42+
--toolchain toolchain_gcc \
43+
--output-type makefile
44+
45+
node tools/patch_makefile.mjs
46+
47+
cp build/*.Makefile ./
48+
cp build/*.mak ./
49+
# Fix the include path to point to the current directory
50+
sed -i 's/-I\.\. /-I\. /g' *.mak
51+
52+
make release -B -f $PROJ_NAME.Makefile POST_BUILD_EXE=$POST_BUILD_EXE ARM_GCC_DIR=$TOOLCHAIN

tools/mkgbl.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/bash
2+
# Required env variables:
3+
# COMMANDER: Path to Simplicity Commander binary
4+
5+
BUILD_OUTPUT=build/release/nc_controller_ncp.hex
6+
OUTFILE=artifact/zwa2_controller.gbl
7+
SIGN_KEY=keys/vendor_sign.key
8+
ENC_KEY=keys/vendor_encrypt.key
9+
10+
mkdir -p artifact
11+
12+
$COMMANDER gbl create $OUTFILE --app $BUILD_OUTPUT --sign $SIGN_KEY --encrypt $ENC_KEY --compress lzma

tools/patch_makefile.mjs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// @ts-check
2+
import fs from "node:fs/promises";
3+
import path from "node:path";
4+
5+
const SDK_DIR = "simplicity_sdk_2024.12.1";
6+
7+
const filename = (await fs.readdir("build")).find((f) => f.endsWith(".mak"));
8+
if (!filename) {
9+
console.error("Makefile not found in build directory.");
10+
process.exit(1);
11+
}
12+
13+
let makefile = await fs.readFile(`build/${filename}`, "utf8");
14+
15+
let prefixEnd = makefile.indexOf("SDK Build Rules");
16+
prefixEnd = makefile.indexOf("#####\n", prefixEnd) + 6;
17+
18+
const suffixIndex = makefile.lastIndexOf(
19+
"# Automatically-generated Simplicity Studio Metadata"
20+
);
21+
22+
const allSources = (await fs.readdir(process.cwd(), { recursive: true }))
23+
.filter((f) => f.endsWith(".c") || f.endsWith(".S"))
24+
.filter((f) => !f.split(path.sep).includes("build"));
25+
26+
const projectSources = allSources.filter(
27+
(f) => !f.split(path.sep).includes(SDK_DIR)
28+
);
29+
30+
const sdkSources = allSources.filter((f) =>
31+
f.split(path.sep).includes(SDK_DIR)
32+
);
33+
34+
let fileImports = "";
35+
for (const source of sdkSources) {
36+
let relative = source.slice(source.indexOf(path.sep) + 1);
37+
let withoutExt = relative.slice(0, relative.lastIndexOf("."));
38+
39+
fileImports += `
40+
$(OUTPUT_DIR)/sdk/${withoutExt}.o: $(COPIED_SDK_PATH)/${relative}
41+
@$(POSIX_TOOL_PATH)echo 'Building $(COPIED_SDK_PATH)/${relative}'
42+
@$(POSIX_TOOL_PATH)mkdir -p $(@D)
43+
$(ECHO)$(CC) $(CFLAGS) -c -o $@ $(COPIED_SDK_PATH)/${relative}
44+
CDEPS += $(OUTPUT_DIR)/sdk/${withoutExt}.d
45+
OBJS += $(OUTPUT_DIR)/sdk/${withoutExt}.o
46+
47+
`;
48+
}
49+
50+
for (const source of projectSources) {
51+
let withoutExt = source.slice(0, source.lastIndexOf("."));
52+
53+
fileImports += `
54+
$(OUTPUT_DIR)/project/${withoutExt}.o: ${source}
55+
@$(POSIX_TOOL_PATH)echo 'Building ${source}'
56+
@$(POSIX_TOOL_PATH)mkdir -p $(@D)
57+
$(ECHO)$(CC) $(CFLAGS) -c -o $@ ${source}
58+
CDEPS += $(OUTPUT_DIR)/project/${withoutExt}.d
59+
OBJS += $(OUTPUT_DIR)/project/${withoutExt}.o
60+
61+
`;
62+
}
63+
64+
makefile =
65+
makefile.slice(0, prefixEnd) + fileImports + makefile.slice(suffixIndex);
66+
67+
makefile = makefile.replace(
68+
/^BASE_SDK_PATH = .*$/m,
69+
`BASE_SDK_PATH = ${path.join(process.cwd(), SDK_DIR)}`
70+
);
71+
72+
await fs.writeFile(`build/${filename}`, makefile);
73+
console.log("Makefile patched.");

0 commit comments

Comments
 (0)