nRF51_OTA_strip.py: python script that strips an nRF51 image

Committer:
Jean-Philippe Brucker
Date:
Wed Aug 26 11:17:14 2015 +0100
Revision:
0:5a3618245257
Add OTA strip script

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jean-Philippe Brucker 0:5a3618245257 1 #/usr/bin/env python3
Jean-Philippe Brucker 0:5a3618245257 2
Jean-Philippe Brucker 0:5a3618245257 3 # Remove the SoftDevice part of an nRF51 application, to make it
Jean-Philippe Brucker 0:5a3618245257 4 # transferable over the air
Jean-Philippe Brucker 0:5a3618245257 5
Jean-Philippe Brucker 0:5a3618245257 6 import intelhex
Jean-Philippe Brucker 0:5a3618245257 7
Jean-Philippe Brucker 0:5a3618245257 8 from os.path import exists
Jean-Philippe Brucker 0:5a3618245257 9 from sys import argv, exit
Jean-Philippe Brucker 0:5a3618245257 10
Jean-Philippe Brucker 0:5a3618245257 11
Jean-Philippe Brucker 0:5a3618245257 12 if not argv[2:]:
Jean-Philippe Brucker 0:5a3618245257 13 print("usage: %s <input hex file> <output name>" % argv[0])
Jean-Philippe Brucker 0:5a3618245257 14 exit(1)
Jean-Philippe Brucker 0:5a3618245257 15
Jean-Philippe Brucker 0:5a3618245257 16 in_file, out_file = argv[1:3]
Jean-Philippe Brucker 0:5a3618245257 17
Jean-Philippe Brucker 0:5a3618245257 18 # Set start address if autodetection doesn't work
Jean-Philippe Brucker 0:5a3618245257 19 start_address = None
Jean-Philippe Brucker 0:5a3618245257 20
Jean-Philippe Brucker 0:5a3618245257 21 if exists(out_file):
Jean-Philippe Brucker 0:5a3618245257 22 confirm = input("File %s exists. Replace (y/N)? " % out_file)
Jean-Philippe Brucker 0:5a3618245257 23 if not confirm.lower().startswith("y"):
Jean-Philippe Brucker 0:5a3618245257 24 print("Nothing to do.")
Jean-Philippe Brucker 0:5a3618245257 25 exit(0)
Jean-Philippe Brucker 0:5a3618245257 26
Jean-Philippe Brucker 0:5a3618245257 27
Jean-Philippe Brucker 0:5a3618245257 28 hex_in = intelhex.IntelHex()
Jean-Philippe Brucker 0:5a3618245257 29 hex_in.fromfile(in_file, format='hex')
Jean-Philippe Brucker 0:5a3618245257 30
Jean-Philippe Brucker 0:5a3618245257 31 # Try to guess where application starts: first word contains the
Jean-Philippe Brucker 0:5a3618245257 32 # application's stack base
Jean-Philippe Brucker 0:5a3618245257 33
Jean-Philippe Brucker 0:5a3618245257 34 for app_start in (
Jean-Philippe Brucker 0:5a3618245257 35 0x16000, # Version 7.1.0 of S110 SoftDevice
Jean-Philippe Brucker 0:5a3618245257 36 0x18000, # 8.0.0
Jean-Philippe Brucker 0:5a3618245257 37 0x1c000, # 1.0 S130
Jean-Philippe Brucker 0:5a3618245257 38 ):
Jean-Philippe Brucker 0:5a3618245257 39
Jean-Philippe Brucker 0:5a3618245257 40 # Read first word (little-endian)
Jean-Philippe Brucker 0:5a3618245257 41 try:
Jean-Philippe Brucker 0:5a3618245257 42 w = hex_in.tobinarray(start=app_start, size=4)
Jean-Philippe Brucker 0:5a3618245257 43 except intelhex.NotEnoughDataError:
Jean-Philippe Brucker 0:5a3618245257 44 continue
Jean-Philippe Brucker 0:5a3618245257 45 word = w[3] << 24 | w[2] << 16 | w[1] << 8 | w[0]
Jean-Philippe Brucker 0:5a3618245257 46
Jean-Philippe Brucker 0:5a3618245257 47 # Assume stack pointer is at the end of RAM
Jean-Philippe Brucker 0:5a3618245257 48 if word in (
Jean-Philippe Brucker 0:5a3618245257 49 0x20004000, # 16K
Jean-Philippe Brucker 0:5a3618245257 50 0x20008000, # 32K
Jean-Philippe Brucker 0:5a3618245257 51 ):
Jean-Philippe Brucker 0:5a3618245257 52 start_address = app_start
Jean-Philippe Brucker 0:5a3618245257 53 print("Found application at %x" % start_address)
Jean-Philippe Brucker 0:5a3618245257 54 break
Jean-Philippe Brucker 0:5a3618245257 55
Jean-Philippe Brucker 0:5a3618245257 56 if not start_address:
Jean-Philippe Brucker 0:5a3618245257 57 print("Application start address not found")
Jean-Philippe Brucker 0:5a3618245257 58 exit(2)
Jean-Philippe Brucker 0:5a3618245257 59
Jean-Philippe Brucker 0:5a3618245257 60
Jean-Philippe Brucker 0:5a3618245257 61 hex_out = hex_in[start_address:]
Jean-Philippe Brucker 0:5a3618245257 62 hex_out.tofile(out_file, format="hex")