mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-23 13:21:44 +03:00
[FL-1443, FL-1289] Move assets compilation to separate Makefile. Add scripts folder. Add OTP flashing with DFU. (#531)
* Assets: move assets compilation to separate Makefile. Move all scripts to scripts folder. Add scripts ReadMe. Add precompiled assets. * Split assets.py into separate entities. Option bytes for FL-1289 and checker/setter. * Cli: explicitly initialize variable befor use in api_hal_vcp_rx_with_timeout * Rename ob_check script to ob.
This commit is contained in:
parent
359bbdfe69
commit
8116bfcbab
@ -51,7 +51,7 @@ size_t cli_read(Cli* cli, uint8_t* buffer, size_t size) {
|
||||
}
|
||||
|
||||
bool cli_cmd_interrupt_received(Cli* cli) {
|
||||
char c;
|
||||
char c = '\0';
|
||||
api_hal_vcp_rx_with_timeout((uint8_t*)&c, 1, 1);
|
||||
return c == CliSymbolAsciiETX;
|
||||
}
|
||||
|
11
assets/Makefile
Normal file
11
assets/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
PROJECT_ROOT = $(abspath $(dir $(abspath $(firstword $(MAKEFILE_LIST))))..)
|
||||
|
||||
include $(PROJECT_ROOT)/assets/assets.mk
|
||||
|
||||
$(ASSETS): $(ASSETS_SOURCES) $(ASSETS_COMPILLER)
|
||||
@echo "\tASSETS\t" $@
|
||||
@$(ASSETS_COMPILLER) icons -s $(ASSETS_SOURCE_DIR) -o $(ASSETS_COMPILED_DIR)
|
||||
|
||||
clean:
|
||||
@echo "\tCLEAN\t"
|
||||
@$(RM) $(ASSETS)
|
@ -1,3 +1,13 @@
|
||||
# Requirements
|
||||
|
||||
- Python3
|
||||
- ImageMagic
|
||||
- Make
|
||||
|
||||
# Compiling
|
||||
|
||||
make all
|
||||
|
||||
# Asset naming rules
|
||||
|
||||
## Images and Animations
|
||||
|
@ -1,10 +1,10 @@
|
||||
ASSETS_DIR := $(PROJECT_ROOT)/assets
|
||||
ASSETS_COMPILLER := $(ASSETS_DIR)/assets.py
|
||||
ASSETS_OUTPUT_DIR := $(ASSETS_DIR)/output
|
||||
ASSETS_COMPILLER := $(PROJECT_ROOT)/scripts/assets.py
|
||||
ASSETS_COMPILED_DIR := $(ASSETS_DIR)/compiled
|
||||
ASSETS_SOURCE_DIR := $(ASSETS_DIR)/icons
|
||||
|
||||
ASSETS_SOURCES += $(shell find $(ASSETS_SOURCE_DIR) -type f -iname '*.png' -or -iname 'frame_rate')
|
||||
ASSETS += $(ASSETS_OUTPUT_DIR)/assets_icons.c
|
||||
ASSETS += $(ASSETS_COMPILED_DIR)/assets_icons.c
|
||||
|
||||
CFLAGS += -I$(ASSETS_OUTPUT_DIR)
|
||||
C_SOURCES += $(ASSETS_OUTPUT_DIR)/assets_icons.c
|
||||
CFLAGS += -I$(ASSETS_COMPILED_DIR)
|
||||
C_SOURCES += $(ASSETS_COMPILED_DIR)/assets_icons.c
|
||||
|
617
assets/compiled/assets_icons.c
Normal file
617
assets/compiled/assets_icons.c
Normal file
File diff suppressed because one or more lines are too long
131
assets/compiled/assets_icons.h
Normal file
131
assets/compiled/assets_icons.h
Normal file
@ -0,0 +1,131 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/icon.h>
|
||||
|
||||
typedef enum {
|
||||
I_SDQuestion_35x43,
|
||||
I_SDError_43x35,
|
||||
I_Health_16x16,
|
||||
I_FaceCharging_29x14,
|
||||
I_BatteryBody_52x28,
|
||||
I_Voltage_16x16,
|
||||
I_Temperature_16x16,
|
||||
I_FaceNopower_29x14,
|
||||
I_FaceNormal_29x14,
|
||||
I_Battery_16x16,
|
||||
I_FaceConfused_29x14,
|
||||
I_PassportBottom_128x17,
|
||||
I_DoorLeft_8x56,
|
||||
I_DoorLocked_10x56,
|
||||
I_DoorRight_8x56,
|
||||
I_DoorLeft_70x55,
|
||||
I_PassportLeft_6x47,
|
||||
I_DoorRight_70x55,
|
||||
I_LockPopup_100x49,
|
||||
I_WalkR2_32x32,
|
||||
I_WalkL2_32x32,
|
||||
I_WalkRB1_32x32,
|
||||
I_Home_painting_17x20,
|
||||
I_WalkLB2_32x32,
|
||||
I_Sofa_40x13,
|
||||
I_WalkLB1_32x32,
|
||||
I_PC_22x29,
|
||||
I_WalkL1_32x32,
|
||||
I_TV_20x20,
|
||||
I_WalkR1_32x32,
|
||||
I_WalkRB2_32x32,
|
||||
I_TV_20x24,
|
||||
I_dir_10px,
|
||||
I_Nfc_10px,
|
||||
I_sub1_10px,
|
||||
I_ir_10px,
|
||||
I_ibutt_10px,
|
||||
I_unknown_10px,
|
||||
I_ble_10px,
|
||||
I_125_10px,
|
||||
I_FX_SittingB_40x27,
|
||||
I_BigGames_24x24,
|
||||
I_BigProfile_24x24,
|
||||
I_DolphinOkay_41x43,
|
||||
I_DolphinFirstStart5_45x53,
|
||||
I_DolphinFirstStart4_67x53,
|
||||
I_DolphinFirstStart2_59x51,
|
||||
I_DolphinFirstStart0_70x53,
|
||||
I_DolphinFirstStart6_58x54,
|
||||
I_DolphinFirstStart1_59x53,
|
||||
I_DolphinFirstStart8_56x51,
|
||||
I_DolphinFirstStart7_61x51,
|
||||
I_Flipper_young_80x60,
|
||||
I_BigBurger_24x24,
|
||||
I_FX_Bang_32x6,
|
||||
I_DolphinFirstStart3_57x48,
|
||||
I_BadUsb_9x8,
|
||||
I_PlaceholderR_30x13,
|
||||
I_Background_128x8,
|
||||
I_Lock_8x8,
|
||||
I_Battery_26x8,
|
||||
I_PlaceholderL_11x13,
|
||||
I_Battery_19x8,
|
||||
I_SDcardMounted_11x8,
|
||||
I_SDcardFail_11x8,
|
||||
I_USBConnected_15x8,
|
||||
I_Bluetooth_5x8,
|
||||
I_Background_128x11,
|
||||
I_IrdaArrowUp_4x8,
|
||||
I_IrdaLearnShort_128x31,
|
||||
I_IrdaArrowDown_4x8,
|
||||
I_IrdaLearn_128x64,
|
||||
I_IrdaSend_128x64,
|
||||
I_IrdaSendShort_128x34,
|
||||
I_passport_happy1_43x45,
|
||||
I_passport_bad3_43x45,
|
||||
I_passport_okay2_43x45,
|
||||
I_passport_bad2_43x45,
|
||||
I_passport_okay3_43x45,
|
||||
I_passport_bad1_43x45,
|
||||
I_passport_happy3_43x45,
|
||||
I_passport_happy2_43x45,
|
||||
I_passport_okay1_43x45,
|
||||
I_ButtonRightSmall_3x5,
|
||||
I_ButtonLeft_4x7,
|
||||
I_ButtonLeftSmall_3x5,
|
||||
I_ButtonRight_4x7,
|
||||
I_ButtonCenter_7x7,
|
||||
A_Games_14,
|
||||
A_Plugins_14,
|
||||
A_Passport_14,
|
||||
A_Sub1ghz_14,
|
||||
A_NFC_14,
|
||||
A_Tamagotchi_14,
|
||||
A_FileManager_14,
|
||||
A_125khz_14,
|
||||
A_U2F_14,
|
||||
A_Infrared_14,
|
||||
A_Power_14,
|
||||
A_Settings_14,
|
||||
A_iButton_14,
|
||||
A_Bluetooth_14,
|
||||
A_GPIO_14,
|
||||
I_DolphinMafia_115x62,
|
||||
I_DolphinExcited_64x63,
|
||||
I_iButtonDolphinSuccess_109x60,
|
||||
I_iButtonDolphinVerySuccess_108x52,
|
||||
I_iButtonKey_49x44,
|
||||
I_DolphinNice_96x59,
|
||||
I_DolphinWait_61x59,
|
||||
A_Wink_128x64,
|
||||
A_MDWL_32x32,
|
||||
A_MDWR_32x32,
|
||||
A_WatchingTV_128x64,
|
||||
A_MDI_32x32,
|
||||
A_MDWRB_32x32,
|
||||
A_MDIB_32x32,
|
||||
A_FX_Sitting_40x27,
|
||||
A_MDWLB_32x32,
|
||||
I_KeySave_24x11,
|
||||
I_KeyBackspaceSelected_16x9,
|
||||
I_KeySaveSelected_24x11,
|
||||
I_KeyBackspace_16x9,
|
||||
} IconName;
|
||||
|
||||
Icon * assets_icons_get(IconName name);
|
5
assets/compiled/assets_icons_i.h
Normal file
5
assets/compiled/assets_icons_i.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <assets_icons.h>
|
||||
|
||||
const IconData * assets_icons_get_data(IconName name);
|
1
assets/output/.gitignore
vendored
1
assets/output/.gitignore
vendored
@ -1 +0,0 @@
|
||||
*
|
@ -8,7 +8,7 @@ ASM_SOURCES += $(wildcard src/*.s)
|
||||
C_SOURCES += $(wildcard src/*.c)
|
||||
CPP_SOURCES += $(wildcard src/*.cpp)
|
||||
|
||||
TARGET ?= f5
|
||||
TARGET ?= f6
|
||||
TARGET_DIR = targets/$(TARGET)
|
||||
include $(TARGET_DIR)/target.mk
|
||||
|
||||
|
@ -3,6 +3,7 @@ PROJECT = firmware
|
||||
|
||||
include $(PROJECT_ROOT)/make/base.mk
|
||||
include $(PROJECT_ROOT)/assets/assets.mk
|
||||
CFLAGS += -I$(ASSETS_COMPILED_DIR)
|
||||
include $(PROJECT_ROOT)/core/core.mk
|
||||
include $(PROJECT_ROOT)/applications/applications.mk
|
||||
include $(PROJECT_ROOT)/lib/lib.mk
|
||||
@ -10,7 +11,7 @@ include $(PROJECT_ROOT)/lib/lib.mk
|
||||
CFLAGS += -Werror -Wno-address-of-packed-member
|
||||
CPPFLAGS += -Werror
|
||||
|
||||
TARGET ?= f5
|
||||
TARGET ?= f6
|
||||
|
||||
TARGET_DIR = targets/$(TARGET)
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -x -e
|
||||
|
||||
rm bootloader/.obj/f*/flash || true
|
||||
make -C bootloader -j9 flash
|
||||
|
||||
rm firmware/.obj/f*/flash || true
|
||||
make -C firmware -j9 flash
|
@ -47,15 +47,15 @@ $(OBJ_DIR)/$(PROJECT).bin: $(OBJ_DIR)/$(PROJECT).elf
|
||||
@echo "\tBIN\t" $@
|
||||
@$(BIN) $< $@
|
||||
|
||||
$(OBJ_DIR)/%.o: %.c $(OBJ_DIR)/BUILD_FLAGS $(ASSETS)
|
||||
$(OBJ_DIR)/%.o: %.c $(OBJ_DIR)/BUILD_FLAGS
|
||||
@echo "\tCC\t" $< "->" $@
|
||||
@$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(OBJ_DIR)/%.o: %.s $(OBJ_DIR)/BUILD_FLAGS $(ASSETS)
|
||||
$(OBJ_DIR)/%.o: %.s $(OBJ_DIR)/BUILD_FLAGS
|
||||
@echo "\tASM\t" $< "->" $@
|
||||
@$(AS) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(OBJ_DIR)/%.o: %.cpp $(OBJ_DIR)/BUILD_FLAGS $(ASSETS)
|
||||
$(OBJ_DIR)/%.o: %.cpp $(OBJ_DIR)/BUILD_FLAGS
|
||||
@echo "\tCPP\t" $< "->" $@
|
||||
@$(CPP) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
@ -67,10 +67,6 @@ $(OBJ_DIR)/upload: $(OBJ_DIR)/$(PROJECT).bin
|
||||
dfu-util -D $(OBJ_DIR)/$(PROJECT).bin -a 0 -s $(FLASH_ADDRESS) $(DFU_OPTIONS)
|
||||
touch $@
|
||||
|
||||
$(ASSETS): $(ASSETS_SOURCES) $(ASSETS_COMPILLER)
|
||||
@echo "\tASSETS\t" $@
|
||||
@$(ASSETS_COMPILLER) icons -s $(ASSETS_SOURCE_DIR) -o $(ASSETS_OUTPUT_DIR)
|
||||
|
||||
flash: $(OBJ_DIR)/flash
|
||||
|
||||
upload: $(OBJ_DIR)/upload
|
||||
@ -104,7 +100,6 @@ bm_debug: flash
|
||||
clean:
|
||||
@echo "\tCLEAN\t"
|
||||
@$(RM) $(OBJ_DIR)/*
|
||||
@$(RM) $(ASSETS)
|
||||
|
||||
z: clean
|
||||
$(MAKE) all
|
||||
@ -123,7 +118,7 @@ format:
|
||||
@echo "Formatting sources with clang-format"
|
||||
@clang-format -style=file -i $(FORMAT_SOURCES)
|
||||
|
||||
generate_cscope_db: $(ASSETS)
|
||||
generate_cscope_db:
|
||||
@echo "$(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES)" | tr ' ' '\n' > $(OBJ_DIR)/source.list.p
|
||||
@cat ~/headers.list >> $(OBJ_DIR)/source.list.p
|
||||
@cat $(OBJ_DIR)/source.list.p | sed -e "s|^[^//]|$$PWD/&|g" > $(OBJ_DIR)/source.list
|
||||
|
51
scripts/ReadMe.md
Normal file
51
scripts/ReadMe.md
Normal file
@ -0,0 +1,51 @@
|
||||
# About
|
||||
|
||||
This folder contains differnt scripts that automates routine actions.
|
||||
Flashing scripts are based on cli version of [STM32CubeProgrammer](https://www.st.com/en/development-tools/stm32cubeprog.html).
|
||||
You will need to add STM32_Programmer_CLI to your path to use them.
|
||||
|
||||
# Flashing empty MCU/Flipper
|
||||
|
||||
Always flash your device in the folllowing sequence:
|
||||
|
||||
- OTP (Only on empty MCU)
|
||||
- Core2 firmware
|
||||
- Core1 firmware
|
||||
- Option Bytes
|
||||
|
||||
## Otp flashing
|
||||
|
||||
!!! Flashing incorrect OTP may permanently brick your device !!!
|
||||
|
||||
Normally OTP data generated and flashed at factory.
|
||||
In case if MCU was replaced you'll need correct OTP data to be able to use companion applications.
|
||||
Use `otp.py` to generate OTP data and `flash_otp_version_*` to flash OTP zone.
|
||||
You will need exact main board revision to genrate OTP data. It can be found on main PCB.
|
||||
|
||||
!!! Flashing incorrect OTP may permanently brick your device !!!
|
||||
|
||||
## Core2 flashing
|
||||
|
||||
Script blindly updates FUS and Radiostack. This operation is going to corrupt bootloader and firmware.
|
||||
Reflash Core1 after Core2.
|
||||
|
||||
## Core1 flashing
|
||||
|
||||
Script compiles and flashes both bootloader and firmware.
|
||||
|
||||
## Option Bytes
|
||||
|
||||
!!! Setting incorrect Otion Bytes may brick your MCU !!!
|
||||
|
||||
Defaults are mostly OK, but there are couple things that we'd like to tune.
|
||||
Also OB may be damaged, so we've made couple scripts to check and set option bytes.
|
||||
|
||||
!!! Setting incorrect Otion Bytes may brick your MCU !!!
|
||||
|
||||
Checking option bytes:
|
||||
|
||||
ob.py check
|
||||
|
||||
Setting option bytes:
|
||||
|
||||
ob.py set
|
@ -6,9 +6,6 @@ import subprocess
|
||||
import io
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import struct
|
||||
import datetime
|
||||
|
||||
ICONS_SUPPORTED_FORMATS = ["png"]
|
||||
|
||||
@ -51,7 +48,7 @@ Icon * assets_icons_get(IconName name) {
|
||||
"""
|
||||
|
||||
|
||||
class Assets:
|
||||
class Main:
|
||||
def __init__(self):
|
||||
# command args
|
||||
self.parser = argparse.ArgumentParser()
|
||||
@ -67,22 +64,6 @@ class Assets:
|
||||
"-o", "--output-directory", help="Output directory"
|
||||
)
|
||||
self.parser_icons.set_defaults(func=self.icons)
|
||||
self.parser_otp = self.subparsers.add_parser(
|
||||
"otp", help="OTP HW version generator"
|
||||
)
|
||||
self.parser_otp.add_argument(
|
||||
"--version", type=int, help="Version", required=True
|
||||
)
|
||||
self.parser_otp.add_argument(
|
||||
"--firmware", type=int, help="Firmware", required=True
|
||||
)
|
||||
self.parser_otp.add_argument("--body", type=int, help="Body", required=True)
|
||||
self.parser_otp.add_argument(
|
||||
"--connect", type=int, help="Connect", required=True
|
||||
)
|
||||
self.parser_otp.add_argument("--name", type=str, help="Name", required=True)
|
||||
self.parser_otp.add_argument("file", help="Output file")
|
||||
self.parser_otp.set_defaults(func=self.otp)
|
||||
# logging
|
||||
self.logger = logging.getLogger()
|
||||
|
||||
@ -101,39 +82,6 @@ class Assets:
|
||||
# execute requested function
|
||||
self.args.func()
|
||||
|
||||
def otp(self):
|
||||
self.logger.debug(f"Generating OTP")
|
||||
|
||||
if self.args.name:
|
||||
name = re.sub(
|
||||
"[^a-zA-Z0-9.]", "", self.args.name
|
||||
) # Filter all special characters
|
||||
name = list(
|
||||
map(str, map(ord, name[0:8]))
|
||||
) # Strip to 8 chars and map to ascii codes
|
||||
while len(name) < 8:
|
||||
name.append("0")
|
||||
|
||||
n1, n2, n3, n4, n5, n6, n7, n8 = map(int, name)
|
||||
|
||||
data = struct.pack(
|
||||
"<BBBBLBBBBBBBB",
|
||||
self.args.version,
|
||||
self.args.firmware,
|
||||
self.args.body,
|
||||
self.args.connect,
|
||||
int(datetime.datetime.now().timestamp()),
|
||||
n1,
|
||||
n2,
|
||||
n3,
|
||||
n4,
|
||||
n5,
|
||||
n6,
|
||||
n7,
|
||||
n8,
|
||||
)
|
||||
open(self.args.file, "wb").write(data)
|
||||
|
||||
def icons(self):
|
||||
self.logger.debug(f"Converting icons")
|
||||
icons_c = open(os.path.join(self.args.output_directory, "assets_icons.c"), "w")
|
||||
@ -248,4 +196,4 @@ class Assets:
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
Assets()()
|
||||
Main()()
|
12
scripts/flash_core1_main_swd.sh
Executable file
12
scripts/flash_core1_main_swd.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -x -e
|
||||
|
||||
SCRIPT_DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
rm $PROJECT_DIR/bootloader/.obj/f*/flash || true
|
||||
make -C $PROJECT_DIR/bootloader -j9 flash
|
||||
|
||||
rm $PROJECT_DIR/firmware/.obj/f*/flash || true
|
||||
make -C $PROJECT_DIR/firmware -j9 flash
|
@ -2,8 +2,9 @@
|
||||
|
||||
set -x -e
|
||||
|
||||
COPRO_DIR="lib/STM32CubeWB/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x"
|
||||
|
||||
SCRIPT_DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
COPRO_DIR="$PROJECT_DIR/lib/STM32CubeWB/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x"
|
||||
|
||||
STM32_Programmer_CLI -c port=swd -fwupgrade $COPRO_DIR/stm32wb5x_FUS_fw_1_0_2.bin 0x080EC000 || true
|
||||
STM32_Programmer_CLI -c port=swd
|
17
scripts/flash_otp_version_dfu.sh
Executable file
17
scripts/flash_otp_version_dfu.sh
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -x -e
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "OTP file required"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ ! -f $1 ]; then
|
||||
echo "Unable to open OTP file"
|
||||
exit
|
||||
fi
|
||||
|
||||
STM32_Programmer_CLI -c port=usb1 -d $1 0x1FFF7000
|
||||
|
||||
STM32_Programmer_CLI -c port=usb1 -r8 0x1FFF7000 8
|
113
scripts/ob.py
Executable file
113
scripts/ob.py
Executable file
@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import logging
|
||||
import argparse
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
class Main:
|
||||
def __init__(self):
|
||||
# command args
|
||||
self.parser = argparse.ArgumentParser()
|
||||
self.parser.add_argument("-d", "--debug", action="store_true", help="Debug")
|
||||
self.subparsers = self.parser.add_subparsers(help="sub-command help")
|
||||
self.parser_check = self.subparsers.add_parser(
|
||||
"check", help="Check Option Bytes"
|
||||
)
|
||||
self.parser_check.set_defaults(func=self.check)
|
||||
self.parser_set = self.subparsers.add_parser("set", help="Set Option Bytes")
|
||||
self.parser_set.set_defaults(func=self.set)
|
||||
# logging
|
||||
self.logger = logging.getLogger()
|
||||
# OB
|
||||
self.ob = {}
|
||||
|
||||
def __call__(self):
|
||||
self.args = self.parser.parse_args()
|
||||
if "func" not in self.args:
|
||||
self.parser.error("Choose something to do")
|
||||
# configure log output
|
||||
self.log_level = logging.DEBUG if self.args.debug else logging.INFO
|
||||
self.logger.setLevel(self.log_level)
|
||||
self.handler = logging.StreamHandler(sys.stdout)
|
||||
self.handler.setLevel(self.log_level)
|
||||
self.formatter = logging.Formatter("%(asctime)s [%(levelname)s] %(message)s")
|
||||
self.handler.setFormatter(self.formatter)
|
||||
self.logger.addHandler(self.handler)
|
||||
# execute requested function
|
||||
self.loadOB()
|
||||
self.args.func()
|
||||
|
||||
def loadOB(self):
|
||||
self.logger.info(f"Loading Option Bytes data")
|
||||
file_path = os.path.join(os.path.dirname(sys.argv[0]), "ob.data")
|
||||
file = open(file_path, "r")
|
||||
for line in file.readlines():
|
||||
k, v, o = line.split(":")
|
||||
self.ob[k.strip()] = v.strip(), o.strip()
|
||||
|
||||
def check(self):
|
||||
self.logger.info(f"Checking Option Bytes")
|
||||
try:
|
||||
output = subprocess.check_output(
|
||||
["STM32_Programmer_CLI", "-q", "-c port=swd", "-ob displ"]
|
||||
)
|
||||
assert output
|
||||
except Exception as e:
|
||||
self.logger.error(f"Failed to call STM32_Programmer_CLI")
|
||||
self.logger.exception(e)
|
||||
return
|
||||
ob_correct = True
|
||||
for line in output.decode().split("\n"):
|
||||
line = line.strip()
|
||||
if not ":" in line:
|
||||
self.logger.debug(f"Skipping line: {line}")
|
||||
continue
|
||||
key, data = line.split(":", 1)
|
||||
key = key.strip()
|
||||
data = data.strip()
|
||||
if not key in self.ob.keys():
|
||||
self.logger.debug(f"Skipping key: {key}")
|
||||
continue
|
||||
self.logger.debug(f"Processing key: {key} {data}")
|
||||
value, comment = data.split(" ", 1)
|
||||
value = value.strip()
|
||||
comment = comment.strip()
|
||||
if self.ob[key][0] != value:
|
||||
self.logger.error(
|
||||
f"Invalid OB: {key} {value}, expected: {self.ob[key][0]}"
|
||||
)
|
||||
ob_correct = False
|
||||
if ob_correct:
|
||||
self.logger.info(f"OB Check OK")
|
||||
else:
|
||||
self.logger.error(f"OB Check FAIL")
|
||||
exit(255)
|
||||
|
||||
def set(self):
|
||||
self.logger.info(f"Setting Option Bytes")
|
||||
options = []
|
||||
for key, (value, attr) in self.ob.items():
|
||||
if "w" in attr:
|
||||
options.append(f"{key}={value}")
|
||||
try:
|
||||
output = subprocess.check_output(
|
||||
[
|
||||
"STM32_Programmer_CLI",
|
||||
"-q",
|
||||
"-c port=swd",
|
||||
f"-ob {' '.join(options)}",
|
||||
]
|
||||
)
|
||||
assert output
|
||||
self.logger.info(f"Success")
|
||||
except Exception as e:
|
||||
self.logger.error(f"Failed to call STM32_Programmer_CLI")
|
||||
self.logger.exception(e)
|
||||
return
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
Main()()
|
34
scripts/ob_check.data
Normal file
34
scripts/ob_check.data
Normal file
@ -0,0 +1,34 @@
|
||||
RDP:0xAA:r
|
||||
BOR_LEV:0x4:rw
|
||||
nBOOT0:0x1:rw
|
||||
nBOOT1:0x1:rw
|
||||
nSWBOOT0:0x1:rw
|
||||
SRAM2RST:0x0:rw
|
||||
SRAM2PE:0x1:rw
|
||||
nRST_STOP:0x1:rw
|
||||
nRST_STDBY:0x1:rw
|
||||
nRSTSHDW:0x1:rw
|
||||
WWDGSW:0x1:rw
|
||||
IWGDSTDBY:0x1:rw
|
||||
IWDGSTOP:0x1:rw
|
||||
IWDGSW:0x1:rw
|
||||
IPCCDBA:0x0:rw
|
||||
ESE:0x1:r
|
||||
SFSA:0xCB:r
|
||||
FSD:0x0:r
|
||||
DDS:0x1:r
|
||||
C2OPT:0x1:r
|
||||
NBRSD:0x0:r
|
||||
SNBRSA:0xF:r
|
||||
BRSD:0x0:r
|
||||
SBRSA:0xA:r
|
||||
SBRV:0x32C00:r
|
||||
PCROP1A_STRT:0x1FF:r
|
||||
PCROP1A_END:0x0:r
|
||||
PCROP_RDP:0x1:r
|
||||
PCROP1B_STRT:0x1FF:r
|
||||
PCROP1B_END:0x0:r
|
||||
WRP1A_STRT:0xFF:r
|
||||
WRP1A_END:0x0:r
|
||||
WRP1B_STRT:0xFF:r
|
||||
WRP1B_END:0x0:r
|
91
scripts/otp.py
Executable file
91
scripts/otp.py
Executable file
@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import logging
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import struct
|
||||
import datetime
|
||||
|
||||
|
||||
class Main:
|
||||
def __init__(self):
|
||||
# command args
|
||||
self.parser = argparse.ArgumentParser()
|
||||
self.parser.add_argument("-d", "--debug", action="store_true", help="Debug")
|
||||
self.subparsers = self.parser.add_subparsers(help="sub-command help")
|
||||
self.parser_generate = self.subparsers.add_parser(
|
||||
"generate", help="OTP HW version generator"
|
||||
)
|
||||
self.parser_generate.add_argument(
|
||||
"--version", type=int, help="Version", required=True
|
||||
)
|
||||
self.parser_generate.add_argument(
|
||||
"--firmware", type=int, help="Firmware", required=True
|
||||
)
|
||||
self.parser_generate.add_argument(
|
||||
"--body", type=int, help="Body", required=True
|
||||
)
|
||||
self.parser_generate.add_argument(
|
||||
"--connect", type=int, help="Connect", required=True
|
||||
)
|
||||
self.parser_generate.add_argument(
|
||||
"--name", type=str, help="Name", required=True
|
||||
)
|
||||
self.parser_generate.add_argument("file", help="Output file")
|
||||
self.parser_generate.set_defaults(func=self.generate)
|
||||
# logging
|
||||
self.logger = logging.getLogger()
|
||||
|
||||
def __call__(self):
|
||||
self.args = self.parser.parse_args()
|
||||
if "func" not in self.args:
|
||||
self.parser.error("Choose something to do")
|
||||
# configure log output
|
||||
self.log_level = logging.DEBUG if self.args.debug else logging.INFO
|
||||
self.logger.setLevel(self.log_level)
|
||||
self.handler = logging.StreamHandler(sys.stdout)
|
||||
self.handler.setLevel(self.log_level)
|
||||
self.formatter = logging.Formatter("%(asctime)s [%(levelname)s] %(message)s")
|
||||
self.handler.setFormatter(self.formatter)
|
||||
self.logger.addHandler(self.handler)
|
||||
# execute requested function
|
||||
self.args.func()
|
||||
|
||||
def generate(self):
|
||||
self.logger.debug(f"Generating OTP")
|
||||
|
||||
if self.args.name:
|
||||
name = re.sub(
|
||||
"[^a-zA-Z0-9.]", "", self.args.name
|
||||
) # Filter all special characters
|
||||
name = list(
|
||||
map(str, map(ord, name[0:8]))
|
||||
) # Strip to 8 chars and map to ascii codes
|
||||
while len(name) < 8:
|
||||
name.append("0")
|
||||
|
||||
n1, n2, n3, n4, n5, n6, n7, n8 = map(int, name)
|
||||
|
||||
data = struct.pack(
|
||||
"<BBBBLBBBBBBBB",
|
||||
self.args.version,
|
||||
self.args.firmware,
|
||||
self.args.body,
|
||||
self.args.connect,
|
||||
int(datetime.datetime.now().timestamp()),
|
||||
n1,
|
||||
n2,
|
||||
n3,
|
||||
n4,
|
||||
n5,
|
||||
n6,
|
||||
n7,
|
||||
n8,
|
||||
)
|
||||
open(self.args.file, "wb").write(data)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
Main()()
|
@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "RUN SYNTAX CHECK INSIDE CONTAINER"
|
||||
docker-compose exec dev ./docker/syntax_check.sh
|
Loading…
Reference in New Issue
Block a user