Switch panda to scons builder (#635)
* add scons builder * cleanup 1 * remove building from python code * add pedal build * fixup flags * add EON flag * change github actions to scons * fixup automated tests * move flashing scripts * fix indent * remove version.mk * fix not in git * fix linker script filename * untested pedal flashing scripts * add release option * better asserts * swap condition * enable usb and fix flash script * usb flash is not supported * use button to enable dfu mode * no usb because misra * remove sleepmaster
parent
d572c012cb
commit
ad9ecefe65
|
@ -36,14 +36,10 @@ jobs:
|
||||||
run: eval "$BUILD"
|
run: eval "$BUILD"
|
||||||
- name: Test python package installer
|
- name: Test python package installer
|
||||||
run: $RUN "cd /tmp/openpilot/panda && python setup.py install"
|
run: $RUN "cd /tmp/openpilot/panda && python setup.py install"
|
||||||
- name: Build panda STM image
|
- name: Build panda STM image and bootstub
|
||||||
run: $RUN "cd /tmp/openpilot/panda/board && make bin"
|
run: $RUN "cd /tmp/openpilot/panda && scons"
|
||||||
- name: Build panda STM bootstub image
|
- name: Build pedal STM image and bootstub
|
||||||
run: $RUN "cd /tmp/openpilot/panda/board && make obj/bootstub.panda.bin"
|
run: $RUN "cd /tmp/openpilot/panda && PEDAL=1 scons"
|
||||||
- name: Build pedal STM image
|
|
||||||
run: $RUN "cd /tmp/openpilot/panda/board/pedal && make obj/comma.bin"
|
|
||||||
- name: Build pedal STM bootstub image
|
|
||||||
run: $RUN "cd /tmp/openpilot/panda/board/pedal && make obj/bootstub.bin"
|
|
||||||
|
|
||||||
safety:
|
safety:
|
||||||
name: safety
|
name: safety
|
||||||
|
|
|
@ -16,3 +16,4 @@ examples/output.csv
|
||||||
.vscode*
|
.vscode*
|
||||||
nosetests.xml
|
nosetests.xml
|
||||||
.mypy_cache/
|
.mypy_cache/
|
||||||
|
.sconsign.dblite
|
||||||
|
|
|
@ -25,7 +25,7 @@ pipeline {
|
||||||
lock(resource: "Pandas", inversePrecedence: true, quantity: 1){
|
lock(resource: "Pandas", inversePrecedence: true, quantity: 1){
|
||||||
timeout(time: 60, unit: 'MINUTES') {
|
timeout(time: 60, unit: 'MINUTES') {
|
||||||
script {
|
script {
|
||||||
sh "docker run --name ${env.DOCKER_NAME} --privileged --volume /dev/bus/usb:/dev/bus/usb --volume /var/run/dbus:/var/run/dbus --net host ${env.DOCKER_IMAGE_TAG} bash -c 'cd /tmp/panda; ./run_automated_tests.sh'"
|
sh "docker run --name ${env.DOCKER_NAME} --privileged --volume /dev/bus/usb:/dev/bus/usb --volume /var/run/dbus:/var/run/dbus --net host ${env.DOCKER_IMAGE_TAG} bash -c 'cd /tmp/panda; scons; ./run_automated_tests.sh'"
|
||||||
sh "docker cp ${env.DOCKER_NAME}:/tmp/panda/nosetests.xml test_results_dev.xml"
|
sh "docker cp ${env.DOCKER_NAME}:/tmp/panda/nosetests.xml test_results_dev.xml"
|
||||||
sh "docker rm ${env.DOCKER_NAME}"
|
sh "docker rm ${env.DOCKER_NAME}"
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ pipeline {
|
||||||
lock(resource: "Pandas", inversePrecedence: true, quantity: 1){
|
lock(resource: "Pandas", inversePrecedence: true, quantity: 1){
|
||||||
timeout(time: 60, unit: 'MINUTES') {
|
timeout(time: 60, unit: 'MINUTES') {
|
||||||
script {
|
script {
|
||||||
sh "docker run --name ${env.DOCKER_NAME} --privileged --volume /dev/bus/usb:/dev/bus/usb --volume /var/run/dbus:/var/run/dbus --net host ${env.DOCKER_IMAGE_TAG} bash -c 'touch /EON; cd /tmp/panda; ./run_automated_tests.sh'"
|
sh "docker run --name ${env.DOCKER_NAME} --privileged --volume /dev/bus/usb:/dev/bus/usb --volume /var/run/dbus:/var/run/dbus --net host ${env.DOCKER_IMAGE_TAG} bash -c 'touch /EON; cd /tmp/panda; scons; ./run_automated_tests.sh'"
|
||||||
sh "docker cp ${env.DOCKER_NAME}:/tmp/panda/nosetests.xml test_results_eon.xml"
|
sh "docker cp ${env.DOCKER_NAME}:/tmp/panda/nosetests.xml test_results_eon.xml"
|
||||||
sh "docker rm ${env.DOCKER_NAME}"
|
sh "docker rm ${env.DOCKER_NAME}"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
SConscript('board/SConscript')
|
|
@ -1,3 +1,3 @@
|
||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
# pylint: skip-file
|
# pylint: skip-file
|
||||||
from .python import Panda, PandaWifiStreaming, PandaDFU, flash_release, BASEDIR, ensure_st_up_to_date, build_st, PandaSerial
|
from .python import Panda, PandaWifiStreaming, PandaDFU, flash_release, BASEDIR, ensure_st_up_to_date, PandaSerial
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
PROJ_NAME = panda
|
|
||||||
CFLAGS = -g -Wall -Wextra -Wstrict-prototypes -Werror
|
|
||||||
|
|
||||||
CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4
|
|
||||||
CFLAGS += -mhard-float -DSTM32F4 -DSTM32F413xx -mfpu=fpv4-sp-d16 -fsingle-precision-constant
|
|
||||||
STARTUP_FILE = startup_stm32f413xx
|
|
||||||
|
|
||||||
include build.mk
|
|
|
@ -0,0 +1,156 @@
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
EON = os.path.isfile('/EON')
|
||||||
|
TICI = os.path.isfile('/TICI')
|
||||||
|
PC = not (EON or TICI)
|
||||||
|
|
||||||
|
PREFIX = "arm-none-eabi-"
|
||||||
|
BUILDER = "DEV"
|
||||||
|
|
||||||
|
if os.getenv("PEDAL"):
|
||||||
|
PROJECT = "pedal"
|
||||||
|
STARTUP_FILE = "startup_stm32f205xx.s"
|
||||||
|
MAIN = "pedal/main.c"
|
||||||
|
PROJECT_FLAGS = [
|
||||||
|
"-mcpu=cortex-m3",
|
||||||
|
"-msoft-float",
|
||||||
|
"-DSTM32F2",
|
||||||
|
"-DSTM32F205xx",
|
||||||
|
"-O2",
|
||||||
|
"-DPEDAL",
|
||||||
|
]
|
||||||
|
|
||||||
|
else:
|
||||||
|
PROJECT = "panda"
|
||||||
|
STARTUP_FILE = "startup_stm32f413xx.s"
|
||||||
|
MAIN = "main.c"
|
||||||
|
PROJECT_FLAGS = [
|
||||||
|
"-mcpu=cortex-m4",
|
||||||
|
"-mhard-float",
|
||||||
|
"-DSTM32F4",
|
||||||
|
"-DSTM32F413xx",
|
||||||
|
"-mfpu=fpv4-sp-d16",
|
||||||
|
"-fsingle-precision-constant",
|
||||||
|
"-Os",
|
||||||
|
"-g",
|
||||||
|
]
|
||||||
|
|
||||||
|
if not PC:
|
||||||
|
PROJECT_FLAGS += ["-DEON"]
|
||||||
|
BUILDER = "EON"
|
||||||
|
|
||||||
|
|
||||||
|
def get_version(builder, build_type):
|
||||||
|
version_file = File('../VERSION').srcnode().abspath
|
||||||
|
version = open(version_file).read()
|
||||||
|
try:
|
||||||
|
git = subprocess.check_output(["git", "rev-parse", "--short=8", "HEAD"], encoding='utf8').strip()
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
git = "unknown"
|
||||||
|
return f"{version}-{builder}-{git}-{build_type}"
|
||||||
|
|
||||||
|
|
||||||
|
def to_c_uint32(x):
|
||||||
|
nums = []
|
||||||
|
for _ in range(0x20):
|
||||||
|
nums.append(x % (2**32))
|
||||||
|
x //= (2**32)
|
||||||
|
return "{" + 'U,'.join(map(str, nums)) + "U}"
|
||||||
|
|
||||||
|
|
||||||
|
def get_key_header(name):
|
||||||
|
from Crypto.PublicKey import RSA
|
||||||
|
|
||||||
|
public_fn = File(f'../certs/{name}.pub').srcnode().abspath
|
||||||
|
rsa = RSA.importKey(open(public_fn).read())
|
||||||
|
assert(rsa.size_in_bits() == 1024)
|
||||||
|
|
||||||
|
rr = pow(2**1024, 2, rsa.n)
|
||||||
|
n0inv = 2**32 - pow(rsa.n, -1, 2**32)
|
||||||
|
|
||||||
|
r = [
|
||||||
|
f"RSAPublicKey {name}_rsa_key = {{",
|
||||||
|
f" .len = 0x20,",
|
||||||
|
f" .n0inv = {n0inv}U,",
|
||||||
|
f" .n = {to_c_uint32(rsa.n)},",
|
||||||
|
f" .rr = {to_c_uint32(rr)},",
|
||||||
|
f" .exponent = {rsa.e},",
|
||||||
|
f"}};",
|
||||||
|
]
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
def objcopy(source, target, env, for_signature):
|
||||||
|
return '$OBJCOPY -O binary %s %s' % (source[0], target[0])
|
||||||
|
|
||||||
|
|
||||||
|
linkerscript_fn = File("stm32_flash.ld").srcnode().abspath
|
||||||
|
|
||||||
|
flags = [
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Wstrict-prototypes",
|
||||||
|
"-Werror",
|
||||||
|
"-mlittle-endian",
|
||||||
|
"-mthumb",
|
||||||
|
"-nostdlib",
|
||||||
|
"-fno-builtin",
|
||||||
|
f"-T{linkerscript_fn}",
|
||||||
|
"-std=gnu11",
|
||||||
|
] + PROJECT_FLAGS
|
||||||
|
|
||||||
|
|
||||||
|
if os.getenv("RELEASE"):
|
||||||
|
BUILD_TYPE = "RELEASE"
|
||||||
|
cert_fn = os.getenv("CERT")
|
||||||
|
assert cert_fn is not None, 'No certificate file specified. Please set CERT env variable'
|
||||||
|
assert os.path.exists(cert_fn), 'Certificate file not found. Please specify absolute path'
|
||||||
|
else:
|
||||||
|
BUILD_TYPE = "DEBUG"
|
||||||
|
cert_fn = File("../certs/debug").srcnode().abspath
|
||||||
|
flags += ["-DALLOW_DEBUG"]
|
||||||
|
|
||||||
|
includes = [
|
||||||
|
"inc",
|
||||||
|
"..",
|
||||||
|
".",
|
||||||
|
]
|
||||||
|
|
||||||
|
panda_env = Environment(
|
||||||
|
ENV=os.environ,
|
||||||
|
CC=PREFIX + 'gcc',
|
||||||
|
AS=PREFIX + 'gcc',
|
||||||
|
OBJCOPY=PREFIX + 'objcopy',
|
||||||
|
OBJDUMP=PREFIX + 'objdump',
|
||||||
|
ASCOM="$AS $ASFLAGS -o $TARGET -c $SOURCES",
|
||||||
|
CFLAGS=flags,
|
||||||
|
ASFLAGS=flags,
|
||||||
|
LINKFLAGS=flags,
|
||||||
|
CPPPATH=includes,
|
||||||
|
BUILDERS={
|
||||||
|
'Objcopy': Builder(generator=objcopy, suffix='.bin', src_suffix='.elf')
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Common autogenerated includes
|
||||||
|
version = f'const uint8_t gitversion[] = "{get_version(BUILDER, BUILD_TYPE)}";'
|
||||||
|
gitversion = panda_env.Textfile("obj/gitversion.h", [version, ""])
|
||||||
|
certs = [get_key_header(n) for n in ["debug", "release"]]
|
||||||
|
certheader = panda_env.Textfile("obj/cert.h", certs + [""])
|
||||||
|
|
||||||
|
startup = panda_env.Object(STARTUP_FILE)
|
||||||
|
|
||||||
|
# Bootstub
|
||||||
|
crypto = ["../crypto/rsa.c", "../crypto/sha.c"]
|
||||||
|
bootstub_elf = panda_env.Program(f"obj/bootstub.{PROJECT}.elf", [startup] + crypto + ["bootstub.c"])
|
||||||
|
bootstub_bin = panda_env.Objcopy(f"obj/bootstub.{PROJECT}.bin", bootstub_elf)
|
||||||
|
|
||||||
|
# Build main
|
||||||
|
main_elf = panda_env.Program(f"obj/{PROJECT}.elf", [startup, MAIN],
|
||||||
|
LINKFLAGS=["-Wl,--section-start,.isr_vector=0x8004000"] + flags)
|
||||||
|
main_bin = panda_env.Objcopy(f"obj/{PROJECT}.bin", main_elf)
|
||||||
|
|
||||||
|
# Sign main
|
||||||
|
sign_py = File("../crypto/sign.py").srcnode().abspath
|
||||||
|
panda_bin_signed = panda_env.Command(f"obj/{PROJECT}.bin.signed", main_bin, f"SETLEN=1 {sign_py} $SOURCE $TARGET {cert_fn}")
|
|
@ -1,91 +0,0 @@
|
||||||
CFLAGS += -I inc -I ../ -nostdlib -fno-builtin -std=gnu11 -Os
|
|
||||||
|
|
||||||
CFLAGS += -Tstm32_flash.ld
|
|
||||||
|
|
||||||
DFU_UTIL = "dfu-util"
|
|
||||||
|
|
||||||
PC = 0
|
|
||||||
|
|
||||||
ifeq (,$(wildcard /EON))
|
|
||||||
ifeq (,$(wildcard /TICI))
|
|
||||||
PC = 1
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq (1, $(PC))
|
|
||||||
BUILDER = DEV
|
|
||||||
else
|
|
||||||
CFLAGS += "-DEON"
|
|
||||||
BUILDER = EON
|
|
||||||
endif
|
|
||||||
|
|
||||||
#COMPILER_PATH = /home/batman/Downloads/gcc-arm-none-eabi-9-2020-q2-update/bin/
|
|
||||||
CC = $(COMPILER_PATH)arm-none-eabi-gcc
|
|
||||||
OBJCOPY = $(COMPILER_PATH)arm-none-eabi-objcopy
|
|
||||||
OBJDUMP = $(COMPILER_PATH)arm-none-eabi-objdump
|
|
||||||
|
|
||||||
ifeq ($(RELEASE),1)
|
|
||||||
CERT = ../../pandaextra/certs/release
|
|
||||||
else
|
|
||||||
# enable the debug cert
|
|
||||||
CERT = ../certs/debug
|
|
||||||
CFLAGS += "-DALLOW_DEBUG"
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
DEPDIR = generated_dependencies
|
|
||||||
$(shell mkdir -p -m 777 $(DEPDIR) >/dev/null)
|
|
||||||
DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td
|
|
||||||
POSTCOMPILE = @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $@
|
|
||||||
|
|
||||||
# this no longer pushes the bootstub
|
|
||||||
flash: obj/$(PROJ_NAME).bin
|
|
||||||
PYTHONPATH=../ python3 -c "from python import Panda; Panda().flash('obj/$(PROJ_NAME).bin')"
|
|
||||||
|
|
||||||
ota: obj/$(PROJ_NAME).bin
|
|
||||||
curl http://192.168.0.10/stupdate --upload-file $<
|
|
||||||
|
|
||||||
bin: obj/$(PROJ_NAME).bin
|
|
||||||
|
|
||||||
# this flashes everything
|
|
||||||
recover: obj/bootstub.$(PROJ_NAME).bin obj/$(PROJ_NAME).bin
|
|
||||||
-PYTHONPATH=../ python3 -c "from python import Panda; Panda().reset(enter_bootstub=True); Panda().reset(enter_bootloader=True)"
|
|
||||||
sleep 1.0
|
|
||||||
$(DFU_UTIL) -d 0483:df11 -a 0 -s 0x08004000 -D obj/$(PROJ_NAME).bin
|
|
||||||
$(DFU_UTIL) -d 0483:df11 -a 0 -s 0x08000000:leave -D obj/bootstub.$(PROJ_NAME).bin
|
|
||||||
|
|
||||||
include ../common/version.mk
|
|
||||||
|
|
||||||
obj/cert.h: ../crypto/getcertheader.py
|
|
||||||
../crypto/getcertheader.py ../certs/debug.pub ../certs/release.pub > $@
|
|
||||||
|
|
||||||
obj/%.$(PROJ_NAME).o: %.c obj/gitversion.h obj/cert.h $(DEPDIR)/%.d
|
|
||||||
$(CC) $(DEPFLAGS) $(CFLAGS) -o $@ -c $<
|
|
||||||
$(POSTCOMPILE)
|
|
||||||
|
|
||||||
obj/%.$(PROJ_NAME).o: ../crypto/%.c
|
|
||||||
$(CC) $(CFLAGS) -o $@ -c $<
|
|
||||||
|
|
||||||
obj/$(STARTUP_FILE).o: $(STARTUP_FILE).s
|
|
||||||
$(CC) $(CFLAGS) -o $@ -c $<
|
|
||||||
|
|
||||||
obj/$(PROJ_NAME).bin: obj/$(STARTUP_FILE).o obj/main.$(PROJ_NAME).o
|
|
||||||
# hack
|
|
||||||
$(CC) -Wl,--section-start,.isr_vector=0x8004000 $(CFLAGS) -o obj/$(PROJ_NAME).elf $^
|
|
||||||
$(OBJCOPY) -v -O binary obj/$(PROJ_NAME).elf obj/code.bin
|
|
||||||
SETLEN=1 ../crypto/sign.py obj/code.bin $@ $(CERT)
|
|
||||||
@BINSIZE=$$(du -b "obj/$(PROJ_NAME).bin" | cut -f 1) ; \
|
|
||||||
if [ $$BINSIZE -ge 49152 ]; then echo "ERROR obj/$(PROJ_NAME).bin is too big!"; exit 1; fi;
|
|
||||||
|
|
||||||
obj/bootstub.$(PROJ_NAME).bin: obj/$(STARTUP_FILE).o obj/bootstub.$(PROJ_NAME).o obj/sha.$(PROJ_NAME).o obj/rsa.$(PROJ_NAME).o
|
|
||||||
$(CC) $(CFLAGS) -o obj/bootstub.$(PROJ_NAME).elf $^
|
|
||||||
$(OBJCOPY) -v -O binary obj/bootstub.$(PROJ_NAME).elf $@
|
|
||||||
|
|
||||||
$(DEPDIR)/%.d: ;
|
|
||||||
.PRECIOUS: $(DEPDIR)/%.d
|
|
||||||
|
|
||||||
include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(wildcard *.c))))
|
|
||||||
|
|
||||||
clean:
|
|
||||||
@$(RM) obj/*
|
|
||||||
@rm -rf $(DEPDIR)
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
scons -u
|
||||||
|
PYTHONPATH=.. python3 -c "from python import Panda; Panda().flash('obj/panda.bin.signed')"
|
|
@ -1,67 +0,0 @@
|
||||||
# :set noet
|
|
||||||
PROJ_NAME = comma
|
|
||||||
|
|
||||||
CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes -Werror -std=gnu11 -DPEDAL
|
|
||||||
CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m3
|
|
||||||
CFLAGS += -msoft-float -DSTM32F2 -DSTM32F205xx
|
|
||||||
CFLAGS += -I ../inc -I ../ -I ../../ -nostdlib -fno-builtin
|
|
||||||
CFLAGS += -T../stm32_flash.ld
|
|
||||||
|
|
||||||
STARTUP_FILE = startup_stm32f205xx
|
|
||||||
|
|
||||||
CC = arm-none-eabi-gcc
|
|
||||||
OBJCOPY = arm-none-eabi-objcopy
|
|
||||||
OBJDUMP = arm-none-eabi-objdump
|
|
||||||
DFU_UTIL = "dfu-util"
|
|
||||||
|
|
||||||
# pedal only uses the debug cert
|
|
||||||
CERT = ../../certs/debug
|
|
||||||
CFLAGS += "-DALLOW_DEBUG"
|
|
||||||
|
|
||||||
canflash: obj/$(PROJ_NAME).bin
|
|
||||||
../../tests/pedal/enter_canloader.py $<
|
|
||||||
|
|
||||||
usbflash: obj/$(PROJ_NAME).bin
|
|
||||||
../../tests/pedal/enter_canloader.py; sleep 0.5
|
|
||||||
PYTHONPATH=../../ python -c "from python import Panda; p = [x for x in [Panda(x) for x in Panda.list()] if x.bootstub]; assert(len(p)==1); p[0].flash('obj/$(PROJ_NAME).bin', reconnect=False)"
|
|
||||||
|
|
||||||
recover: obj/bootstub.bin obj/$(PROJ_NAME).bin
|
|
||||||
../../tests/pedal/enter_canloader.py --recover; sleep 0.5
|
|
||||||
$(DFU_UTIL) -d 0483:df11 -a 0 -s 0x08004000 -D obj/$(PROJ_NAME).bin
|
|
||||||
$(DFU_UTIL) -d 0483:df11 -a 0 -s 0x08000000:leave -D obj/bootstub.bin
|
|
||||||
|
|
||||||
include ../../common/version.mk
|
|
||||||
|
|
||||||
obj/cert.h: ../../crypto/getcertheader.py
|
|
||||||
../../crypto/getcertheader.py ../../certs/debug.pub ../../certs/release.pub > $@
|
|
||||||
|
|
||||||
obj/main.o: main.c ../*.h
|
|
||||||
mkdir -p obj
|
|
||||||
$(CC) $(CFLAGS) -o $@ -c $<
|
|
||||||
|
|
||||||
obj/bootstub.o: ../bootstub.c ../*.h obj/gitversion.h obj/cert.h
|
|
||||||
mkdir -p obj
|
|
||||||
mkdir -p ../obj
|
|
||||||
cp obj/gitversion.h ../obj/gitversion.h
|
|
||||||
cp obj/cert.h ../obj/cert.h
|
|
||||||
$(CC) $(CFLAGS) -o $@ -c $<
|
|
||||||
|
|
||||||
obj/$(STARTUP_FILE).o: ../$(STARTUP_FILE).s
|
|
||||||
$(CC) $(CFLAGS) -o $@ -c $<
|
|
||||||
|
|
||||||
obj/%.o: ../../crypto/%.c
|
|
||||||
$(CC) $(CFLAGS) -o $@ -c $<
|
|
||||||
|
|
||||||
obj/$(PROJ_NAME).bin: obj/$(STARTUP_FILE).o obj/main.o
|
|
||||||
# hack
|
|
||||||
$(CC) -Wl,--section-start,.isr_vector=0x8004000 $(CFLAGS) -o obj/$(PROJ_NAME).elf $^
|
|
||||||
$(OBJCOPY) -v -O binary obj/$(PROJ_NAME).elf obj/code.bin
|
|
||||||
SETLEN=1 ../../crypto/sign.py obj/code.bin $@ $(CERT)
|
|
||||||
|
|
||||||
obj/bootstub.bin: obj/$(STARTUP_FILE).o obj/bootstub.o obj/sha.o obj/rsa.o
|
|
||||||
$(CC) $(CFLAGS) -o obj/bootstub.$(PROJ_NAME).elf $^
|
|
||||||
$(OBJCOPY) -v -O binary obj/bootstub.$(PROJ_NAME).elf $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f obj/*
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
PEDAL=1 scons -u
|
||||||
|
cd pedal
|
||||||
|
|
||||||
|
../../tests/pedal/enter_canloader.py ../obj/pedal.bin.signed
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DFU_UTIL="dfu-util"
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
PEDAL=1 scons -u
|
||||||
|
cd pedal
|
||||||
|
|
||||||
|
$DFU_UTIL -d 0483:df11 -a 0 -s 0x08004000 -D ../obj/pedal.bin.signed
|
||||||
|
$DFU_UTIL -d 0483:df11 -a 0 -s 0x08000000:leave -D ../obj/bootstub.pedal.bin
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DFU_UTIL="dfu-util"
|
||||||
|
|
||||||
|
scons -u
|
||||||
|
|
||||||
|
PYTHONPATH=.. python3 -c "from python import Panda; Panda().reset(enter_bootstub=True); Panda().reset(enter_bootloader=True)"
|
||||||
|
sleep 1
|
||||||
|
$DFU_UTIL -d 0483:df11 -a 0 -s 0x08004000 -D obj/panda.bin.signed
|
||||||
|
$DFU_UTIL -d 0483:df11 -a 0 -s 0x08000000:leave -D obj/bootstub.panda.bin
|
|
@ -1,20 +0,0 @@
|
||||||
ifeq ($(RELEASE),1)
|
|
||||||
BUILD_TYPE = "RELEASE"
|
|
||||||
else
|
|
||||||
BUILD_TYPE = "DEBUG"
|
|
||||||
endif
|
|
||||||
|
|
||||||
SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
|
|
||||||
|
|
||||||
ifneq ($(wildcard $(SELF_DIR)/../.git/HEAD),)
|
|
||||||
obj/gitversion.h: $(SELF_DIR)/../VERSION $(SELF_DIR)/../.git/HEAD $(SELF_DIR)/../.git/index
|
|
||||||
echo "const uint8_t gitversion[] = \"$(shell cat $(SELF_DIR)/../VERSION)-$(BUILDER)-$(shell git rev-parse --short=8 HEAD)-$(BUILD_TYPE)\";" > $@
|
|
||||||
else
|
|
||||||
ifneq ($(wildcard $(SELF_DIR)/../../.git/modules/panda/HEAD),)
|
|
||||||
obj/gitversion.h: $(SELF_DIR)/../VERSION $(SELF_DIR)/../../.git/modules/panda/HEAD $(SELF_DIR)/../../.git/modules/panda/index
|
|
||||||
echo "const uint8_t gitversion[] = \"$(shell cat $(SELF_DIR)/../VERSION)-$(BUILDER)-$(shell git rev-parse --short=8 HEAD)-$(BUILD_TYPE)\";" > $@
|
|
||||||
else
|
|
||||||
obj/gitversion.h: $(SELF_DIR)/../VERSION
|
|
||||||
echo "const uint8_t gitversion[] = \"$(shell cat $(SELF_DIR)/../VERSION)-$(BUILDER)-unknown-$(BUILD_TYPE)\";" > $@
|
|
||||||
endif
|
|
||||||
endif
|
|
|
@ -1,43 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
import sys
|
|
||||||
from Crypto.PublicKey import RSA
|
|
||||||
|
|
||||||
def egcd(a, b):
|
|
||||||
if a == 0:
|
|
||||||
return (b, 0, 1)
|
|
||||||
else:
|
|
||||||
g, y, x = egcd(b % a, a)
|
|
||||||
return (g, x - (b // a) * y, y)
|
|
||||||
|
|
||||||
def modinv(a, m):
|
|
||||||
g, x, _ = egcd(a, m)
|
|
||||||
if g != 1:
|
|
||||||
raise Exception('modular inverse does not exist')
|
|
||||||
else:
|
|
||||||
return x % m
|
|
||||||
|
|
||||||
def to_c_string(x):
|
|
||||||
mod = (hex(x)[2:-1].rjust(0x100, '0'))
|
|
||||||
hh = ''.join('\\x' + mod[i:i + 2] for i in range(0, 0x100, 2))
|
|
||||||
return hh
|
|
||||||
|
|
||||||
def to_c_uint32(x):
|
|
||||||
nums = []
|
|
||||||
for _ in range(0x20):
|
|
||||||
nums.append(x % (2**32))
|
|
||||||
x //= (2**32)
|
|
||||||
return "{" + 'U,'.join(map(str, nums)) + "U}"
|
|
||||||
|
|
||||||
for fn in sys.argv[1:]:
|
|
||||||
rsa = RSA.importKey(open(fn).read())
|
|
||||||
rr = pow(2**1024, 2, rsa.n)
|
|
||||||
n0inv = 2**32 - modinv(rsa.n, 2**32)
|
|
||||||
|
|
||||||
cname = fn.split("/")[-1].split(".")[0] + "_rsa_key"
|
|
||||||
|
|
||||||
print('RSAPublicKey ' + cname + ' = {.len = 0x20,')
|
|
||||||
print(' .n0inv = %dU,' % n0inv)
|
|
||||||
print(' .n = %s,' % to_c_uint32(rsa.n))
|
|
||||||
print(' .rr = %s,' % to_c_uint32(rr))
|
|
||||||
print(' .exponent = %d,' % rsa.e)
|
|
||||||
print('};')
|
|
|
@ -7,7 +7,6 @@ import usb1
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
from .dfu import PandaDFU # pylint: disable=import-error
|
from .dfu import PandaDFU # pylint: disable=import-error
|
||||||
from .flash_release import flash_release # noqa pylint: disable=import-error
|
from .flash_release import flash_release # noqa pylint: disable=import-error
|
||||||
|
@ -19,17 +18,10 @@ from .isotp import isotp_send, isotp_recv # pylint: disable=import-error
|
||||||
__version__ = '0.0.9'
|
__version__ = '0.0.9'
|
||||||
|
|
||||||
BASEDIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../")
|
BASEDIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../")
|
||||||
|
DEFAULT_FW_FN = os.path.join(BASEDIR, "board", "obj", "panda.bin.signed")
|
||||||
|
|
||||||
DEBUG = os.getenv("PANDADEBUG") is not None
|
DEBUG = os.getenv("PANDADEBUG") is not None
|
||||||
|
|
||||||
# *** wifi mode ***
|
|
||||||
def build_st(target, mkfile="Makefile", clean=True):
|
|
||||||
from panda import BASEDIR
|
|
||||||
|
|
||||||
clean_cmd = "make -f %s clean" % mkfile if clean else ":"
|
|
||||||
cmd = 'cd %s && %s && make -f %s %s' % (os.path.join(BASEDIR, "board"), clean_cmd, mkfile, target)
|
|
||||||
_ = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
|
|
||||||
|
|
||||||
def parse_can_buffer(dat):
|
def parse_can_buffer(dat):
|
||||||
ret = []
|
ret = []
|
||||||
for j in range(0, len(dat), 0x10):
|
for j in range(0, len(dat), 0x10):
|
||||||
|
@ -184,7 +176,6 @@ class Panda(object):
|
||||||
if self._serial is None or this_serial == self._serial:
|
if self._serial is None or this_serial == self._serial:
|
||||||
self._serial = this_serial
|
self._serial = this_serial
|
||||||
print("opening device", self._serial, hex(device.getProductID()))
|
print("opening device", self._serial, hex(device.getProductID()))
|
||||||
time.sleep(1)
|
|
||||||
self.bootstub = device.getProductID() == 0xddee
|
self.bootstub = device.getProductID() == 0xddee
|
||||||
self.legacy = (device.getbcdDevice() != 0x2300)
|
self.legacy = (device.getbcdDevice() != 0x2300)
|
||||||
self._handle = device.open()
|
self._handle = device.open()
|
||||||
|
@ -267,23 +258,12 @@ class Panda(object):
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def flash(self, fn=None, code=None, reconnect=True):
|
def flash(self, fn=DEFAULT_FW_FN, code=None, reconnect=True):
|
||||||
print("flash: main version is " + self.get_version())
|
print("flash: main version is " + self.get_version())
|
||||||
if not self.bootstub:
|
if not self.bootstub:
|
||||||
self.reset(enter_bootstub=True)
|
self.reset(enter_bootstub=True)
|
||||||
assert(self.bootstub)
|
assert(self.bootstub)
|
||||||
|
|
||||||
if fn is None and code is None:
|
|
||||||
if self.legacy:
|
|
||||||
fn = "obj/comma.bin"
|
|
||||||
print("building legacy st code")
|
|
||||||
build_st(fn, "Makefile.legacy")
|
|
||||||
else:
|
|
||||||
fn = "obj/panda.bin"
|
|
||||||
print("building panda st code")
|
|
||||||
build_st(fn)
|
|
||||||
fn = os.path.join(BASEDIR, "board", fn)
|
|
||||||
|
|
||||||
if code is None:
|
if code is None:
|
||||||
with open(fn, "rb") as f:
|
with open(fn, "rb") as f:
|
||||||
code = f.read()
|
code = f.read()
|
||||||
|
|
|
@ -92,16 +92,8 @@ class PandaDFU(object):
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
def recover(self):
|
def recover(self):
|
||||||
from panda import BASEDIR, build_st
|
from panda import BASEDIR
|
||||||
if self.legacy:
|
fn = os.path.join(BASEDIR, "board", "obj", "bootstub.panda.bin")
|
||||||
fn = "obj/bootstub.comma.bin"
|
|
||||||
print("building legacy bootstub")
|
|
||||||
build_st(fn, "Makefile.legacy")
|
|
||||||
else:
|
|
||||||
fn = "obj/bootstub.panda.bin"
|
|
||||||
print("building panda bootstub")
|
|
||||||
build_st(fn)
|
|
||||||
fn = os.path.join(BASEDIR, "board", fn)
|
|
||||||
|
|
||||||
with open(fn, "rb") as f:
|
with open(fn, "rb") as f:
|
||||||
code = f.read()
|
code = f.read()
|
||||||
|
|
|
@ -11,3 +11,4 @@ cffi==1.14.3
|
||||||
crcmod
|
crcmod
|
||||||
pre-commit==2.4.0
|
pre-commit==2.4.0
|
||||||
pylint==2.5.2
|
pylint==2.5.2
|
||||||
|
scons==4.1.0.post1
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
from panda import build_st
|
|
||||||
|
|
||||||
def test_build_panda():
|
|
||||||
build_st("obj/panda.bin")
|
|
||||||
|
|
||||||
def test_build_bootstub_panda():
|
|
||||||
build_st("obj/bootstub.panda.bin")
|
|
|
@ -26,7 +26,7 @@ def test_flash(p):
|
||||||
@test_all_pandas
|
@test_all_pandas
|
||||||
@panda_connect_and_init
|
@panda_connect_and_init
|
||||||
def test_get_signature(p):
|
def test_get_signature(p):
|
||||||
fn = os.path.join(BASEDIR, "board/obj/panda.bin")
|
fn = os.path.join(BASEDIR, "board/obj/panda.bin.signed")
|
||||||
|
|
||||||
firmware_sig = Panda.get_signature_from_firmware(fn)
|
firmware_sig = Panda.get_signature_from_firmware(fn)
|
||||||
panda_sig = p.get_signature()
|
panda_sig = p.get_signature()
|
||||||
|
|
Loading…
Reference in New Issue