Skip to content

Commit

Permalink
Drop support for MKR 1000 and MKR Vidor 4000 (#209)
Browse files Browse the repository at this point in the history
  • Loading branch information
umbynos committed Aug 17, 2023
1 parent d625838 commit 34be246
Show file tree
Hide file tree
Showing 43 changed files with 453 additions and 2,220 deletions.
4 changes: 2 additions & 2 deletions .ecrc
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"Exclude": [
"^indexes/download/testdata/module_firmware_index\\.json$",
"^indexes/download/testdata/plugin_firmware_index\\.json$",
"^indexes/download/testdata/package_index\\.json$",
"^indexes/firmwareindex/testdata/module_firmware_index\\.json$",
"^indexes/testdata/package_index\\.json$",
"^indexes/firmwareindex/testdata/plugin_firmware_index\\.json$",
"^LICENSE\\.txt$",
"^poetry\\.lock$",
"^\\.licenses/",
Expand Down
25 changes: 2 additions & 23 deletions .github/workflows/generate-index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,13 @@ jobs:
- name: Install Poetry
run: pip install poetry

- name: Install Arduino CLI
uses: arduino/setup-arduino-cli@v1

- name: Install platforms
run: |
arduino-cli core update-index -v
arduino-cli version
arduino-cli core install arduino:samd@${{ env.SAMD_V }} -v
env:
SAMD_V: 1.8.11

- name: Install dependencies
run: |
cd $GITHUB_WORKSPACE
task poetry:install-deps
- name: Generate plugin firmware index
run: poetry run ./generator.py -a $(which arduino-cli)

- name: Generate module firmware index
run: poetry run ./generator.py -a $(which arduino-cli) --no-new
run: poetry run ./generator.py

# fix `gpg: signing failed: Inappropriate ioctl for device`
# https://github.com/keybase/keybase-issues/issues/2798
Expand All @@ -68,13 +54,6 @@ jobs:
# disable gpg pass prompt
# https://stackoverflow.com/questions/49072403/suppress-the-passphrase-prompt-in-gpg-command
- name: sign the module firmware index json
run: |
gpg \
--pinentry-mode=loopback \
--passphrase "${{ secrets.PASSPHRASE }}" \
--output boards/module_firmware_index.json.sig \
--detach-sign boards/module_firmware_index.json

- name: sign the plugin firmware index json
run: |
Expand All @@ -85,7 +64,7 @@ jobs:
--detach-sign boards/plugin_firmware_index.json
- name: create the gzip
run: gzip --keep boards/module_firmware_index.json boards/plugin_firmware_index.json
run: gzip --keep boards/plugin_firmware_index.json

- name: s3 sync
run: |
Expand Down
4 changes: 2 additions & 2 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
.vs/
.ionide/

indexes/download/testdata/module_firmware_index.json
indexes/download/testdata/plugin_firmware_index.json
indexes/download/testdata/package_index.json
indexes/firmwareindex/testdata/module_firmware_index.json
indexes/firmwareindex/testdata/plugin_firmware_index.json
indexes/testdata/package_index.json

# Generated files
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Arduino Firmware Uploader

The Arduino Firmware Uploader is a tool made to update the firmware and/or add SSL certificates for any Arduino board
equipped with WINC or NINA Wi-Fi module.
equipped with ESP32-S3 or NINA Wi-Fi module.

[![Test Go status](https://github.com/arduino/arduino-fwuploader/actions/workflows/test-go-task.yml/badge.svg)](https://github.com/arduino/arduino-fwuploader/actions/workflows/test-go-task.yml)
[![Codecov](https://codecov.io/gh/arduino/arduino-fwuploader/branch/main/graph/badge.svg)](https://codecov.io/gh/arduino/arduino-fwuploader)
Expand Down
2 changes: 1 addition & 1 deletion cli/arguments/arguments.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ type Flags struct {

// AddToCommand adds the flags used to set address and fqbn to the specified Command
func (f *Flags) AddToCommand(cmd *cobra.Command) {
cmd.Flags().StringVarP(&f.Fqbn, "fqbn", "b", "", "Fully Qualified Board Name, e.g.: arduino:samd:mkr1000, arduino:mbed_nano:nanorp2040connect")
cmd.Flags().StringVarP(&f.Fqbn, "fqbn", "b", "", "Fully Qualified Board Name, e.g.: arduino:samd:mkrwifi1010, arduino:mbed_nano:nanorp2040connect")
cmd.Flags().StringVarP(&f.Address, "address", "a", "", "Upload port, e.g.: COM10, /dev/ttyACM0")
}
92 changes: 8 additions & 84 deletions cli/certificates/flash.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,13 @@ import (
"fmt"
"io"
"os"
"strings"
"time"

"github.com/arduino/arduino-fwuploader/certificates"
"github.com/arduino/arduino-fwuploader/cli/arguments"
"github.com/arduino/arduino-fwuploader/cli/common"
"github.com/arduino/arduino-fwuploader/cli/feedback"
"github.com/arduino/arduino-fwuploader/cli/globals"
"github.com/arduino/arduino-fwuploader/flasher"
"github.com/arduino/arduino-fwuploader/indexes/download"
"github.com/arduino/arduino-fwuploader/indexes/firmwareindex"
"github.com/arduino/arduino-fwuploader/plugin"
"github.com/arduino/go-paths-helper"
"github.com/sirupsen/logrus"
Expand All @@ -54,9 +50,9 @@ func NewFlashCommand() *cobra.Command {
Short: "Flashes certificates to board.",
Long: "Flashes specified certificates to board at specified address.",
Example: "" +
" " + os.Args[0] + " certificates flash --fqbn arduino:samd:mkr1000 --address COM10 --url arduino.cc:443 --file /home/me/Digicert.cer\n" +
" " + os.Args[0] + " certificates flash -b arduino:samd:mkr1000 -a COM10 -u arduino.cc:443 -u google.com:443\n" +
" " + os.Args[0] + " certificates flash -b arduino:samd:mkr1000 -a COM10 -f /home/me/VeriSign.cer -f /home/me/Digicert.cer\n",
" " + os.Args[0] + " certificates flash --fqbn arduino:samd:mkrwifi1010 --address COM10 --url arduino.cc:443 --file /home/me/Digicert.cer\n" +
" " + os.Args[0] + " certificates flash -b arduino:renesas_uno:unor4wifi -a COM10 -u arduino.cc:443 -u google.com:443\n" +
" " + os.Args[0] + " certificates flash -b arduino:samd:mkrwifi1010 -a COM10 -f /home/me/VeriSign.cer -f /home/me/Digicert.cer\n",
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
runFlash(certificateURLs, certificatePaths)
Expand All @@ -81,25 +77,19 @@ func runFlash(certificateURLs, certificatePaths []string) {
board := common.GetBoard(firmwareIndex, commonFlags.Fqbn)
uploadToolDir := common.DownloadRequiredToolsForBoard(packageIndex, board)

var res *flasher.FlashResult
var flashErr error
if !board.IsPlugin() {
res, flashErr = flashCertificates(board, uploadToolDir, certificateURLs, certificatePaths)
} else {
uploader, err := plugin.NewFWUploaderPlugin(uploadToolDir)
if err != nil {
feedback.Fatal(fmt.Sprintf("Could not open uploader plugin: %s", err), feedback.ErrGeneric)
}
res, flashErr = flashCertificatesWithPlugin(uploader, certificateURLs, certificatePaths)
uploader, err := plugin.NewFWUploaderPlugin(uploadToolDir)
if err != nil {
feedback.Fatal(fmt.Sprintf("Could not open uploader plugin: %s", err), feedback.ErrGeneric)
}

res, flashErr := flashCertificates(uploader, certificateURLs, certificatePaths)
feedback.PrintResult(res)
if flashErr != nil {
os.Exit(int(feedback.ErrGeneric))
}
}

func flashCertificatesWithPlugin(uploader *plugin.FwUploader, certificateURLs, certificatePaths []string) (*flasher.FlashResult, error) {
func flashCertificates(uploader *plugin.FwUploader, certificateURLs, certificatePaths []string) (*flasher.FlashResult, error) {
tmp, err := paths.MkTempDir("", "")
if err != nil {
return nil, err
Expand Down Expand Up @@ -161,69 +151,3 @@ func flashCertificatesWithPlugin(uploader *plugin.FwUploader, certificateURLs, c
},
}, err
}

func flashCertificates(board *firmwareindex.IndexBoard, uploadToolDir *paths.Path, certificateURLs, certificatePaths []string) (*flasher.FlashResult, error) {
loaderSketchPath, err := download.DownloadSketch(board.LoaderSketch)
if err != nil {
feedback.Fatal(fmt.Sprintf("Error downloading loader sketch from %s: %s", board.LoaderSketch.URL, err), feedback.ErrGeneric)
}
logrus.Debugf("loader sketch downloaded in %s", loaderSketchPath.String())

loaderSketch := strings.ReplaceAll(loaderSketchPath.String(), loaderSketchPath.Ext(), "")
programmerOut, programmerErr, err := common.FlashSketch(board, loaderSketch, uploadToolDir, commonFlags.Address)
if err != nil {
feedback.FatalError(err, feedback.ErrGeneric)
}

// Wait a bit after flashing the loader sketch for the board to become
// available again.
logrus.Debug("sleeping for 3 sec")
time.Sleep(3 * time.Second)

// Get flasher depending on which module to use
var f flasher.Flasher
moduleName := board.Module

// This matches the baudrate used in the FirmwareUpdater.ino sketch
// https://github.com/arduino-libraries/WiFiNINA/blob/master/examples/Tools/FirmwareUpdater/FirmwareUpdater.ino
const baudRate = 1000000
switch moduleName {
case "NINA":
// we use address and not bootloaderPort because the board should not be in bootloader mode
f, err = flasher.NewNinaFlasher(commonFlags.Address, baudRate, 30)
case "WINC1500":
f, err = flasher.NewWincFlasher(commonFlags.Address, baudRate, 30)
default:
err = fmt.Errorf("unknown module: %s", moduleName)
}
if err != nil {
feedback.Fatal(fmt.Sprintf("Error during certificates flashing: %s", err), feedback.ErrGeneric)
}
defer f.Close()

// now flash the certificate
certFileList := paths.NewPathList(certificatePaths...)
flasherOut := new(bytes.Buffer)
flasherErr := new(bytes.Buffer)
if feedback.GetFormat() == feedback.JSON {
err = f.FlashCertificates(&certFileList, certificateURLs, flasherOut)
if err != nil {
flasherErr.Write([]byte(fmt.Sprintf("Error during certificates flashing: %s", err)))
}
} else {
err = f.FlashCertificates(&certFileList, certificateURLs, io.MultiWriter(flasherOut, os.Stdout))
if err != nil {
os.Stderr.Write([]byte(fmt.Sprintf("Error during certificates flashing: %s", err)))
}
}
return &flasher.FlashResult{
Programmer: &flasher.ExecOutput{
Stdout: programmerOut.String(),
Stderr: programmerErr.String(),
},
Flasher: &flasher.ExecOutput{
Stdout: flasherOut.String(),
Stderr: flasherErr.String(),
},
}, err
}
76 changes: 3 additions & 73 deletions cli/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,15 @@
package common

import (
"bytes"
"fmt"
"os"
"path/filepath"
"strings"

"github.com/arduino/arduino-cli/arduino/cores/packagemanager"
"github.com/arduino/arduino-cli/arduino/serialutils"
"github.com/arduino/arduino-fwuploader/cli/feedback"
"github.com/arduino/arduino-fwuploader/cli/globals"
"github.com/arduino/arduino-fwuploader/indexes"
"github.com/arduino/arduino-fwuploader/indexes/download"
"github.com/arduino/arduino-fwuploader/indexes/firmwareindex"
programmer "github.com/arduino/arduino-fwuploader/programmers"
"github.com/arduino/go-paths-helper"
"github.com/arduino/go-properties-orderedmap"
"github.com/sirupsen/logrus"
)

Expand All @@ -59,24 +52,19 @@ func InitIndexes() (*packagemanager.PackageManager, *firmwareindex.Index) {
}

// Load main firmware index and optional additional indexes
firmwareIndex, err := indexes.GetFirmwareIndex(globals.ModuleFirmwareIndexGZURL, true)
pluginFirmwareIndex, err := indexes.GetFirmwareIndex(globals.PluginFirmwareIndexGZURL, true)
if err != nil {
feedback.Fatal(fmt.Sprintf("Can't load firmware index: %s", err), feedback.ErrGeneric)
}
if pluginIndex, err := indexes.GetFirmwareIndex(globals.PluginFirmwareIndexGZURL, true); err != nil {
feedback.Fatal(fmt.Sprintf("Can't load (plugin) firmware index: %s", err), feedback.ErrGeneric)
} else {
firmwareIndex.MergeWith(pluginIndex)
}
for _, additionalURL := range AdditionalFirmwareIndexURLs {
additionalIndex, err := indexes.GetFirmwareIndex(additionalURL, false)
if err != nil {
feedback.Fatal(fmt.Sprintf("Can't load firmware index: %s", err), feedback.ErrGeneric)
}
firmwareIndex.MergeWith(additionalIndex)
pluginFirmwareIndex.MergeWith(additionalIndex)
}

return pmbuilder.Build(), firmwareIndex
return pmbuilder.Build(), pluginFirmwareIndex
}

// CheckFlags runs a basic check, errors if the flags are not defined
Expand Down Expand Up @@ -105,11 +93,6 @@ func GetBoard(firmwareIndex *firmwareindex.Index, fqbn string) *firmwareindex.In
// DownloadRequiredToolsForBoard is an helper function that downloads the correct tool to flash a board,
// it returns the path of the downloaded tool
func DownloadRequiredToolsForBoard(pm *packagemanager.PackageManager, board *firmwareindex.IndexBoard) *paths.Path {
if !board.IsPlugin() {
// Just download the upload tool for integrated uploaders
return downloadTool(pm, board.Uploader)
}

// Download the plugin
toolDir := downloadTool(pm, board.UploaderPlugin)

Expand All @@ -133,56 +116,3 @@ func downloadTool(pm *packagemanager.PackageManager, tool string) *paths.Path {
logrus.Debugf("upload tool downloaded in %s", toolDir.String())
return toolDir
}

// FlashSketch is the business logic that handles the flashing procedure,
// it returns using a buffer the stdout and the stderr of the programmer
func FlashSketch(board *firmwareindex.IndexBoard, sketch string, uploadToolDir *paths.Path, address string) (programmerOut, programmerErr *bytes.Buffer, err error) {
bootloaderPort, err := GetNewAddress(board, address)
if err != nil {
return nil, nil, err
}

uploaderCommand := board.GetUploaderCommand()
uploaderCommand = strings.ReplaceAll(uploaderCommand, "{tool_dir}", filepath.FromSlash(uploadToolDir.String()))
uploaderCommand = strings.ReplaceAll(uploaderCommand, "{serial.port.file}", bootloaderPort)
uploaderCommand = strings.ReplaceAll(uploaderCommand, "{loader.sketch}", sketch) // we leave that name here because it's only a template,

logrus.Debugf("uploading with command: %s", uploaderCommand)
commandLine, err := properties.SplitQuotedString(uploaderCommand, "\"", false)
if err != nil {
feedback.Fatal(fmt.Sprintf(`Error splitting command line "%s": %s`, uploaderCommand, err), feedback.ErrGeneric)
}

// Flash the actual sketch
programmerOut = new(bytes.Buffer)
programmerErr = new(bytes.Buffer)
if feedback.GetFormat() == feedback.JSON {
err = programmer.Flash(commandLine, programmerOut, programmerErr)
} else {
err = programmer.Flash(commandLine, os.Stdout, os.Stderr)
}
if err != nil {
return nil, nil, fmt.Errorf("error during sketch flashing: %s", err)
}
return programmerOut, programmerErr, err
}

// GetNewAddress is a function used to reset a board and put it in bootloader mode
// it could happen that the board is assigned to a different serial port, after the reset,
// this fuction handles also this possibility
func GetNewAddress(board *firmwareindex.IndexBoard, oldAddress string) (string, error) {
// Check if board needs a 1200bps touch for upload
bootloaderPort := oldAddress
if board.UploadTouch {
logrus.Info("Putting board into bootloader mode")
newUploadPort, err := serialutils.Reset(oldAddress, board.UploadWait, nil, false)
if err != nil {
return "", fmt.Errorf("error during sketch flashing: missing board address. %s", err)
}
if newUploadPort != "" {
logrus.Infof("Found port to upload: %s", newUploadPort)
bootloaderPort = newUploadPort
}
}
return bootloaderPort, nil
}

0 comments on commit 34be246

Please sign in to comment.