clean up makefile
- rename target sd -> flash-sd, mbr -> flash-mbr, dfu-flash -> flash-dfu - update readme - clean up python script, add multiprocess build
This commit is contained in:
parent
597dc6f0a9
commit
6c0bb9d8ec
5 changed files with 132 additions and 235 deletions
96
Makefile
96
Makefile
|
|
@ -7,6 +7,7 @@
|
|||
# - SD_HEX : to bootloader hex binary
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# local customization
|
||||
-include Makefile.user
|
||||
|
||||
SDK_PATH = lib/sdk/components
|
||||
|
|
@ -37,7 +38,7 @@ OUT_NAME = $(BOARD)_bootloader-$(GIT_VERSION)
|
|||
MERGED_FILE = $(OUT_NAME)_$(SD_NAME)_$(SD_VERSION)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Tool configure
|
||||
# Tool Configure
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Toolchain commands
|
||||
|
|
@ -208,39 +209,46 @@ ASM_SRC = $(NRFX_PATH)/mdk/gcc_startup_$(MCU_SUB_VARIANT).S
|
|||
#------------------------------------------------------------------------------
|
||||
|
||||
# src
|
||||
IPATH += src
|
||||
IPATH += src/boards
|
||||
IPATH += src/boards/$(BOARD)
|
||||
IPATH += src/cmsis/include
|
||||
IPATH += src/usb
|
||||
IPATH += $(TUSB_PATH)
|
||||
IPATH += \
|
||||
src \
|
||||
src/boards \
|
||||
src/boards/$(BOARD) \
|
||||
src/cmsis/include \
|
||||
src/usb \
|
||||
$(TUSB_PATH)
|
||||
|
||||
# nrfx
|
||||
IPATH += $(NRFX_PATH)
|
||||
IPATH += $(NRFX_PATH)/mdk
|
||||
IPATH += $(NRFX_PATH)/hal
|
||||
IPATH += $(NRFX_PATH)/drivers/include
|
||||
IPATH += $(NRFX_PATH)/drivers/src
|
||||
IPATH += \
|
||||
$(NRFX_PATH) \
|
||||
$(NRFX_PATH)/mdk \
|
||||
$(NRFX_PATH)/hal \
|
||||
$(NRFX_PATH)/drivers/include \
|
||||
$(NRFX_PATH)/drivers/src
|
||||
|
||||
IPATH += $(SDK11_PATH)/libraries/bootloader_dfu/hci_transport
|
||||
IPATH += $(SDK11_PATH)/libraries/bootloader_dfu
|
||||
IPATH += $(SDK11_PATH)/drivers_nrf/pstorage
|
||||
IPATH += $(SDK11_PATH)/ble/common
|
||||
IPATH += $(SDK11_PATH)/ble/ble_services/ble_dfu
|
||||
IPATH += $(SDK11_PATH)/ble/ble_services/ble_dis
|
||||
# sdk11 for cdc/ble dfu
|
||||
IPATH += \
|
||||
$(SDK11_PATH)/libraries/bootloader_dfu/hci_transport \
|
||||
$(SDK11_PATH)/libraries/bootloader_dfu \
|
||||
$(SDK11_PATH)/drivers_nrf/pstorage \
|
||||
$(SDK11_PATH)/ble/common \
|
||||
$(SDK11_PATH)/ble/ble_services/ble_dfu \
|
||||
$(SDK11_PATH)/ble/ble_services/ble_dis
|
||||
|
||||
IPATH += $(SDK_PATH)/libraries/timer
|
||||
IPATH += $(SDK_PATH)/libraries/scheduler
|
||||
IPATH += $(SDK_PATH)/libraries/crc16
|
||||
IPATH += $(SDK_PATH)/libraries/util
|
||||
IPATH += $(SDK_PATH)/libraries/hci/config
|
||||
IPATH += $(SDK_PATH)/libraries/uart
|
||||
IPATH += $(SDK_PATH)/libraries/hci
|
||||
IPATH += $(SDK_PATH)/drivers_nrf/delay
|
||||
# later sdk with updated drivers
|
||||
IPATH += \
|
||||
$(SDK_PATH)/libraries/timer \
|
||||
$(SDK_PATH)/libraries/scheduler \
|
||||
$(SDK_PATH)/libraries/crc16 \
|
||||
$(SDK_PATH)/libraries/util \
|
||||
$(SDK_PATH)/libraries/hci/config \
|
||||
$(SDK_PATH)/libraries/uart \
|
||||
$(SDK_PATH)/libraries/hci \
|
||||
$(SDK_PATH)/drivers_nrf/delay
|
||||
|
||||
# Softdevice
|
||||
IPATH += $(SD_PATH)/$(SD_FILENAME)_API/include
|
||||
IPATH += $(SD_PATH)/$(SD_FILENAME)_API/include/nrf52
|
||||
# SoftDevice
|
||||
IPATH += \
|
||||
$(SD_PATH)/$(SD_FILENAME)_API/include \
|
||||
$(SD_PATH)/$(SD_FILENAME)_API/include/nrf52
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Compiler Flags
|
||||
|
|
@ -278,9 +286,6 @@ CFLAGS += \
|
|||
# Suppress warning caused by SDK
|
||||
CFLAGS += -Wno-unused-parameter -Wno-expansion-to-defined
|
||||
|
||||
# TinyUSB tusb_hal_nrf_power_event
|
||||
CFLAGS += -Wno-cast-function-type
|
||||
|
||||
# Nordic Softdevice SDK header files contains inline assembler that has
|
||||
# broken constraints. As a result the IPA-modref pass, introduced in gcc-11,
|
||||
# is able to "prove" that arguments to wrapper functions generated with
|
||||
|
|
@ -332,6 +337,7 @@ LIBS += -lm -lc
|
|||
#------------------------------------------------------------------------------
|
||||
# Assembler flags
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
ASFLAGS += $(CFLAGS)
|
||||
|
||||
#function for removing duplicates in a list
|
||||
|
|
@ -356,7 +362,7 @@ INC_PATHS = $(addprefix -I,$(IPATH))
|
|||
# BUILD TARGETS
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
.PHONY: all clean flash dfu-flash sd gdbflash gdb
|
||||
.PHONY: all clean flash dfu-flash flash-dfu flash-sd flash-mbr gdbflash gdb
|
||||
|
||||
# default target to build
|
||||
all: $(BUILD)/$(OUT_NAME).out $(BUILD)/$(OUT_NAME)_nosd.hex $(BUILD)/update-$(OUT_NAME)_nosd.uf2 $(BUILD)/$(MERGED_FILE).hex $(BUILD)/$(MERGED_FILE).zip
|
||||
|
|
@ -431,7 +437,9 @@ copy-artifact: $(BIN)
|
|||
@$(CP) $(BUILD)/$(MERGED_FILE).hex $(BIN)
|
||||
@$(CP) $(BUILD)/$(MERGED_FILE).zip $(BIN)
|
||||
|
||||
#------------------- Flash target -------------------
|
||||
#--------------------------------------
|
||||
# Flash Target
|
||||
#--------------------------------------
|
||||
|
||||
check_defined = \
|
||||
$(strip $(foreach 1,$1, \
|
||||
|
|
@ -440,29 +448,29 @@ __check_defined = \
|
|||
$(if $(value $1),, \
|
||||
$(error Undefined make flag: $1$(if $2, ($2))))
|
||||
|
||||
# erase chip
|
||||
erase:
|
||||
@echo Erasing flash
|
||||
$(call FLASH_ERASE_CMD)
|
||||
|
||||
# Flash the compiled
|
||||
flash: $(BUILD)/$(OUT_NAME)_nosd.hex
|
||||
@echo Flashing: $(notdir $<)
|
||||
$(call FLASH_CMD,$<)
|
||||
|
||||
erase:
|
||||
@echo Erasing flash
|
||||
$(call FLASH_ERASE_CMD)
|
||||
|
||||
# flash SD only
|
||||
sd:
|
||||
flash-sd:
|
||||
@echo Flashing: $(SD_HEX)
|
||||
$(call FLASH_NOUICR_CMD,$(SD_HEX))
|
||||
|
||||
# flash MBR only
|
||||
mbr:
|
||||
flash-mbr:
|
||||
@echo Flashing: $(MBR_HEX)
|
||||
$(call FLASH_NOUICR_CMD,$(MBR_HEX))
|
||||
|
||||
#------------------- Flash with NRFUTIL via DFU -------------------
|
||||
|
||||
# dfu using CDC interface
|
||||
dfu-flash: $(BUILD)/$(MERGED_FILE).zip
|
||||
# dfu with adafruit-nrfutil using CDC interface
|
||||
dfu-flash: flash-dfu
|
||||
flash-dfu: $(BUILD)/$(MERGED_FILE).zip
|
||||
@:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0)
|
||||
$(NRFUTIL) --verbose dfu serial --package $< -p $(SERIAL) -b 115200 --singlebank --touch 1200
|
||||
|
||||
|
|
|
|||
70
README.md
70
README.md
|
|
@ -121,45 +121,18 @@ both bootloader and the Nordic SoftDevice, you can freely upgrade/downgrade to a
|
|||
You should only continue if you are looking to develop bootloader for your own.
|
||||
You must have have a J-Link available to "unbrick" your device.
|
||||
|
||||
Prerequisites
|
||||
### Prerequisites
|
||||
|
||||
- ARM GCC
|
||||
|
||||
To install for macos
|
||||
|
||||
```bash
|
||||
brew tap ArmMbed/homebrew-formulae
|
||||
brew install arm-none-eabi-gcc
|
||||
brew link --overwrite arm-none-eabi-gcc # if a prior version was present
|
||||
```
|
||||
|
||||
- Nordic's [nRF5x Command Line Tools](https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Command-Line-Tools)
|
||||
- [Python IntelHex](https://pypi.org/project/IntelHex/)
|
||||
|
||||
To build:
|
||||
### Build:
|
||||
|
||||
```
|
||||
make BOARD=feather_nrf52840_express all
|
||||
```
|
||||
|
||||
To flash the bootloader with JLink:
|
||||
|
||||
```
|
||||
make BOARD=feather_nrf52840_express flash
|
||||
```
|
||||
|
||||
To upgrade the bootloader using DFU Serial via port /dev/ttyACM0
|
||||
|
||||
```
|
||||
make BOARD=feather_nrf52840_express SERIAL=/dev/ttyACM0 dfu-flash
|
||||
```
|
||||
|
||||
To flash SoftDevice (and chip erase):
|
||||
|
||||
```
|
||||
make BOARD=feather_nrf52840_express sd
|
||||
```
|
||||
|
||||
For the list of supported boards, run `make` without `BOARD=` :
|
||||
|
||||
```
|
||||
|
|
@ -169,9 +142,41 @@ Supported boards are: feather_nrf52840_express feather_nrf52840_express pca10056
|
|||
Makefile:90: *** BOARD not defined. Stop
|
||||
```
|
||||
|
||||
### Flash
|
||||
|
||||
To flash the bootloader (without softdevice/mbr) using JLink:
|
||||
|
||||
```
|
||||
make BOARD=feather_nrf52840_express flash
|
||||
```
|
||||
|
||||
If you are using pyocd as debugger, add `FLASHER=pyocd` to make command:
|
||||
|
||||
```
|
||||
make BOARD=feather_nrf52840_express FLASHER=pyocd flash
|
||||
```
|
||||
|
||||
To upgrade the bootloader using DFU Serial via port /dev/ttyACM0
|
||||
|
||||
```
|
||||
make BOARD=feather_nrf52840_express SERIAL=/dev/ttyACM0 flash-dfu
|
||||
```
|
||||
|
||||
To flash SoftDevice (will also erase chip):
|
||||
|
||||
```
|
||||
make BOARD=feather_nrf52840_express flash-sd
|
||||
```
|
||||
|
||||
To flash MBR only
|
||||
|
||||
```
|
||||
make BOARD=feather_nrf52840_express flash-mbr
|
||||
```
|
||||
|
||||
### Common makefile problems
|
||||
|
||||
#### 1. `arm-none-eabi-gcc`: No such file or directory
|
||||
#### `arm-none-eabi-gcc`: No such file or directory
|
||||
|
||||
If you get the following error ...
|
||||
|
||||
|
|
@ -190,7 +195,7 @@ $ make CROSS_COMPILE=/opt/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi- B
|
|||
|
||||
For other compile errors, check the gcc version with `arm-none-eabi-gcc --version` to insure it is at least 9.x.
|
||||
|
||||
#### 2. `ModuleNotFoundError: No module named 'intelhex'`
|
||||
#### `ModuleNotFoundError: No module named 'intelhex'`
|
||||
|
||||
Install python-intelhex with
|
||||
|
||||
|
|
@ -198,8 +203,7 @@ Install python-intelhex with
|
|||
pip install intelhex
|
||||
```
|
||||
|
||||
|
||||
#### 3. `make: nrfjprog: No such file or directory`
|
||||
#### `make: nrfjprog: No such file or directory`
|
||||
|
||||
Make sure that `nrfjprog` is available from the command-line. This binary is
|
||||
part of Nordic's nRF5x Command Line Tools.
|
||||
|
|
|
|||
|
|
@ -1,23 +1,49 @@
|
|||
import os
|
||||
import shutil
|
||||
import glob
|
||||
import sys
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
subprocess.run("rm -rf _build/", shell=True)
|
||||
subprocess.run("rm -rf bin/", shell=True)
|
||||
from multiprocessing import Pool
|
||||
|
||||
SUCCEEDED = "\033[32msucceeded\033[0m"
|
||||
FAILED = "\033[31mfailed\033[0m"
|
||||
|
||||
success_count = 0
|
||||
fail_count = 0
|
||||
exit_status = 0
|
||||
|
||||
build_format = '| {:32} | {:18} | {:5} | {:6} | {:6} |'
|
||||
build_separator = '-' * 74
|
||||
|
||||
|
||||
def build_board(board):
|
||||
start_time = time.monotonic()
|
||||
make_result = subprocess.run("make -j BOARD={} all".format(board), shell=True, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
build_duration = time.monotonic() - start_time
|
||||
|
||||
flash_size = "-"
|
||||
sram_size = "-"
|
||||
succeeded = 0
|
||||
|
||||
if make_result.returncode == 0:
|
||||
succeeded = 1
|
||||
out_file = glob.glob('_build/build-{}/*.out'.format(board))[0]
|
||||
size_output = subprocess.run('size {}'.format(out_file), shell=True, stdout=subprocess.PIPE).stdout.decode(
|
||||
"utf-8")
|
||||
size_list = size_output.split('\n')[1].split('\t')
|
||||
flash_size = int(size_list[0])
|
||||
sram_size = int(size_list[1]) + int(size_list[2])
|
||||
|
||||
print(build_format.format(board, SUCCEEDED if succeeded else FAILED, "{:.2f}s".format(build_duration), flash_size,
|
||||
sram_size))
|
||||
|
||||
if make_result.returncode != 0:
|
||||
print(make_result.stdout.decode("utf-8"))
|
||||
|
||||
return succeeded
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# remove build folder first
|
||||
subprocess.run("rm -rf _build/", shell=True)
|
||||
|
||||
# All supported boards
|
||||
all_boards = []
|
||||
for entry in os.scandir("src/boards"):
|
||||
|
|
@ -25,54 +51,23 @@ for entry in os.scandir("src/boards"):
|
|||
all_boards.append(entry.name)
|
||||
all_boards.sort()
|
||||
|
||||
#sha, version = build_info.get_version_info()
|
||||
|
||||
total_time = time.monotonic()
|
||||
|
||||
print(build_separator)
|
||||
print(build_format.format('Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM'))
|
||||
print(build_separator)
|
||||
|
||||
for board in all_boards:
|
||||
bin_directory = "bin/{}/".format(board)
|
||||
os.makedirs(bin_directory, exist_ok=True)
|
||||
success_count = 0
|
||||
total_time = time.monotonic()
|
||||
|
||||
start_time = time.monotonic()
|
||||
make_result = subprocess.run("make -j 4 BOARD={} all".format(board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
build_duration = time.monotonic() - start_time
|
||||
with Pool(processes=os.cpu_count()) as pool:
|
||||
success_count = sum(pool.map(build_board, all_boards))
|
||||
|
||||
flash_size = "-"
|
||||
sram_size = "-"
|
||||
|
||||
if make_result.returncode == 0:
|
||||
success = SUCCEEDED
|
||||
success_count += 1
|
||||
|
||||
out_file = glob.glob('_build/build-{}/*.out'.format(board))[0]
|
||||
size_output = subprocess.run('size {}'.format(out_file), shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8")
|
||||
size_list = size_output.split('\n')[1].split('\t')
|
||||
flash_size = int(size_list[0])
|
||||
sram_size = int(size_list[1]) + int(size_list[2])
|
||||
else:
|
||||
exit_status = make_result.returncode
|
||||
success = FAILED
|
||||
fail_count += 1
|
||||
|
||||
for entry in os.scandir("_build/build-{}".format(board)):
|
||||
for extension in ["zip", "hex", "uf2"]:
|
||||
if entry.name.endswith(extension):
|
||||
if ("nosd" in entry.name) or ("s140" in entry.name) or ("s132" in entry.name):
|
||||
shutil.copy(entry.path, bin_directory)
|
||||
|
||||
print(build_format.format(board, success, "{:.2f}s".format(build_duration), flash_size, sram_size))
|
||||
|
||||
if make_result.returncode != 0:
|
||||
print(make_result.stdout.decode("utf-8"))
|
||||
total_time = time.monotonic() - total_time
|
||||
fail_count = len(all_boards) - success_count
|
||||
|
||||
# Build Summary
|
||||
total_time = time.monotonic() - total_time
|
||||
print(build_separator)
|
||||
print("Build Sumamary: {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, total_time))
|
||||
print(
|
||||
"Build Summary: {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, total_time))
|
||||
print(build_separator)
|
||||
|
||||
sys.exit(exit_status)
|
||||
sys.exit(fail_count)
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
"""
|
||||
`adafruit_adabot`
|
||||
====================================================
|
||||
|
||||
TODO(description)
|
||||
|
||||
* Author(s): Scott Shawcroft
|
||||
"""
|
||||
import os
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
def _fix_url(url):
|
||||
if url.startswith("/"):
|
||||
url = "https://api.github.com" + url
|
||||
return url
|
||||
|
||||
def _fix_kwargs(kwargs):
|
||||
api_version = "application/vnd.github.scarlet-witch-preview+json;application/vnd.github.hellcat-preview+json"
|
||||
if "headers" in kwargs:
|
||||
if "Accept" in kwargs["headers"]:
|
||||
kwargs["headers"]["Accept"] += ";" + api_version
|
||||
else:
|
||||
kwargs["headers"]["Accept"] = api_version
|
||||
else:
|
||||
kwargs["headers"] = {"Accept": "application/vnd.github.hellcat-preview+json"}
|
||||
if "ADABOT_GITHUB_ACCESS_TOKEN" in os.environ and "auth" not in kwargs:
|
||||
access_token = os.environ["ADABOT_GITHUB_ACCESS_TOKEN"]
|
||||
if "params" in kwargs:
|
||||
kwargs["params"]["access_token"] = access_token
|
||||
else:
|
||||
kwargs["params"] = {"access_token": access_token}
|
||||
if "timeout" not in kwargs:
|
||||
kwargs["timeout"] = 30
|
||||
return kwargs
|
||||
|
||||
def get(url, **kwargs):
|
||||
response = requests.get(_fix_url(url), **_fix_kwargs(kwargs))
|
||||
remaining = int(response.headers["X-RateLimit-Remaining"])
|
||||
if remaining % 100 == 0:
|
||||
print(remaining, "requests remaining this hour")
|
||||
return response
|
||||
|
||||
def post(url, **kwargs):
|
||||
return requests.post(_fix_url(url), **_fix_kwargs(kwargs))
|
||||
|
||||
def put(url, **kwargs):
|
||||
return requests.put(_fix_url(url), **_fix_kwargs(kwargs))
|
||||
|
||||
def patch(url, **kwargs):
|
||||
return requests.patch(_fix_url(url), **_fix_kwargs(kwargs))
|
||||
|
||||
def delete(url, **kwargs):
|
||||
return requests.delete(_fix_url(url), **_fix_kwargs(kwargs))
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
import uritemplate
|
||||
import glob
|
||||
|
||||
sys.path.append("adabot")
|
||||
import github_requests as github
|
||||
|
||||
exit_status = 0
|
||||
|
||||
filepaths = list(glob.iglob('../bin/*/*', recursive=True))
|
||||
filepaths.sort()
|
||||
|
||||
for full_filename in filepaths:
|
||||
filename = os.path.basename(full_filename)
|
||||
url_vars = {}
|
||||
url_vars["name"] = filename
|
||||
url = uritemplate.expand(os.environ["UPLOAD_URL"], url_vars)
|
||||
headers = {"content-type": "application/octet-stream"}
|
||||
print(url)
|
||||
with open(full_filename, "rb") as f:
|
||||
response = github.post(url, data=f, headers=headers)
|
||||
if not response.ok:
|
||||
if response.status_code == 422 and response.json().get("errors", [{"code":""}])[0]["code"] == "already_exists":
|
||||
print("File already uploaded. Skipping.")
|
||||
continue
|
||||
print("Upload of {} failed with {}.".format(filename, response.status_code))
|
||||
print(response.text)
|
||||
sys.exit(response.status_code)
|
||||
|
||||
sys.exit(exit_status)
|
||||
Loading…
Reference in a new issue