Import of the contiki-2.x development code from the SICS internal CVS server
This commit is contained in:
parent
c2ae514a13
commit
05f6bb5feb
18
cpu/msp430/buildscripts/Makefile.unix
Normal file
18
cpu/msp430/buildscripts/Makefile.unix
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
ifndef JTAG
|
||||||
|
JTAG := $(CONTIKI_CPU)/buildscripts/jtag/pyjtag/jtag.py
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef JTAG_PORT
|
||||||
|
JTAG_PORT = /dev/ppi0
|
||||||
|
endif
|
||||||
|
|
||||||
|
%.u: %.$(TARGET)
|
||||||
|
$(JTAG) -l $(JTAG_PORT) -e
|
||||||
|
$(JTAG) -l $(JTAG_PORT) -D -D -S -R 2048 -p $^
|
||||||
|
$(JTAG) -l $(JTAG_PORT) -D -r
|
||||||
|
|
||||||
|
r:
|
||||||
|
$(JTAG) -l $(JTAG_PORT) -r
|
||||||
|
|
||||||
|
erase:
|
||||||
|
$(JTAG) -l $(JTAG_PORT) -e
|
7
cpu/msp430/buildscripts/Makefile.win
Normal file
7
cpu/msp430/buildscripts/Makefile.win
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
%.u: %.ihex
|
||||||
|
msp430-jtag -eI $^
|
||||||
|
|
||||||
|
#CW=cw23
|
||||||
|
|
||||||
|
#%.u: %.ihex
|
||||||
|
# $(CW) -d f430p $^
|
BIN
cpu/msp430/buildscripts/jtag/pyjtag/_parjtag.so
Executable file
BIN
cpu/msp430/buildscripts/jtag/pyjtag/_parjtag.so
Executable file
Binary file not shown.
318
cpu/msp430/buildscripts/jtag/pyjtag/elf.py
Normal file
318
cpu/msp430/buildscripts/jtag/pyjtag/elf.py
Normal file
|
@ -0,0 +1,318 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
import struct
|
||||||
|
|
||||||
|
# ELF object file reader
|
||||||
|
# (C) 2003 cliechti@gmx.net
|
||||||
|
# Python license
|
||||||
|
|
||||||
|
# size alignment
|
||||||
|
# Elf32_Addr 4 4 Unsigned program address
|
||||||
|
# Elf32_Half 2 2 Unsigned medium integer
|
||||||
|
# Elf32_Off 4 4 Unsigned file offset
|
||||||
|
# Elf32_Sword 4 4 Signed large integer
|
||||||
|
# Elf32_Word 4 4 Unsigned large integer
|
||||||
|
# unsignedchar 1 1 Unsigned small integer
|
||||||
|
|
||||||
|
#define EI_NIDENT 16
|
||||||
|
#~ typedef struct{
|
||||||
|
#~ unsigned char e_ident[EI_NIDENT];
|
||||||
|
#~ Elf32_Half e_type;
|
||||||
|
#~ Elf32_Half e_machine;
|
||||||
|
#~ Elf32_Word e_version;
|
||||||
|
#~ Elf32_Addr e_entry;
|
||||||
|
#~ Elf32_Off e_phoff;
|
||||||
|
#~ Elf32_Off e_shoff;
|
||||||
|
#~ Elf32_Word e_flags;
|
||||||
|
#~ Elf32_Half e_ehsize;
|
||||||
|
#~ Elf32_Half e_phentsize;
|
||||||
|
#~ Elf32_Half e_phnum;
|
||||||
|
#~ Elf32_Half e_shentsize;
|
||||||
|
#~ Elf32_Half e_shnum;
|
||||||
|
#~ Elf32_Half e_shstrndx;
|
||||||
|
#~ } Elf32_Ehdr;
|
||||||
|
|
||||||
|
|
||||||
|
#Section Header
|
||||||
|
#~ typedef struct {
|
||||||
|
#~ Elf32_Word sh_name;
|
||||||
|
#~ Elf32_Word sh_type;
|
||||||
|
#~ Elf32_Word sh_flags;
|
||||||
|
#~ Elf32_Addr sh_addr;
|
||||||
|
#~ Elf32_Off sh_offset;
|
||||||
|
#~ Elf32_Word sh_size;
|
||||||
|
#~ Elf32_Word sh_link;
|
||||||
|
#~ Elf32_Word sh_info;
|
||||||
|
#~ Elf32_Word sh_addralign;
|
||||||
|
#~ Elf32_Word sh_entsize;
|
||||||
|
#~ } Elf32_Shdr;
|
||||||
|
|
||||||
|
#~ typedef struct {
|
||||||
|
#~ Elf32_Word p_type;
|
||||||
|
#~ Elf32_Off p_offset;
|
||||||
|
#~ Elf32_Addr p_vaddr;
|
||||||
|
#~ Elf32_Addr p_paddr;
|
||||||
|
#~ Elf32_Word p_filesz;
|
||||||
|
#~ Elf32_Word p_memsz;
|
||||||
|
#~ Elf32_Word p_flags;
|
||||||
|
#~ Elf32_Word p_align;
|
||||||
|
#~ } Elf32_Phdr;
|
||||||
|
|
||||||
|
|
||||||
|
class ELFException(Exception): pass
|
||||||
|
|
||||||
|
class ELFSection:
|
||||||
|
"""read and store a section"""
|
||||||
|
Elf32_Shdr = "<IIIIIIIIII" #header format
|
||||||
|
|
||||||
|
#section types
|
||||||
|
SHT_NULL = 0
|
||||||
|
SHT_PROGBITS = 1
|
||||||
|
SHT_SYMTAB = 2
|
||||||
|
SHT_STRTAB = 3
|
||||||
|
SHT_RELA = 4
|
||||||
|
SHT_HASH = 5
|
||||||
|
SHT_DYNAMIC = 6
|
||||||
|
SHT_NOTE = 7
|
||||||
|
SHT_NOBITS = 8
|
||||||
|
SHT_REL = 9
|
||||||
|
SHT_SHLIB = 10
|
||||||
|
SHT_DYNSYM = 11
|
||||||
|
SHT_LOPROC = 0x70000000L
|
||||||
|
SHT_HIPROC = 0x7fffffffL
|
||||||
|
SHT_LOUSER = 0x80000000L
|
||||||
|
SHT_HIUSER = 0xffffffffL
|
||||||
|
#section attribute flags
|
||||||
|
SHF_WRITE = 0x1
|
||||||
|
SHF_ALLOC = 0x2
|
||||||
|
SHF_EXECINSTR = 0x4
|
||||||
|
SHF_MASKPROC = 0xf0000000
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
"""creat a new empty section object"""
|
||||||
|
(self.sh_name, self.sh_type, self.sh_flags, self.sh_addr,
|
||||||
|
self.sh_offset, self.sh_size, self.sh_link, self.sh_info,
|
||||||
|
self.sh_addralign, self.sh_entsize) = [0]*10
|
||||||
|
self.name = None
|
||||||
|
self.data = None
|
||||||
|
self.lma = None
|
||||||
|
|
||||||
|
def fromString(self, s):
|
||||||
|
"""get section header from string"""
|
||||||
|
(self.sh_name, self.sh_type, self.sh_flags, self.sh_addr,
|
||||||
|
self.sh_offset, self.sh_size, self.sh_link, self.sh_info,
|
||||||
|
self.sh_addralign, self.sh_entsize) = struct.unpack(self.Elf32_Shdr, s)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""pretty print for debug..."""
|
||||||
|
return "%s(%s, sh_type=%s, sh_flags=%s, "\
|
||||||
|
"sh_addr=0x%04x, sh_offset=0x%04x, sh_size=%s, sh_link=%s, "\
|
||||||
|
"sh_info=%s, sh_addralign=%s, sh_entsize=%s, lma=0x%04x)" % (
|
||||||
|
self.__class__.__name__,
|
||||||
|
self.name is not None and "%r" % self.name or "sh_name=%s" % self.sh_name,
|
||||||
|
self.sh_type, self.sh_flags, self.sh_addr,
|
||||||
|
self.sh_offset, self.sh_size, self.sh_link, self.sh_info,
|
||||||
|
self.sh_addralign, self.sh_entsize, self.lma)
|
||||||
|
|
||||||
|
class ELFProgramHeader:
|
||||||
|
"""Store and parse a program header"""
|
||||||
|
Elf32_Phdr = "<IIIIIIII" #header format
|
||||||
|
|
||||||
|
#segmet types
|
||||||
|
PT_NULL = 0
|
||||||
|
PT_LOAD = 1
|
||||||
|
PT_DYNAMIC = 2
|
||||||
|
PT_INTERP = 3
|
||||||
|
PT_NOTE = 4
|
||||||
|
PT_SHLIB = 5
|
||||||
|
PT_PHDR = 6
|
||||||
|
PT_LOPROC = 0x70000000L
|
||||||
|
PT_HIPROC = 0x7fffffffL
|
||||||
|
|
||||||
|
#segment flags
|
||||||
|
PF_R = 0x4 #segment is readable
|
||||||
|
PF_W = 0x2 #segment is writable
|
||||||
|
PF_X = 0x1 #segment is executable
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
"""create a new, empty segment/program header"""
|
||||||
|
(self.p_type, self.p_offset, self.p_vaddr, self.p_paddr,
|
||||||
|
self.p_filesz, self.p_memsz, self.p_flags, self.p_align) = [0]*8
|
||||||
|
self.data = None
|
||||||
|
|
||||||
|
def fromString(self, s):
|
||||||
|
"""parse header info from string"""
|
||||||
|
(self.p_type, self.p_offset, self.p_vaddr, self.p_paddr,
|
||||||
|
self.p_filesz, self.p_memsz, self.p_flags,
|
||||||
|
self.p_align) = struct.unpack(self.Elf32_Phdr, s)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""pretty print for debug..."""
|
||||||
|
return "%s(p_type=%s, p_offset=0x%04x, p_vaddr=0x%04x, p_paddr=0x%04x, "\
|
||||||
|
"p_filesz=%s, p_memsz=%s, p_flags=%s, "\
|
||||||
|
"p_align=%s)" % (
|
||||||
|
self.__class__.__name__,
|
||||||
|
self.p_type, self.p_offset, self.p_vaddr, self.p_paddr,
|
||||||
|
self.p_filesz, self.p_memsz, self.p_flags,
|
||||||
|
self.p_align)
|
||||||
|
|
||||||
|
class ELFObject:
|
||||||
|
"""Object to read and handle an LEF object file"""
|
||||||
|
#header information
|
||||||
|
Elf32_Ehdr = "<16sHHIIIIIHHHHHH"
|
||||||
|
|
||||||
|
#offsets within e_ident
|
||||||
|
EI_MAG0 = 0 #File identification
|
||||||
|
EI_MAG1 = 1 #File identification
|
||||||
|
EI_MAG2 = 2 #File identification
|
||||||
|
EI_MAG3 = 3 #File identification
|
||||||
|
EI_CLASS = 4 #File class
|
||||||
|
EI_DATA = 5 #Data encoding
|
||||||
|
EI_VERSION = 6 #File version
|
||||||
|
EI_PAD = 7 #Start of padding bytes
|
||||||
|
EI_NIDENT = 16 #Size of e_ident[]
|
||||||
|
#elf file type flags
|
||||||
|
ET_NONE = 0 #No file type
|
||||||
|
ET_REL = 1 #Relocatable file
|
||||||
|
ET_EXEC = 2 #Executable file
|
||||||
|
ET_DYN = 3 #Shared object file
|
||||||
|
ET_CORE = 4 #Core file
|
||||||
|
ET_LOPROC = 0xff00 #Processor-specific
|
||||||
|
ET_HIPROC = 0xffff #Processor-specific
|
||||||
|
#ELF format
|
||||||
|
ELFCLASSNONE = 0 #Invalid class
|
||||||
|
ELFCLASS32 = 1 #32-bit objects
|
||||||
|
ELFCLASS64 = 2 #64-bit objects
|
||||||
|
#encoding
|
||||||
|
ELFDATANONE = 0 #Invalid data encoding
|
||||||
|
ELFDATA2LSB = 1 #See below
|
||||||
|
ELFDATA2MSB = 2 #See below
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
"""create a new elf object"""
|
||||||
|
(self.e_ident, self.e_type, self.e_machine, self.e_version,
|
||||||
|
self.e_entry, self.e_phoff, self.e_shoff,
|
||||||
|
self.e_flags, self.e_ehsize, self.e_phentsize, self.e_phnum,
|
||||||
|
self.e_shentsize, self.e_shnum, self.e_shstrndx) = [0]*14
|
||||||
|
|
||||||
|
def fromFile(self, fileobj):
|
||||||
|
"""read all relevant data from fileobj.
|
||||||
|
the file must be seekable"""
|
||||||
|
#get file header
|
||||||
|
(self.e_ident, self.e_type, self.e_machine, self.e_version,
|
||||||
|
self.e_entry, self.e_phoff, self.e_shoff,
|
||||||
|
self.e_flags, self.e_ehsize, self.e_phentsize, self.e_phnum,
|
||||||
|
self.e_shentsize, self.e_shnum, self.e_shstrndx) = struct.unpack(
|
||||||
|
self.Elf32_Ehdr, fileobj.read(struct.calcsize(self.Elf32_Ehdr)))
|
||||||
|
#verify if its a known format and realy an ELF file
|
||||||
|
if self.e_ident[0:4] != '\x7fELF' and\
|
||||||
|
self.e_ident[self.EI_CLASS] != self.ELFCLASS32 and\
|
||||||
|
self.e_ident[self.EI_DATA] != self.ELFDATA2LSB and\
|
||||||
|
self.e_ident[self.EI_VERSION] != 1:
|
||||||
|
raise ELFException("Not a valid ELF file")
|
||||||
|
|
||||||
|
#load programm headers
|
||||||
|
self.programmheaders = []
|
||||||
|
if self.e_phnum:
|
||||||
|
#load program headers
|
||||||
|
fileobj.seek(self.e_phoff)
|
||||||
|
for sectionnum in range(self.e_phnum):
|
||||||
|
shdr = (fileobj.read(self.e_phentsize) + '\0'* struct.calcsize(ELFProgramHeader.Elf32_Phdr))[0:struct.calcsize(ELFProgramHeader.Elf32_Phdr)]
|
||||||
|
psection = ELFProgramHeader()
|
||||||
|
psection.fromString(shdr)
|
||||||
|
if psection.p_offset: #skip if section has invalid offset in file
|
||||||
|
self.programmheaders.append(psection)
|
||||||
|
#~ #get the segment data from the file for each prg header
|
||||||
|
#~ for phdr in self.programmheaders:
|
||||||
|
#~ fileobj.seek(phdr.p_offset)
|
||||||
|
#~ phdr.data = fileobj.read(phdr.p_filesz)
|
||||||
|
#~ #pad if needed
|
||||||
|
#~ if phdr.p_filesz < phdr.p_memsz:
|
||||||
|
#~ phdr.data = phdr.data + '\0' * (phdr.p_memsz-phdr.p_filesz)
|
||||||
|
|
||||||
|
#load sections
|
||||||
|
self.sections = []
|
||||||
|
fileobj.seek(self.e_shoff)
|
||||||
|
for sectionnum in range(self.e_shnum):
|
||||||
|
shdr = (fileobj.read(self.e_shentsize) + '\0'* struct.calcsize(ELFSection.Elf32_Shdr))[0:struct.calcsize(ELFSection.Elf32_Shdr)]
|
||||||
|
elfsection = ELFSection()
|
||||||
|
elfsection.fromString(shdr)
|
||||||
|
self.sections.append(elfsection)
|
||||||
|
|
||||||
|
#load data for all sections
|
||||||
|
for section in self.sections:
|
||||||
|
fileobj.seek(section.sh_offset)
|
||||||
|
data = fileobj.read(section.sh_size)
|
||||||
|
section.data = data
|
||||||
|
if section.sh_type == ELFSection.SHT_STRTAB:
|
||||||
|
section.values = data.split('\0')
|
||||||
|
section.lma = self.getLMA(section)
|
||||||
|
|
||||||
|
#get section names
|
||||||
|
for section in self.sections:
|
||||||
|
start = self.sections[self.e_shstrndx].data[section.sh_name:]
|
||||||
|
section.name = start.split('\0')[0]
|
||||||
|
|
||||||
|
def getSection(self, name):
|
||||||
|
"""get section by name"""
|
||||||
|
for section in self.sections:
|
||||||
|
if section.name == '.text':
|
||||||
|
return section
|
||||||
|
|
||||||
|
def getProgrammableSections(self):
|
||||||
|
"""get all program headers that are marked as executable and
|
||||||
|
have suitable attributes to be code"""
|
||||||
|
res = []
|
||||||
|
for p in self.programmheaders:
|
||||||
|
#~ print p
|
||||||
|
#~ if section.sh_flags & self.SHF_ALLOC and section.name not in ('.data', '.data1', '.bss'):
|
||||||
|
#~ if p.p_type == ELFProgramHeader.PT_LOAD:# and p.p_paddr == p.p_vaddr and p.p_flags & ELFProgramHeader.PF_X:
|
||||||
|
if p.p_type == ELFProgramHeader.PT_LOAD:
|
||||||
|
res.append(p)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def getLMA(self, section):
|
||||||
|
#magic load memory address calculation ;-)
|
||||||
|
for p in self.programmheaders:
|
||||||
|
if (p.p_paddr != 0 and \
|
||||||
|
p.p_type == ELFProgramHeader.PT_LOAD and \
|
||||||
|
p.p_vaddr != p.p_paddr and \
|
||||||
|
p.p_vaddr <= section.sh_addr and \
|
||||||
|
(p.p_vaddr + p.p_memsz >= section.sh_addr + section.sh_size) \
|
||||||
|
and (not (section.sh_flags & ELFSection.SHF_ALLOC and section.sh_type != ELFSection.SHT_NOBITS) \
|
||||||
|
or (p.p_offset <= section.sh_offset \
|
||||||
|
and (p.p_offset + p.p_filesz >= section.sh_offset + section.sh_size)))):
|
||||||
|
return section.sh_addr + p.p_paddr - p.p_vaddr
|
||||||
|
return section.sh_addr
|
||||||
|
|
||||||
|
def getSections(self):
|
||||||
|
"""get sections relevant for the application"""
|
||||||
|
res = []
|
||||||
|
for section in self.sections:
|
||||||
|
if section.sh_flags & ELFSection.SHF_ALLOC and section.sh_type != ELFSection.SHT_NOBITS:
|
||||||
|
res.append(section)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""pretty print for debug..."""
|
||||||
|
return "%s(self.e_type=%r, self.e_machine=%r, self.e_version=%r, sections=%r)" % (
|
||||||
|
self.__class__.__name__,
|
||||||
|
self.e_type, self.e_machine, self.e_version,
|
||||||
|
[section.name for section in self.sections])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print "This is only a module test!"
|
||||||
|
elf = ELFObject()
|
||||||
|
elf.fromFile(open("test.elf"))
|
||||||
|
if elf.e_type != ELFObject.ET_EXEC:
|
||||||
|
raise Exception("No executable")
|
||||||
|
print elf
|
||||||
|
|
||||||
|
#~ print repr(elf.getSection('.text').data)
|
||||||
|
#~ print [(s.name, hex(s.sh_addr)) for s in elf.getSections()]
|
||||||
|
print "-"*20
|
||||||
|
for p in elf.sections: print p
|
||||||
|
print "-"*20
|
||||||
|
for p in elf.getSections(): print p
|
||||||
|
print "-"*20
|
||||||
|
for p in elf.getProgrammableSections(): print p
|
49
cpu/msp430/buildscripts/jtag/pyjtag/gen-ihex.py
Normal file
49
cpu/msp430/buildscripts/jtag/pyjtag/gen-ihex.py
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""Test File generator.
|
||||||
|
This tool generates a hex file, of given size, ending on address
|
||||||
|
0xffff.
|
||||||
|
|
||||||
|
USAGE: hen-ihex.py size_in_kilobyte
|
||||||
|
|
||||||
|
The resulting Intel-hex file is output to stdout, use redirection
|
||||||
|
to save the data to a file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
#return a string with data in intel hex format
|
||||||
|
def makeihex(address, data):
|
||||||
|
out = []
|
||||||
|
start = 0
|
||||||
|
while start<len(data):
|
||||||
|
end = start + 16
|
||||||
|
if end > len(data): end = len(data)
|
||||||
|
out.append(_ihexline(address, [ord(x) for x in data[start:end]]))
|
||||||
|
start += 16
|
||||||
|
address += 16
|
||||||
|
out.append(_ihexline(address, [], end=1)) #append no data but an end line
|
||||||
|
return ''.join(out)
|
||||||
|
|
||||||
|
def _ihexline(address, buffer, end=0):
|
||||||
|
out = []
|
||||||
|
if end:
|
||||||
|
type = 1
|
||||||
|
else:
|
||||||
|
type = 0
|
||||||
|
out.append( ':%02X%04X%02X' % (len(buffer),address&0xffff,type) )
|
||||||
|
sum = len(buffer) + ((address>>8)&255) + (address&255)
|
||||||
|
for b in buffer:
|
||||||
|
if b == None: b = 0 #substitute nonexistent values with zero
|
||||||
|
out.append('%02X' % (b&255) )
|
||||||
|
sum += b&255
|
||||||
|
out.append('%02X\n' %( (-sum)&255))
|
||||||
|
return ''.join(out)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import struct, sys
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print __doc__
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
size = int(sys.argv[1]) #in kilo
|
||||||
|
startadr = 0x10000 - 1024*size
|
||||||
|
data = ''.join([struct.pack(">H", x) for x in range(startadr, startadr+ 1024*size, 2)])
|
||||||
|
print makeihex(startadr, data)
|
108
cpu/msp430/buildscripts/jtag/pyjtag/install-pyjtag.nsi
Normal file
108
cpu/msp430/buildscripts/jtag/pyjtag/install-pyjtag.nsi
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
Name "install-pyjtag"
|
||||||
|
OutFile "install-pyjtag.exe"
|
||||||
|
|
||||||
|
!define SF_SELECTED 1
|
||||||
|
!define SF_SUBSEC 2
|
||||||
|
!define SF_SUBSECEND 4
|
||||||
|
!define SF_BOLD 8
|
||||||
|
!define SF_RO 16
|
||||||
|
!define SF_EXPAND 32
|
||||||
|
|
||||||
|
!define SECTION_OFF 0xFFFFFFFE
|
||||||
|
|
||||||
|
LicenseText License
|
||||||
|
LicenseData license.txt
|
||||||
|
|
||||||
|
SetOverwrite on
|
||||||
|
SetDateSave on
|
||||||
|
|
||||||
|
; The default installation directory
|
||||||
|
InstallDir $PROGRAMFILES\mspgcc
|
||||||
|
; Registry key to check for directory (so if you install again, it will
|
||||||
|
; overwrite the old one automatically)
|
||||||
|
InstallDirRegKey HKLM SOFTWARE\mspgcc "rootdir"
|
||||||
|
|
||||||
|
; The text to prompt the user to enter a directory
|
||||||
|
DirText "This will install the pyjtag executables. You can choose the same \
|
||||||
|
directory as for the other mspgcc tools."
|
||||||
|
|
||||||
|
; The text to prompt the user to enter a directory
|
||||||
|
ComponentText "Select which optional things you want installed."
|
||||||
|
|
||||||
|
Section "msp430-jtag (required)"
|
||||||
|
SectionIn RO
|
||||||
|
SetOutPath $INSTDIR
|
||||||
|
|
||||||
|
File /r bin
|
||||||
|
File /oname=license-pyjtag.txt license.txt
|
||||||
|
File /oname=readme-pyjtag.txt readme.txt
|
||||||
|
File /oname=bin\jtag.py jtag.py
|
||||||
|
|
||||||
|
; Write the installation path into the registry
|
||||||
|
WriteRegStr HKLM SOFTWARE\mspgcc "rootdir" "$INSTDIR"
|
||||||
|
; Write the uninstall keys for Windows
|
||||||
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\mspgcc-pyjtag" "DisplayName" "mspgcc pyjtag (remove only)"
|
||||||
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\mspgcc-pyjtag" "UninstallString" '"$INSTDIR\uninstall-pyjtag.exe"'
|
||||||
|
WriteUninstaller "uninstall-pyjtag.exe"
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
|
Section "giveio (needed on Win NT/2k/XP, but NOT on 9x/ME)"
|
||||||
|
SetOutPath $INSTDIR\bin
|
||||||
|
File ..\jtag\hardware_access\giveio\giveio.sys
|
||||||
|
File ..\jtag\hardware_access\giveio\loaddrv.exe
|
||||||
|
SetOutPath $INSTDIR
|
||||||
|
nsExec::ExecToLog '$INSTDIR\bin\loaddrv.exe install giveio $INSTDIR\bin\giveio.sys'
|
||||||
|
Pop $0 ;return value/error/timeout
|
||||||
|
IntCmp $0 2 ext_here ;assume its alredy installed
|
||||||
|
IntCmp $0 0 0 ext_err ext_err ;if not 0 -> error
|
||||||
|
nsExec::ExecToLog '$INSTDIR\bin\loaddrv.exe start giveio'
|
||||||
|
Pop $0 ;return value/error/timeout
|
||||||
|
IntCmp $0 0 0 ext_err ext_err ;if not 0 -> error
|
||||||
|
nsExec::ExecToLog '$INSTDIR\bin\loaddrv.exe starttype giveio auto'
|
||||||
|
Pop $0 ;return value/error/timeout
|
||||||
|
IntCmp $0 0 0 ext_err ext_err ;if not 0 -> error
|
||||||
|
WriteRegStr HKLM SOFTWARE\mspgcc "giveio" "started"
|
||||||
|
Goto ext_ok
|
||||||
|
ext_err:
|
||||||
|
DetailPrint "Error while installing and starting giveio"
|
||||||
|
MessageBox MB_OK|MB_ICONSTOP "Error while installing and starting giveio"
|
||||||
|
Goto ext_ok
|
||||||
|
ext_here:
|
||||||
|
DetailPrint "Installing giveio gave an error, assuming its already installed"
|
||||||
|
ext_ok:
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
|
; special uninstall section.
|
||||||
|
Section "Uninstall"
|
||||||
|
; remove registry keys
|
||||||
|
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\mspgcc-pyjtag"
|
||||||
|
DeleteRegKey HKLM SOFTWARE\NSIS_Example2
|
||||||
|
; remove files
|
||||||
|
Delete $INSTDIR\bin\msp430-jtag.exe
|
||||||
|
Delete $INSTDIR\bin\_parjtag.pyd
|
||||||
|
Delete $INSTDIR\bin\jtag.py
|
||||||
|
Delete $INSTDIR\bin\HIL.dll
|
||||||
|
Delete $INSTDIR\bin\MSP430mspgcc.dll
|
||||||
|
;XXX python22.dll is left installed as it is used by pybsl and other tools
|
||||||
|
Delete $INSTDIR\license-pyjtag.txt
|
||||||
|
Delete $INSTDIR\readme-pyjtag.txt
|
||||||
|
; giveio
|
||||||
|
; if it was started by us, stop it
|
||||||
|
ReadRegStr $0 HKLM SOFTWARE\mspgcc "giveio"
|
||||||
|
StrCmp $0 '' no_giveio
|
||||||
|
nsExec::ExecToLog '$INSTDIR\bin\loaddrv.exe stop giveio'
|
||||||
|
Pop $0 ;return value/error/timeout
|
||||||
|
IntCmp $0 0 0 giveio_err giveio_err ;if not 0 -> error
|
||||||
|
nsExec::ExecToLog '$INSTDIR\bin\loaddrv.exe remove giveio'
|
||||||
|
Pop $0 ;return value/error/timeout
|
||||||
|
IntCmp $0 0 0 giveio_err giveio_err ;if not 0 -> error
|
||||||
|
Goto no_giveio
|
||||||
|
giveio_err:
|
||||||
|
DetailPrint "Error while uninstalling giveio service"
|
||||||
|
MessageBox MB_OK|MB_ICONSTOP "Error while uninstalling giveio service"
|
||||||
|
no_giveio:
|
||||||
|
Delete loaddrv.exe
|
||||||
|
Delete giveio.sys
|
||||||
|
; MUST REMOVE UNINSTALLER, too
|
||||||
|
Delete $INSTDIR\uninstall-pyjtag.exe
|
||||||
|
SectionEnd
|
604
cpu/msp430/buildscripts/jtag/pyjtag/jtag.py
Executable file
604
cpu/msp430/buildscripts/jtag/pyjtag/jtag.py
Executable file
|
@ -0,0 +1,604 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#Parallel JTAG programmer for the MSP430 embedded proccessor.
|
||||||
|
#
|
||||||
|
#(C) 2002 Chris Liechti <cliechti@gmx.net>
|
||||||
|
#this is distributed under a free software license, see license.txt
|
||||||
|
#
|
||||||
|
#Requires Python 2+ and the binary extension _parjtag.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import _parjtag
|
||||||
|
|
||||||
|
VERSION = "1.3"
|
||||||
|
|
||||||
|
DEBUG = 0 #disable debug messages by default
|
||||||
|
|
||||||
|
|
||||||
|
#frame specific consts
|
||||||
|
ERASE_MASS = 2
|
||||||
|
ERASE_MAIN = 1
|
||||||
|
ERASE_SGMT = 0
|
||||||
|
|
||||||
|
#states
|
||||||
|
FREERUNNING = 0
|
||||||
|
STOPPED = 1
|
||||||
|
|
||||||
|
#Configurations of the MSP430 driver
|
||||||
|
VERIFICATION_MODE = 0 #Verify data downloaded to FLASH memories.
|
||||||
|
RAMSIZE_OPTION = 1 #Change RAM used to download and program flash blocks
|
||||||
|
DEBUG_OPTION = 2 #Set debug level. Enables debug outputs.
|
||||||
|
|
||||||
|
#enumeration of output formats for uploads
|
||||||
|
HEX = 0
|
||||||
|
INTELHEX = 1
|
||||||
|
BINARY = 2
|
||||||
|
|
||||||
|
#exceptions
|
||||||
|
class JTAGException(Exception): pass
|
||||||
|
|
||||||
|
#for the use with memread
|
||||||
|
def hexdump( (adr, memstr) ):
|
||||||
|
"""Print a hex dump of data collected with memread
|
||||||
|
arg1: tuple with adress, memory
|
||||||
|
return None"""
|
||||||
|
count = 0
|
||||||
|
ascii = ''
|
||||||
|
for value in map(ord, memstr):
|
||||||
|
if not count: print "%04x: " % adr,
|
||||||
|
print "%02x" % value,
|
||||||
|
ascii += (32 <= value < 128) and chr(value) or '.'
|
||||||
|
count += 1
|
||||||
|
adr += 1
|
||||||
|
if count == 16:
|
||||||
|
count = 0
|
||||||
|
print " ", ascii
|
||||||
|
ascii = ''
|
||||||
|
if count < 16: print " "*(16-count), " ", ascii
|
||||||
|
|
||||||
|
def makeihex( (address, data) ):
|
||||||
|
"""work though the data and output lines in inzel hex format.
|
||||||
|
and end tag is appended"""
|
||||||
|
start = 0
|
||||||
|
while start<len(data):
|
||||||
|
end = start + 16
|
||||||
|
if end > len(data): end = len(data)
|
||||||
|
_ihexline(address, [ord(x) for x in data[start:end]])
|
||||||
|
start += 16
|
||||||
|
address += 16
|
||||||
|
_ihexline(address, [], type=1) #append no data but an end line
|
||||||
|
|
||||||
|
def _ihexline(address, buffer, type=0):
|
||||||
|
"""encode one line, output with checksum"""
|
||||||
|
sys.stdout.write( ':%02X%04X%02X' % (len(buffer), address & 0xffff, type) )
|
||||||
|
sum = len(buffer) + ((address >> 8) & 255) + (address & 255)
|
||||||
|
for b in buffer:
|
||||||
|
if b == None: b = 0 #substitute nonexistent values with zero
|
||||||
|
sys.stdout.write('%02X' % (b & 255))
|
||||||
|
sum += b&255
|
||||||
|
sys.stdout.write('%02X\n' %( (-sum) & 255))
|
||||||
|
|
||||||
|
|
||||||
|
class Segment:
|
||||||
|
"""store a string with memory contents along with its startaddress"""
|
||||||
|
def __init__(self, startaddress = 0, data=None):
|
||||||
|
if data is None:
|
||||||
|
self.data = ''
|
||||||
|
else:
|
||||||
|
self.data = data
|
||||||
|
self.startaddress = startaddress
|
||||||
|
|
||||||
|
def __getitem__(self, index):
|
||||||
|
return self.data[index]
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.data)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "Segment(startaddress = 0x%04x, data=%r)" % (self.startaddress, self.data)
|
||||||
|
|
||||||
|
class Memory:
|
||||||
|
"""represent memory contents. with functions to load files"""
|
||||||
|
def __init__(self, filename=None):
|
||||||
|
self.segments = []
|
||||||
|
if filename:
|
||||||
|
self.filename = filename
|
||||||
|
self.loadFile(filename)
|
||||||
|
|
||||||
|
def append(self, seg):
|
||||||
|
self.segments.append(seg)
|
||||||
|
|
||||||
|
def __getitem__(self, index):
|
||||||
|
return self.segments[index]
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.segments)
|
||||||
|
|
||||||
|
def loadIHex(self, file):
|
||||||
|
"""load data from a (opened) file in Intel-HEX format"""
|
||||||
|
segmentdata = []
|
||||||
|
currentAddr = 0
|
||||||
|
startAddr = 0
|
||||||
|
lines = file.readlines()
|
||||||
|
for l in lines:
|
||||||
|
if not l.strip(): continue #skip empty lines
|
||||||
|
if l[0] != ':': raise Exception("File Format Error\n")
|
||||||
|
l = l.strip() #fix CR-LF issues...
|
||||||
|
length = int(l[1:3],16)
|
||||||
|
address = int(l[3:7],16)
|
||||||
|
type = int(l[7:9],16)
|
||||||
|
check = int(l[-2:],16)
|
||||||
|
if type == 0x00:
|
||||||
|
if currentAddr != address:
|
||||||
|
if segmentdata:
|
||||||
|
self.segments.append( Segment(startAddr, ''.join(segmentdata)) )
|
||||||
|
startAddr = currentAddr = address
|
||||||
|
segmentdata = []
|
||||||
|
for i in range(length):
|
||||||
|
segmentdata.append( chr(int(l[9+2*i:11+2*i],16)) )
|
||||||
|
currentAddr = length + currentAddr
|
||||||
|
elif type == 0x01:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
sys.stderr.write("Ignored unknown field (type 0x%02x) in ihex file.\n" % type)
|
||||||
|
if segmentdata:
|
||||||
|
self.segments.append( Segment(startAddr, ''.join(segmentdata)) )
|
||||||
|
|
||||||
|
def loadTIText(self, file):
|
||||||
|
"""load data from a (opened) file in TI-Text format"""
|
||||||
|
next = 1
|
||||||
|
currentAddr = 0
|
||||||
|
startAddr = 0
|
||||||
|
segmentdata = []
|
||||||
|
#Convert data for MSP430, TXT-File is parsed line by line
|
||||||
|
while next >= 1:
|
||||||
|
#Read one line
|
||||||
|
l = file.readline()
|
||||||
|
if not l: break #EOF
|
||||||
|
l = l.strip()
|
||||||
|
if l[0] == 'q': break
|
||||||
|
elif l[0] == '@': #if @ => new address => send frame and set new addr.
|
||||||
|
#create a new segment
|
||||||
|
if segmentdata:
|
||||||
|
self.segments.append( Segment(startAddr, ''.join(segmentdata)) )
|
||||||
|
startAddr = currentAddr = int(l[1:],16)
|
||||||
|
segmentdata = []
|
||||||
|
else:
|
||||||
|
for i in l.split():
|
||||||
|
segmentdata.append(chr(int(i,16)))
|
||||||
|
if segmentdata:
|
||||||
|
self.segments.append( Segment(startAddr, ''.join(segmentdata)) )
|
||||||
|
|
||||||
|
def loadELF(self, file):
|
||||||
|
"""load data from a (opened) file in ELF object format.
|
||||||
|
File must be seekable"""
|
||||||
|
import elf
|
||||||
|
obj = elf.ELFObject()
|
||||||
|
obj.fromFile(file)
|
||||||
|
if obj.e_type != elf.ELFObject.ET_EXEC:
|
||||||
|
raise Exception("No executable")
|
||||||
|
for section in obj.getSections():
|
||||||
|
if DEBUG:
|
||||||
|
sys.stderr.write("ELF section %s at 0x%04x %d bytes\n" % (section.name, section.lma, len(section.data)))
|
||||||
|
if len(section.data):
|
||||||
|
self.segments.append( Segment(section.lma, section.data) )
|
||||||
|
|
||||||
|
def loadFile(self, filename):
|
||||||
|
"""fill memory with the contents of a file. file type is determined from extension"""
|
||||||
|
#TODO: do a contents based detection
|
||||||
|
if filename[-4:].lower() == '.txt':
|
||||||
|
self.loadTIText(open(filename, "rb"))
|
||||||
|
elif filename[-4:].lower() in ('.a43', '.hex'):
|
||||||
|
self.loadIHex(open(filename, "rb"))
|
||||||
|
else:
|
||||||
|
self.loadELF(open(filename, "rb"))
|
||||||
|
|
||||||
|
def getMemrange(self, fromadr, toadr):
|
||||||
|
"""get a range of bytes from the memory. unavailable values are filled with 0xff."""
|
||||||
|
res = ''
|
||||||
|
toadr = toadr + 1 #python indxes are excluding end, so include it
|
||||||
|
while fromadr < toadr:
|
||||||
|
for seg in self.segments:
|
||||||
|
segend = seg.startaddress + len(seg.data)
|
||||||
|
if seg.startaddress <= fromadr and fromadr < segend:
|
||||||
|
if toadr > segend: #not all data in segment
|
||||||
|
catchlength = segend-fromadr
|
||||||
|
else:
|
||||||
|
catchlength = toadr-fromadr
|
||||||
|
res = res + seg.data[fromadr-seg.startaddress : fromadr-seg.startaddress+catchlength]
|
||||||
|
fromadr = fromadr + catchlength #adjust start
|
||||||
|
if len(res) >= toadr-fromadr:
|
||||||
|
break #return res
|
||||||
|
else: #undefined memory is filled with 0xff
|
||||||
|
res = res + chr(255)
|
||||||
|
fromadr = fromadr + 1 #adjust start
|
||||||
|
return res
|
||||||
|
|
||||||
|
class JTAG:
|
||||||
|
"""wrap the _parjtag extension"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.showprogess = 0
|
||||||
|
|
||||||
|
def connect(self, lpt=None):
|
||||||
|
"""connect to specified or default port"""
|
||||||
|
if lpt is None:
|
||||||
|
_parjtag.connect()
|
||||||
|
else:
|
||||||
|
_parjtag.connect(lpt)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
"""release JTAG"""
|
||||||
|
_parjtag.release()
|
||||||
|
|
||||||
|
def uploadData(self, startaddress, size):
|
||||||
|
"""upload a datablock"""
|
||||||
|
if DEBUG > 1: sys.stderr.write("* uploadData()\n")
|
||||||
|
return _parjtag.memread(startaddress, size)
|
||||||
|
|
||||||
|
def actionMassErase(self):
|
||||||
|
"""Erase the flash memory completely (with mass erase command)"""
|
||||||
|
sys.stderr.write("Mass Erase...\n")
|
||||||
|
_parjtag.memerase(ERASE_MASS)
|
||||||
|
|
||||||
|
def actionMainErase(self):
|
||||||
|
"""Erase the MAIN flash memory, leave the INFO mem"""
|
||||||
|
sys.stderr.write("Erase Main Flash...\n")
|
||||||
|
_parjtag.memerase(ERASE_MAIN, 0xfffe)
|
||||||
|
|
||||||
|
def makeActionSegmentErase(self, address):
|
||||||
|
"""Selective segment erase"""
|
||||||
|
class SegmentEraser:
|
||||||
|
def __init__(self, segaddr):
|
||||||
|
self.address = segaddr
|
||||||
|
def __call__(self):
|
||||||
|
sys.stderr.write("Erase Segment @ 0x%04x...\n" % self.address)
|
||||||
|
_parjtag.memerase(ERASE_SGMT, self.address)
|
||||||
|
return SegmentEraser(address)
|
||||||
|
|
||||||
|
def actionEraseCheck(self):
|
||||||
|
"""check the erasure of required flash cells."""
|
||||||
|
sys.stderr.write("Erase Check by file ...\n")
|
||||||
|
if self.data is not None:
|
||||||
|
for seg in self.data:
|
||||||
|
data = _parjtag.memread(seg.startaddress, len(seg.data))
|
||||||
|
if data != '\xff'*len(seg.data): raise JTAGException("Erase check failed")
|
||||||
|
else:
|
||||||
|
raise JTAGException("cannot do erase check against data with not knowing the actual data")
|
||||||
|
|
||||||
|
def progess_update(self, count, total):
|
||||||
|
sys.stderr.write("\r%d%%" % (100*count/total))
|
||||||
|
|
||||||
|
def actionProgram(self):
|
||||||
|
"""program data into flash memory."""
|
||||||
|
if self.data is not None:
|
||||||
|
sys.stderr.write("Program ...\n")
|
||||||
|
if self.showprogess:
|
||||||
|
_parjtag.set_flash_callback(self.progess_update)
|
||||||
|
bytes = 0
|
||||||
|
for seg in self.data:
|
||||||
|
_parjtag.memwrite(seg.startaddress, seg.data)
|
||||||
|
bytes += len(seg.data)
|
||||||
|
if self.showprogess:
|
||||||
|
sys.stderr.write("\r")
|
||||||
|
sys.stderr.write("%i bytes programmed.\n" % bytes)
|
||||||
|
else:
|
||||||
|
raise JTAGException("programming without data not possible")
|
||||||
|
|
||||||
|
def actionVerify(self):
|
||||||
|
"""Verify programmed data"""
|
||||||
|
if self.data is not None:
|
||||||
|
sys.stderr.write("Verify ...\n")
|
||||||
|
for seg in self.data:
|
||||||
|
data = _parjtag.memread(seg.startaddress, len(seg.data))
|
||||||
|
if data != seg.data: raise JTAGException("Verify failed")
|
||||||
|
else:
|
||||||
|
raise JTAGException("verify without data not possible")
|
||||||
|
|
||||||
|
def actionReset(self):
|
||||||
|
"""perform a reset"""
|
||||||
|
sys.stderr.write("Reset device ...\n")
|
||||||
|
_parjtag.reset(0, 0)
|
||||||
|
|
||||||
|
def actionRun(self, address):
|
||||||
|
"""start program at specified address"""
|
||||||
|
raise NotImplementedError
|
||||||
|
#sys.stderr.write("Load PC with 0x%04x ...\n" % address)
|
||||||
|
|
||||||
|
def funclet(self):
|
||||||
|
"""download and start funclet"""
|
||||||
|
sys.stderr.write("Download and execute of funclet...\n")
|
||||||
|
if len(self.data) > 1:
|
||||||
|
raise JTAGException("don't know how to handle multiple segments in funclets")
|
||||||
|
_parjtag.funclet(self.data[0].data)
|
||||||
|
sys.stderr.write("Funclet OK.\n")
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
"""print some help message"""
|
||||||
|
sys.stderr.write("""
|
||||||
|
USAGE: %s [options] [file]
|
||||||
|
Version: %s
|
||||||
|
|
||||||
|
If "-" is specified as file the data is read from the stdinput.
|
||||||
|
A file ending with ".txt" is considered to be in TIText format all
|
||||||
|
other filenames are considered IntelHex.
|
||||||
|
|
||||||
|
General options:
|
||||||
|
-h, --help Show this help screen.
|
||||||
|
-l, --lpt=name Specify an other parallel port.
|
||||||
|
(defaults to LPT1 (/dev/parport0 on unix)
|
||||||
|
-D, --debug Increase level of debug messages. This won't be
|
||||||
|
very useful for the average user...
|
||||||
|
-I, --intelhex Force fileformat to IntelHex
|
||||||
|
-T, --titext Force fileformat to be TIText
|
||||||
|
-f, --funclet The given file is a funclet (a small program to
|
||||||
|
be run in RAM)
|
||||||
|
-R, --ramsize Specify the amont of RAM to be used to program
|
||||||
|
flash (default 256).
|
||||||
|
|
||||||
|
Program Flow Specifiers:
|
||||||
|
|
||||||
|
-e, --masserase Mass Erase (clear all flash memory)
|
||||||
|
-m, --mainerase Erase main flash memory only
|
||||||
|
--eraseinfo Erase info flash memory only (0x1000-0x10ff)
|
||||||
|
--erase=address Selectively erase segment at the specified address
|
||||||
|
-E, --erasecheck Erase Check by file
|
||||||
|
-p, --program Program file
|
||||||
|
-v, --verify Verify by file
|
||||||
|
|
||||||
|
The order of the above options matters! The table is ordered by normal
|
||||||
|
execution order. For the options "Epv" a file must be specified.
|
||||||
|
Program flow specifiers default to "p" if a file is given.
|
||||||
|
Don't forget to specify "e" or "eE" when programming flash!
|
||||||
|
"p" already verifies the programmed data, "v" adds an additional
|
||||||
|
verification though uploading the written data for a 1:1 compare.
|
||||||
|
No default action is taken if "p" and/or "v" is given, say specifying
|
||||||
|
only "v" does a check by file of a programmed device.
|
||||||
|
|
||||||
|
Data retreiving:
|
||||||
|
-u, --upload=addr Upload a datablock (see also: -s).
|
||||||
|
-s, --size=num Size of the data block do upload. (Default is 2)
|
||||||
|
-x, --hex Show a hexadecimal display of the uploaded data.
|
||||||
|
(Default)
|
||||||
|
-b, --bin Get binary uploaded data. This can be used
|
||||||
|
to redirect the output into a file.
|
||||||
|
-i, --ihex Uploaded data is output in Intel HEX format.
|
||||||
|
This can be used to clone a device.
|
||||||
|
|
||||||
|
Do before exit:
|
||||||
|
-g, --go=address Start programm execution at specified address.
|
||||||
|
This implies option "w" (wait)
|
||||||
|
-r, --reset Reset connected MSP430. Starts application.
|
||||||
|
This is a normal device reset and will start
|
||||||
|
the programm that is specified in the reset
|
||||||
|
interrupt vector. (see also -g)
|
||||||
|
-w, --wait Wait for <ENTER> before closing parallel port.
|
||||||
|
""" % (sys.argv[0], VERSION))
|
||||||
|
|
||||||
|
def main():
|
||||||
|
global DEBUG
|
||||||
|
import getopt
|
||||||
|
filetype = None
|
||||||
|
filename = None
|
||||||
|
reset = 0
|
||||||
|
wait = 0
|
||||||
|
goaddr = None
|
||||||
|
jtag = JTAG()
|
||||||
|
toinit = []
|
||||||
|
todo = []
|
||||||
|
startaddr = None
|
||||||
|
size = 2
|
||||||
|
outputformat= HEX
|
||||||
|
lpt = None
|
||||||
|
funclet = None
|
||||||
|
ramsize = None
|
||||||
|
|
||||||
|
sys.stderr.write("MSP430 parallel JTAG programmer Version: %s\n" % VERSION)
|
||||||
|
try:
|
||||||
|
opts, args = getopt.getopt(sys.argv[1:],
|
||||||
|
"hl:weEmpvrg:Du:d:s:xbiITfR:S",
|
||||||
|
["help", "lpt=", "wait"
|
||||||
|
"masserase", "erasecheck", "mainerase", "program",
|
||||||
|
"erase=", "eraseinfo",
|
||||||
|
"verify", "reset", "go=", "debug",
|
||||||
|
"upload=", "download=", "size=", "hex", "bin", "ihex",
|
||||||
|
"intelhex", "titext", "funclet", "ramsize=", "progress"]
|
||||||
|
)
|
||||||
|
except getopt.GetoptError:
|
||||||
|
# print help information and exit:
|
||||||
|
usage()
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
for o, a in opts:
|
||||||
|
if o in ("-h", "--help"):
|
||||||
|
usage()
|
||||||
|
sys.exit()
|
||||||
|
elif o in ("-l", "--lpt"):
|
||||||
|
lpt = a
|
||||||
|
elif o in ("-w", "--wait"):
|
||||||
|
wait = 1
|
||||||
|
elif o in ("-e", "--masserase"):
|
||||||
|
toinit.append(jtag.actionMassErase) #Erase Flash
|
||||||
|
elif o in ("-E", "--erasecheck"):
|
||||||
|
toinit.append(jtag.actionEraseCheck) #Erase Check (by file)
|
||||||
|
elif o in ("-m", "--mainerase"):
|
||||||
|
toinit.append(jtag.actionMainErase) #Erase main Flash
|
||||||
|
elif o == "--erase":
|
||||||
|
try:
|
||||||
|
seg = int(a, 0)
|
||||||
|
toinit.append(jtag.makeActionSegmentErase(seg))
|
||||||
|
except ValueError:
|
||||||
|
sys.stderr.write("segment address must be a valid number in dec, hex or octal\n")
|
||||||
|
sys.exit(2)
|
||||||
|
elif o == "--eraseinfo":
|
||||||
|
toinit.append(jtag.makeActionSegmentErase(0x1000))
|
||||||
|
toinit.append(jtag.makeActionSegmentErase(0x1080))
|
||||||
|
elif o in ("-p", "--program"):
|
||||||
|
todo.append(jtag.actionProgram) #Program file
|
||||||
|
elif o in ("-v", "--verify"):
|
||||||
|
todo.append(jtag.actionVerify) #Verify file
|
||||||
|
elif o in ("-r", "--reset"):
|
||||||
|
reset = 1
|
||||||
|
elif o in ("-g", "--go"):
|
||||||
|
try:
|
||||||
|
goaddr = int(a, 0) #try to convert decimal
|
||||||
|
except ValueError:
|
||||||
|
sys.stderr.write("upload address must be a valid number in dec, hex or octal\n")
|
||||||
|
sys.exit(2)
|
||||||
|
elif o in ("-D", "--debug"):
|
||||||
|
DEBUG = DEBUG + 1
|
||||||
|
elif o in ("-u", "--upload"):
|
||||||
|
try:
|
||||||
|
startaddr = int(a, 0) #try to convert number of any base
|
||||||
|
except ValueError:
|
||||||
|
sys.stderr.write("upload address must be a valid number in dec, hex or octal\n")
|
||||||
|
sys.exit(2)
|
||||||
|
elif o in ("-s", "--size"):
|
||||||
|
try:
|
||||||
|
size = int(a, 0)
|
||||||
|
except ValueError:
|
||||||
|
sys.stderr.write("upload address must be a valid number in dec, hex or octal\n")
|
||||||
|
sys.exit(2)
|
||||||
|
#outut formats
|
||||||
|
elif o in ("-x", "--hex"):
|
||||||
|
outputformat = HEX
|
||||||
|
elif o in ("-b", "--bin"):
|
||||||
|
outputformat = BINARY
|
||||||
|
elif o in ("-i", "--ihex"):
|
||||||
|
outputformat = INTELHEX
|
||||||
|
#input formats
|
||||||
|
elif o in ("-I", "--intelhex"):
|
||||||
|
filetype = 0
|
||||||
|
elif o in ("-T", "--titext"):
|
||||||
|
filetype = 1
|
||||||
|
#others
|
||||||
|
elif o in ("-f", "--funclet"):
|
||||||
|
funclet = 1
|
||||||
|
elif o in ("-R", "--ramsize"):
|
||||||
|
try:
|
||||||
|
ramsize = int(a, 0)
|
||||||
|
except ValueError:
|
||||||
|
sys.stderr.write("ramsize must be a valid number in dec, hex or octal\n")
|
||||||
|
sys.exit(2)
|
||||||
|
elif o in ("-S", "--progress"):
|
||||||
|
jtag.showprogess = 1
|
||||||
|
|
||||||
|
if len(args) == 0:
|
||||||
|
sys.stderr.write("Use -h for help\n")
|
||||||
|
elif len(args) == 1: #a filename is given
|
||||||
|
if not funclet:
|
||||||
|
if not todo: #if there are no actions yet
|
||||||
|
todo.extend([ #add some useful actions...
|
||||||
|
jtag.actionProgram,
|
||||||
|
])
|
||||||
|
filename = args[0]
|
||||||
|
else: #number of args is wrong
|
||||||
|
usage()
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
if DEBUG: #debug infos
|
||||||
|
sys.stderr.write("debug level set to %d\n" % DEBUG)
|
||||||
|
_parjtag.configure(DEBUG_OPTION, DEBUG)
|
||||||
|
sys.stderr.write("python version: %s\n" % sys.version)
|
||||||
|
|
||||||
|
|
||||||
|
#sanity check of options
|
||||||
|
if goaddr and reset:
|
||||||
|
sys.stderr.write("Warning: option --reset ignored as --go is specified!\n")
|
||||||
|
reset = 0
|
||||||
|
|
||||||
|
if startaddr and reset:
|
||||||
|
sys.stderr.write("Warning: option --reset ignored as --upload is specified!\n")
|
||||||
|
reset = 0
|
||||||
|
|
||||||
|
#prepare data to download
|
||||||
|
jtag.data = Memory() #prepare downloaded data
|
||||||
|
if filetype is not None: #if the filetype is given...
|
||||||
|
if filename is None:
|
||||||
|
raise ValueError("no filename but filetype specified")
|
||||||
|
if filename == '-': #get data from stdin
|
||||||
|
file = sys.stdin
|
||||||
|
else:
|
||||||
|
file = open(filename,"rb") #or from a file
|
||||||
|
if filetype == 0: #select load function
|
||||||
|
jtag.data.loadIHex(file) #intel hex
|
||||||
|
elif filetype == 1:
|
||||||
|
jtag.data.loadTIText(file) #TI's format
|
||||||
|
else:
|
||||||
|
raise ValueError("illegal filetype specified")
|
||||||
|
else: #no filetype given...
|
||||||
|
if filename == '-': #for stdin:
|
||||||
|
jtag.data.loadIHex(sys.stdin) #assume intel hex
|
||||||
|
elif filename:
|
||||||
|
jtag.data.loadFile(filename) #autodetect otherwise
|
||||||
|
|
||||||
|
if DEBUG > 5: sys.stderr.write("File: %r\n" % filename)
|
||||||
|
|
||||||
|
try:
|
||||||
|
jtag.connect(lpt) #try to open port
|
||||||
|
except IOError:
|
||||||
|
raise #do not handle here
|
||||||
|
else: #continue if open was successful
|
||||||
|
if ramsize is not None:
|
||||||
|
_parjtag.configure(RAMSIZE_OPTION, ramsize)
|
||||||
|
#initialization list
|
||||||
|
if toinit: #erase and erase check
|
||||||
|
if DEBUG: sys.stderr.write("Preparing device ...\n")
|
||||||
|
for f in toinit: f()
|
||||||
|
|
||||||
|
#work list
|
||||||
|
if todo:
|
||||||
|
if DEBUG > 0: #debug
|
||||||
|
#show a nice list of sheduled actions
|
||||||
|
sys.stderr.write("TODO list:\n")
|
||||||
|
for f in todo:
|
||||||
|
try:
|
||||||
|
sys.stderr.write(" %s\n" % f.func_name)
|
||||||
|
except AttributeError:
|
||||||
|
sys.stderr.write(" %r\n" % f)
|
||||||
|
for f in todo: f() #work through todo list
|
||||||
|
|
||||||
|
if reset: #reset device first if desired
|
||||||
|
jtag.actionReset()
|
||||||
|
|
||||||
|
if funclet is not None: #download and start funclet
|
||||||
|
jtag.funclet()
|
||||||
|
|
||||||
|
if goaddr is not None: #start user programm at specified address
|
||||||
|
jtag.actionRun(goaddr) #load PC and execute
|
||||||
|
|
||||||
|
#upload datablock and output
|
||||||
|
if startaddr is not None:
|
||||||
|
if goaddr: #if a program was started...
|
||||||
|
raise NotImplementedError
|
||||||
|
#TODO:
|
||||||
|
#sys.stderr.write("Waiting to device for reconnect for upload: ")
|
||||||
|
data = jtag.uploadData(startaddr, size) #upload data
|
||||||
|
if outputformat == HEX: #depending on output format
|
||||||
|
hexdump( (startaddr, data) ) #print a hex display
|
||||||
|
elif outputformat == INTELHEX:
|
||||||
|
makeihex( (startaddr, data) ) #ouput a intel-hex file
|
||||||
|
else:
|
||||||
|
sys.stdout.write(data) #binary output w/o newline!
|
||||||
|
wait = 0 #wait makes no sense as after the upload the device is still stopped
|
||||||
|
|
||||||
|
if wait: #wait at the end if desired
|
||||||
|
sys.stderr.write("Press <ENTER> ...\n") #display a prompt
|
||||||
|
raw_input() #wait for newline
|
||||||
|
|
||||||
|
_parjtag.reset(1, 1) #reset and release target
|
||||||
|
#~ jtag.actionReset()
|
||||||
|
jtag.close() #Release communication port
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except SystemExit:
|
||||||
|
raise #let pass exit() calls
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
if DEBUG: raise #show full trace in debug mode
|
||||||
|
sys.stderr.write("user abort.\n") #short messy in user mode
|
||||||
|
sys.exit(1) #set errorlevel for script usage
|
||||||
|
except Exception, msg: #every Exception is caught and displayed
|
||||||
|
if DEBUG: raise #show full trace in debug mode
|
||||||
|
sys.stderr.write("\nAn error occoured:\n%s\n" % msg) #short messy in user mode
|
||||||
|
sys.exit(1) #set errorlevel for script usage
|
62
cpu/msp430/buildscripts/jtag/pyjtag/license.txt
Normal file
62
cpu/msp430/buildscripts/jtag/pyjtag/license.txt
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
Copyright (c) 2001-2002 Chris Liechti <cliechti@gmx.net>
|
||||||
|
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
This is the Python license. In short, you can use this product in
|
||||||
|
commercial and non-commercial applications, modify it, redistribute it.
|
||||||
|
A notification to the author when you use and/or modify it is welcome.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING THIS SOFTWARE
|
||||||
|
============================================
|
||||||
|
|
||||||
|
LICENSE AGREEMENT
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
1. This LICENSE AGREEMENT is between the copyright holder of this
|
||||||
|
product, and the Individual or Organization ("Licensee") accessing
|
||||||
|
and otherwise using this product in source or binary form and its
|
||||||
|
associated documentation.
|
||||||
|
|
||||||
|
2. Subject to the terms and conditions of this License Agreement,
|
||||||
|
the copyright holder hereby grants Licensee a nonexclusive,
|
||||||
|
royalty-free, world-wide license to reproduce, analyze, test,
|
||||||
|
perform and/or display publicly, prepare derivative works, distribute,
|
||||||
|
and otherwise use this product alone or in any derivative version,
|
||||||
|
provided, however, that copyright holders License Agreement and
|
||||||
|
copyright holders notice of copyright are retained in this product
|
||||||
|
alone or in any derivative version prepared by Licensee.
|
||||||
|
|
||||||
|
3. In the event Licensee prepares a derivative work that is based on
|
||||||
|
or incorporates this product or any part thereof, and wants to make
|
||||||
|
the derivative work available to others as provided herein, then
|
||||||
|
Licensee hereby agrees to include in any such work a brief summary of
|
||||||
|
the changes made to this product.
|
||||||
|
|
||||||
|
4. The copyright holder is making this product available to Licensee
|
||||||
|
on an "AS IS" basis. THE COPYRIGHT HOLDER MAKES NO REPRESENTATIONS
|
||||||
|
OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT
|
||||||
|
LIMITATION, THE COPYRIGHT HOLDER MAKES NO AND DISCLAIMS ANY
|
||||||
|
REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||||
|
ANY PARTICULAR PURPOSE OR THAT THE USE OF THIS PRODUCT WILL
|
||||||
|
NOT INFRINGE ANY THIRD PARTY RIGHTS.
|
||||||
|
|
||||||
|
5. THE COPYRIGHT HOLDER SHALL NOT BE LIABLE TO LICENSEE OR ANY
|
||||||
|
OTHER USERS OF THIS PRODUCT FOR ANY INCIDENTAL, SPECIAL, OR
|
||||||
|
CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING,
|
||||||
|
DISTRIBUTING, OR OTHERWISE USING THIS PRODUCT, OR ANY
|
||||||
|
DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
THEREOF.
|
||||||
|
|
||||||
|
6. This License Agreement will automatically terminate upon a
|
||||||
|
material breach of its terms and conditions.
|
||||||
|
|
||||||
|
7. Nothing in this License Agreement shall be deemed to create any
|
||||||
|
relationship of agency, partnership, or joint venture between the
|
||||||
|
copyright holder and Licensee. This License Agreement does not grant
|
||||||
|
permission to use trademarks or trade names from the copyright holder
|
||||||
|
in a trademark sense to endorse or promote products or services of
|
||||||
|
Licensee, or any third party.
|
||||||
|
|
||||||
|
8. By copying, installing or otherwise using this product, Licensee
|
||||||
|
agrees to be bound by the terms and conditions of this License
|
||||||
|
Agreement.
|
33
cpu/msp430/buildscripts/jtag/pyjtag/makefile
Normal file
33
cpu/msp430/buildscripts/jtag/pyjtag/makefile
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
|
||||||
|
.PHONY: all FORCE clean windist
|
||||||
|
|
||||||
|
all: windist
|
||||||
|
|
||||||
|
#wrap py to exe and build windows installer
|
||||||
|
windist:
|
||||||
|
python setup.py py2exe
|
||||||
|
rm -r bin
|
||||||
|
mv dist/jtag/jtag.exe dist/msp430-jtag.exe
|
||||||
|
mv dist/jtag/* dist/
|
||||||
|
rmdir dist/jtag
|
||||||
|
mv dist bin
|
||||||
|
rm -r build
|
||||||
|
|
||||||
|
|
||||||
|
#generate test files
|
||||||
|
fill60k.a43:
|
||||||
|
python gen-ihex.py 60 >$@
|
||||||
|
fill48k.a43:
|
||||||
|
python gen-ihex.py 48 >$@
|
||||||
|
fill32k.a43:
|
||||||
|
python gen-ihex.py 32 >$@
|
||||||
|
fill16k.a43:
|
||||||
|
python gen-ihex.py 16 >$@
|
||||||
|
fill8k.a43:
|
||||||
|
python gen-ihex.py 8 >$@
|
||||||
|
fill4k.a43:
|
||||||
|
python gen-ihex.py 4 >$@
|
||||||
|
|
||||||
|
#clean up the mess...
|
||||||
|
clean:
|
||||||
|
rm -r dist build bin
|
182
cpu/msp430/buildscripts/jtag/pyjtag/readme.txt
Normal file
182
cpu/msp430/buildscripts/jtag/pyjtag/readme.txt
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
pyJTAG
|
||||||
|
------
|
||||||
|
|
||||||
|
Software to talk to the parallel port JTAG PCB as seen with the FET kits.
|
||||||
|
It is released under a free software license,
|
||||||
|
see license.txt for more details.
|
||||||
|
|
||||||
|
(C) 2002-2003 Chris Liechti <cliechti@gmx.net>
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
- understands TI-Text and Intel-hex
|
||||||
|
- download to Flash and/or RAM, erase, verify
|
||||||
|
- reset device
|
||||||
|
- load addres into R0/PC and run
|
||||||
|
- upload a memory block MSP->PC (output as binary data or hex dump)
|
||||||
|
- written in Python, runs on Win32, Linux, BSD
|
||||||
|
- use per command line, or in a Python script
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
- Linux, BSD, Un*x or Windows PC
|
||||||
|
- Python 2.0 or newer, 2.2 recomeded
|
||||||
|
- Parallel JTAG hardware with an MSP430 device connected
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
Python installations are available from www.python.org. On Windows simply
|
||||||
|
use the installer. The win32all package has an installer too. These
|
||||||
|
installations should run fine with the deafults.
|
||||||
|
|
||||||
|
On Linux just Python is needed. On some distributions is Python 1.5.2
|
||||||
|
installed per default. You may meed to change the first line in the script
|
||||||
|
from "python" to "python2". Maybe Python 2.x is in a separate package that
|
||||||
|
has to be installed. There are rpm and deb binary packages and a source
|
||||||
|
tarball available through the Python homepage.
|
||||||
|
|
||||||
|
The pyjtag archive can simply be unpacked to a directory, Windows users
|
||||||
|
can use WinZip or WinRar among others to extract the gzipped tar file.
|
||||||
|
If you want to run it from everywhere the directory where the file jtag.py
|
||||||
|
is, should be added to the PATH.
|
||||||
|
Look at "~/.profile", "/etc/profile" on Linux, "autoexec.bat" on Win9x/ME,
|
||||||
|
System Properties/Environment in Win2000/NT/XP.
|
||||||
|
|
||||||
|
_parjtag.so/dll from the jtag archive must be copied to the same directory as
|
||||||
|
jtag.py. On Windows also MSP430mspgcc.dll and HIL.dll must be located in the
|
||||||
|
same dir or somewhere in the PATH.
|
||||||
|
|
||||||
|
Short introduction
|
||||||
|
------------------
|
||||||
|
This software uses the JTAG hardware that comes with the FET kits. It is
|
||||||
|
connected to the parallel port.
|
||||||
|
|
||||||
|
The program can be started by typing "python jtag.py" in a console. Often
|
||||||
|
it works also with just "jtag.py" or "./jtag.py".
|
||||||
|
|
||||||
|
USAGE: jtag.py [options] [file]
|
||||||
|
If "-" is specified as file the data is read from the stdinput.
|
||||||
|
A file ending with ".txt" is considered to be in TIText format all
|
||||||
|
other filenames are considered IntelHex.
|
||||||
|
|
||||||
|
General options:
|
||||||
|
-h, --help Show this help screen.
|
||||||
|
-l, --lpt=name Specify an other parallel port.
|
||||||
|
(defaults to LPT1 (/dev/parport0 on unix)
|
||||||
|
-D, --debug Increase level of debug messages. This won't be
|
||||||
|
very useful for the average user...
|
||||||
|
-I, --intelhex Force fileformat to IntelHex
|
||||||
|
-T, --titext Force fileformat to be TIText
|
||||||
|
-f, --funclet The given file is a funclet (a small program to
|
||||||
|
be run in RAM)
|
||||||
|
-R, --ramsize Specify the amont of RAM to be used to program
|
||||||
|
flash (default 256).
|
||||||
|
|
||||||
|
Program Flow Specifiers:
|
||||||
|
|
||||||
|
-e, --masserase Mass Erase (clear all flash memory)
|
||||||
|
-m, --mainerase Erase main flash memory only
|
||||||
|
--eraseinfo Erase info flash memory only (0x1000-0x10ff)
|
||||||
|
--erase=address Selectively erase segment at the specified address
|
||||||
|
-E, --erasecheck Erase Check by file
|
||||||
|
-p, --program Program file
|
||||||
|
-v, --verify Verify by file
|
||||||
|
|
||||||
|
The order of the above options matters! The table is ordered by normal
|
||||||
|
execution order. For the options "Epv" a file must be specified.
|
||||||
|
Program flow specifiers default to "p" if a file is given.
|
||||||
|
Don't forget to specify "e" or "eE" when programming flash!
|
||||||
|
"p" already verifies the programmed data, "v" adds an additional
|
||||||
|
verification though uploading the written data for a 1:1 compare.
|
||||||
|
No default action is taken if "p" and/or "v" is given, say specifying
|
||||||
|
only "v" does a check by file of a programmed device.
|
||||||
|
|
||||||
|
Data retreiving:
|
||||||
|
-u, --upload=addr Upload a datablock (see also: -s).
|
||||||
|
-s, --size=num Size of the data block do upload. (Default is 2)
|
||||||
|
-x, --hex Show a hexadecimal display of the uploaded data.
|
||||||
|
(Default)
|
||||||
|
-b, --bin Get binary uploaded data. This can be used
|
||||||
|
to redirect the output into a file.
|
||||||
|
-i, --ihex Uploaded data is output in Intel HEX format.
|
||||||
|
This can be used to clone a device.
|
||||||
|
|
||||||
|
Do before exit:
|
||||||
|
-g, --go=address Start programm execution at specified address.
|
||||||
|
This implies option "w" (wait)
|
||||||
|
-r, --reset Reset connected MSP430. Starts application.
|
||||||
|
This is a normal device reset and will start
|
||||||
|
the programm that is specified in the reset
|
||||||
|
interrupt vector. (see also -g)
|
||||||
|
-w, --wait Wait for <ENTER> before closing parallel port.
|
||||||
|
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
These examples assume that you have added the installation directory to
|
||||||
|
the PATH. Type the full path to jtag.py otherwise and maybe use
|
||||||
|
"python jtag.py". Depending on installation it may also appear under the
|
||||||
|
name "msp430-jtag".
|
||||||
|
|
||||||
|
jtag.py -e
|
||||||
|
Only erase flash.
|
||||||
|
|
||||||
|
jtag.py -eErw 6port.a43
|
||||||
|
Erase flash, erase check, download an executable, run it (reset)
|
||||||
|
and wait.
|
||||||
|
|
||||||
|
jtag.py -mS -R 2048 6port.a43
|
||||||
|
Use ramsize option on a device with 2k RAM to speed up
|
||||||
|
download. Of course any value from 128B up to the maximum
|
||||||
|
a device has is allowed.
|
||||||
|
The progress and mainerase options are also activated.
|
||||||
|
Only erasing the main memory is useful to keep calibration
|
||||||
|
data in the information memory.
|
||||||
|
|
||||||
|
jtag.py 6port.a43
|
||||||
|
Download of an executable to en empty (new or erased) device.
|
||||||
|
(Note that in new devices some of the first bytes in the
|
||||||
|
information memory are random data. If data should be
|
||||||
|
downloaded there, specify -eE.)
|
||||||
|
|
||||||
|
jtag.py --go=0x220 ramtest.a43
|
||||||
|
Download a program into RAM and run it, may not work
|
||||||
|
with all devices.
|
||||||
|
|
||||||
|
jtag.py -f blinking.a43
|
||||||
|
Download a program into RAM and run it. It must be
|
||||||
|
a special format with "startadr", "entrypoint",
|
||||||
|
"exitpoint" as the first three words in the data
|
||||||
|
and it must end on "jmp $". See MSP430debug sources
|
||||||
|
for more info.
|
||||||
|
|
||||||
|
jtag.py -u 0x0c00 -s 1024
|
||||||
|
Get a memory dump in HEX, from the bootstrap loader.
|
||||||
|
or save the binary in a file:
|
||||||
|
"python jtag.py -u 0x0c00 -s 1024 -b >dump.bin"
|
||||||
|
or as an intel-hex file:
|
||||||
|
"python jtag.py -u 0x0c00 -s 1024 -i >dump.a43"
|
||||||
|
|
||||||
|
jtag.py -r
|
||||||
|
Just start the user program (with a reset).
|
||||||
|
|
||||||
|
cat 6port.a43|jtag.py -e -
|
||||||
|
Pipe the data from "cat" to jtag.py to erase and program the
|
||||||
|
flash. (un*x example, don't forget the dash at the end of the
|
||||||
|
line)
|
||||||
|
|
||||||
|
History
|
||||||
|
-------
|
||||||
|
1.0 public release
|
||||||
|
1.1 fix of verify error
|
||||||
|
1.2 use the verification during programming
|
||||||
|
1.3 meinerase, progress options, ihex output
|
||||||
|
|
||||||
|
References
|
||||||
|
----------
|
||||||
|
- Python: http://www.python.org
|
||||||
|
|
||||||
|
- Texas Instruments MSP430 Homepage, links to Datasheets and Application
|
||||||
|
Notes: http://www.ti.com/sc/msp430
|
||||||
|
|
9
cpu/msp430/buildscripts/jtag/pyjtag/setup.py
Normal file
9
cpu/msp430/buildscripts/jtag/pyjtag/setup.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# setup.py
|
||||||
|
from distutils.core import setup
|
||||||
|
import glob
|
||||||
|
import py2exe
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name="msp430-jtag",
|
||||||
|
scripts=["jtag.py"],
|
||||||
|
)
|
Loading…
Reference in a new issue