When working with embedded systems, you’ll often need to check if two firmware versions are truly identical. Here’s when it matters most:
- π Flash Region Check: Did that “tiny change” accidentally modify your bootloader?
- π¦ Code Size Mystery: Why did your firmware suddenly grow 5KB?
- π Security Verification: Are your encryption keys still correct?
- β Release Validation: Does your production build match the tested version?
Standard diff tools fail here because HEX files:
- Have scattered address records (not sequential)
- Use special extended addressing (beyond 64KB)
- Assume missing addresses = 0xFF (erased flash state)
Introducing: pyBinaryCompareIntelHex (Your HEX Diff Hero)
A dead-simple Python toolkit that actually understands embedded memory. No complex setup needed!
π All code on GitHub: github.com/jimmywong2003/pyBinaryCompareIntelHex
How It Works: 2 Steps, Zero Headaches
Step 1: Extract Binary from HEX
Convert HEX to clean binary for specific memory regions:
python generateBinaryFromHex.py
β¨ Example – Extract 64KB from flash:
# Extract 64KB from flash starting at 0x08000000 python generateBinaryFromHex.py firmware.hex 0x08000000 0x10000 output.bin
β¨ Why it’s smart:
- Handles 32-bit addresses (no 64KB limit!)
- Fills missing gaps with 0xFF (like real flash)
- Works for ANY region (bootloader, config, app code)
Step 2: Compare Binaries with Real Addresses
See differences in actual memory addresses, not confusing offsets:
π― Example – Compare with base address:
# Compare two binaries with base address 0x08000000 python compareBinary.py old.bin new.bin 0x08000000
π― Sample output (human-readable!):
Found 2 differences: 0x08001A24: 0x3A (old) vs 0x3B (new) 0x08001A25: 0x1F (old) vs 0x20 (new)
β Key benefits:
- Shows real MCU addresses (no hex editor needed)
- Limits to 10 differences (avoids info overload)
- Handles different file sizes gracefully
Real Example: Why Did Code Size Increase?
Problem: After adding a feature, firmware grew by 3KB. Is this normal?
- Extract text section from both versions:
python generateBinaryFromHex.py v1.hex 0x08004000 0x10000 v1_text.bin
python generateBinaryFromHex.py v2.hex 0x08004000 0x10000 v2_text.bin - Compare with real addresses:
python compareBinary.py v1_text.bin v2_text.bin 0x08004000
- Read the result (no guessing!):
0x08004A2C: 0x00 (v1) vs 0x1A (v2) β New function starts here!
π‘ Insight: If differences cluster in one area β expected change. If scattered β investigate!
Better Than Standard Tools (Seriously)
| Tool | Intel HEX Support | Real Addresses |
|---|---|---|
| diff / WinDiff | β Treats as text | β Shows offsets only |
| Hex Editors | β οΈ Manual work | β οΈ Hard to track |
| pyBinaryCompareIntelHex | β Native support | β Real MCU addresses |
Get Started in 30 Seconds
β No installation needed (pure Python):
git clone https://github.com/jimmywong2003/pyBinaryCompareIntelHex cd pyBinaryCompareIntelHex
β Check bootloader didn’t change (add to your CI!):
# Extract bootloader from new build python generateBinaryFromHex.py new.hex 0x08000000 0x4000 new_bl.bin # Compare with reference python compareBinary.py ref_bl.bin new_bl.bin 0x08000000
π Success output: same
π Problem output: Shows exactly where it changed
Why You’ll Love This
- β±οΈ Saves hours vs manual hex analysis
- π§ No mental math for address calculations
- π‘οΈ Catches sneaky changes in critical regions
- π Works in CI pipelines for automated checks
β Pro Tip: Bookmark the GitHub repo – you’ll use this more than you think!