Skip to content

Commit

Permalink
Merge pull request #103 from OpenSourceLightshows/kurt/save-version-t…
Browse files Browse the repository at this point in the history
…o-firmware

kurt/save-version-to-firmware
  • Loading branch information
Unreal-Dan authored Dec 9, 2024
2 parents 3b50efc + b4029e2 commit 175f395
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 10 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ jobs:
uses: ncipollo/release-action@v1
with:
tag: ${{ env.new_tag }}
name: Helios Vortex ${{ env.new_version }}
name: Helios ${{ env.new_version }}
body: |
Release of Helios Vortex version ${{ env.new_version }}
Release of Helios version ${{ env.new_version }}
draft: false
prerelease: false
env:
Expand Down
2 changes: 2 additions & 0 deletions Helios/Helios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ bool Helios::keepgoing;
bool Helios::sleeping;
#endif

volatile char helios_version[] = HELIOS_VERSION_STR;

bool Helios::init()
{
// first initialize all the components of helios
Expand Down
37 changes: 37 additions & 0 deletions Helios/HeliosConfig.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,43 @@
#ifndef HELIOS_CONFIG_H
#define HELIOS_CONFIG_H

// Version Configurations
//
// The engine major version indicates the state of the save file,
// if changes to the save format occur then the major version
// must increment so that the savefiles will not be loaded
#ifndef HELIOS_VERSION_MAJOR
#define HELIOS_VERSION_MAJOR 0
#endif

// A minor version simply indicates a bugfix or minor change that
// will not affect the save files produced by the engine. This means
// a savefile produced by 1.1 should be loadable by an engine on 1.2
// and vice versa, but an engine on 2.0 cannot share savefiles with
// either of the engines on version 1.1 or 1.2
#ifndef HELIOS_VERSION_MINOR
#define HELIOS_VERSION_MINOR 0
#endif

// The build or patch number based on the major.minor version, this is
// set by the build system using the number of commits since last version
#ifndef HELIOS_BUILD_NUMBER
#define HELIOS_BUILD_NUMBER 0
#endif

// Produces a number like 1.3.0
#ifndef HELIOS_VERSION_NUMBER
#define HELIOS_VERSION_NUMBER HELIOS_VERSION_MAJOR.HELIOS_VERSION_MINOR.HELIOS_BUILD_NUMBER
#endif


// Helios Version String
//
// This is the string literal equivalent of HELIOS_VERSION_NUMBER above
#define ADD_QUOTES(str) #str
#define EXPAND_AND_QUOTE(str) ADD_QUOTES(str)
#define HELIOS_VERSION_STR EXPAND_AND_QUOTE(HELIOS_VERSION_NUMBER)

// Short Click Threshold
//
// The length of time in milliseconds for a click to
Expand Down
49 changes: 41 additions & 8 deletions HeliosEmbedded/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
### CONFIGURATION ###
#####################

.PHONY: all upload set_fuses set_default_fuses set_16mhz_fuses set_8mhz_fuses set_1mhz_fuses get_fuses extract_hex upload_hex extract_eeprom upload_eeprom clean
.PHONY: all upload set_fuses set_default_fuses set_16mhz_fuses set_8mhz_fuses set_1mhz_fuses get_fuses extract_hex upload_hex extract_eeprom upload_eeprom clean compute_version extract_version

ifneq ($(OS),Windows_NT)
OS = $(shell uname -s)
Expand Down Expand Up @@ -67,9 +67,12 @@ AVRDUDE_FLAGS = -C$(AVRDUDE_CONF) \
-P$(AVRDUDE_PORT) \
-b$(AVRDUDE_BAUDRATE) \
-v \
-B1 \
-V \
-D
-B1

# -v -- Verbose output - display detailed progress
# -B1 -- Bit clock period (in microseconds) - sets programming speed
# -V -- Disable automatic verify check when uploading
# -D -- Disable auto erase for flash memory


#######################
Expand All @@ -81,6 +84,16 @@ CPU_SPEED = 8000000L
# the port for serial upload
SERIAL_PORT = COM11

# compiler defines
DEFINES=\
-DHELIOS_VERSION_MAJOR=$(HELIOS_VERSION_MAJOR) \
-DHELIOS_VERSION_MINOR=$(HELIOS_VERSION_MINOR) \
-DHELIOS_BUILD_NUMBER=$(HELIOS_BUILD_NUMBER) \
-DHELIOS_VERSION_NUMBER=$(HELIOS_VERSION_NUMBER) \
-D__AVR_ATtiny85__ \
-DF_CPU=$(CPU_SPEED) \
-D HELIOS_EMBEDDED

CFLAGS = -g \
-Os \
-MMD \
Expand All @@ -99,7 +112,6 @@ CFLAGS = -g \
-D__AVR_ATtiny85__ \
-mmcu=$(AVRDUDE_CHIP) \
-DF_CPU=$(CPU_SPEED) \
-D HELIOS_EMBEDDED

LDFLAGS = -g \
-Wall \
Expand All @@ -116,6 +128,9 @@ ifeq ($(OS),Windows_NT) # Windows
LDFLAGS+=-B $(DEVICE_DIR)
endif

ifneq ($(DEFINES),)
CFLAGS+=$(DEFINES)
endif
INCLUDES= \
-I $(INCLUDE_DIR) \
-I ../Helios
Expand Down Expand Up @@ -146,20 +161,21 @@ DFILES = $(SRCS:.cpp=.d)
# Target name
TARGET = helios

all: $(TARGET).hex
all: compute_version $(TARGET).hex
@echo Detected Operating System: $(OS)
$(OBJDUMP) --disassemble --source --line-numbers --demangle --section=.text $(TARGET).elf > $(TARGET).lst
$(NM) --numeric-sort --line-numbers --demangle --print-size --format=s $(TARGET).elf > $(TARGET).map
chmod +x avrsize.sh
./avrsize.sh $(TARGET).elf
@echo "== Success building Helios v$(HELIOS_VERSION_NUMBER) =="

$(TARGET).hex: $(TARGET).elf
$(OBJCOPY) -O binary -R .eeprom $(TARGET).elf $(TARGET).bin
$(OBJCOPY) -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 $(TARGET).elf $(TARGET).eep
$(OBJCOPY) -O ihex -R .eeprom $< $@

$(TARGET).elf: $(OBJS)
$(LD) $(LDFLAGS) $^ -o $@
$(TARGET).elf: compute_version $(OBJS)
$(LD) $(LDFLAGS) $(OBJS) -o $@

%.o: %.S
$(CC) $(ASMFLAGS) -c $< -o $@
Expand Down Expand Up @@ -270,5 +286,22 @@ extract_hex: helios_firmware.hex
clean:
rm -f $(OBJS) $(TARGET).elf $(TARGET).hex $(DFILES) $(TARGET).bin $(TARGET).eep $(TARGET).lst $(TARGET).map

compute_version:
$(eval LATEST_TAG ?= $(shell git fetch --depth=1 origin +refs/tags/*:refs/tags/* &> /dev/null && git tag --list | sort -V | tail -n1))
$(eval HELIOS_VERSION_MAJOR ?= $(shell echo $(LATEST_TAG) | cut -d. -f1))
$(eval HELIOS_VERSION_MINOR ?= $(shell echo $(LATEST_TAG) | sed 's/$(BRANCH_SUFFIX)$$//' | cut -d. -f2))
$(eval HELIOS_BUILD_NUMBER ?= $(shell git rev-list --count $(LATEST_TAG)..HEAD))
$(eval HELIOS_VERSION_MAJOR := $(if $(HELIOS_VERSION_MAJOR),$(HELIOS_VERSION_MAJOR),0))
$(eval HELIOS_VERSION_MINOR := $(if $(HELIOS_VERSION_MINOR),$(HELIOS_VERSION_MINOR),1))
$(eval HELIOS_BUILD_NUMBER := $(if $(HELIOS_BUILD_NUMBER),$(HELIOS_BUILD_NUMBER),0))
$(eval HELIOS_VERSION_NUMBER := $(HELIOS_VERSION_MAJOR).$(HELIOS_VERSION_MINOR).$(HELIOS_BUILD_NUMBER))

extract_version:
@echo "Reading firmware version..."
$(eval TEMP_HEX := $(shell mktemp))
$(AVRDUDE) $(AVRDUDE_FLAGS) -U flash:r:$(TEMP_HEX):i > /dev/null 2>&1
python ./find_version.py $(TEMP_HEX)
@rm $(TEMP_HEX)

# include dependency files to ensure partial rebuilds work correctly
-include $(DFILES)
56 changes: 56 additions & 0 deletions HeliosEmbedded/find_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import sys

def find_version(hex_content):
try:
# Convert hex file content to string if it's bytes
if isinstance(hex_content, bytes):
hex_content = hex_content.decode('ascii')

# Look for the specific hex pattern: 312E332E3238 (1.3.28)
# First convert the entire content to a continuous string of hex values
hex_string = ''.join(line.strip()[9:-2] for line in hex_content.splitlines() if line.startswith(':'))

# Look for our version pattern
import re
# Pattern for version number in hex (31 2E 33 2E 32 38 = "1.3.28")
version_pattern = r'312E[0-9A-F]{2}2E[0-9A-F]{2,4}'
match = re.search(version_pattern, hex_string)

if match:
# Convert hex to ASCII
hex_version = match.group(0)
version_bytes = bytes.fromhex(hex_version)
version_str = version_bytes.decode('ascii')
return version_str

return None
except Exception as e:
print(f"Error processing hex file: {str(e)}")
return None

if __name__ == "__main__":
try:
# Check if filename is provided as argument
if len(sys.argv) > 1:
filename = sys.argv[1]
with open(filename, 'rb') as f: # Open in binary mode
content = f.read()
# Otherwise read from stdin if input is piped
elif not sys.stdin.isatty():
content = sys.stdin.buffer.read() # Read binary from stdin
# If no input provided, show usage
else:
print("Error: No input provided")
print("Usage: python find_version.py [filename]")
print(" or: cat file.hex | python find_version.py")
sys.exit(1)

version = find_version(content)
if version:
print(f"Found version: {version}")
else:
print("Version signature not found.")
except FileNotFoundError:
print("Error: Hex file not found")
except Exception as e:
print(f"Error: {str(e)}")

0 comments on commit 175f395

Please sign in to comment.