代码拉取完成,页面将自动刷新
#!/usr/bin/env python3
# stcflash Copyright (C) 2013 laborer ([email protected])
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import time
import logging
import sys
import serial
import os.path
import binascii
import struct
import argparse
PROTOCOL_89 = "89"
PROTOCOL_12C5A = "12c5a"
PROTOCOL_12C52 = "12c52"
PROTOCOL_12Cx052 = "12cx052"
PROTOCOL_15F2K ="15F2K"
PROTOCOL_8F2K ="8F2K"
PROTOSET_89 = [PROTOCOL_89]
PROTOSET_12 = [PROTOCOL_12C5A, PROTOCOL_12C52, PROTOCOL_12Cx052]
PROTOSET_12B = [PROTOCOL_12C52, PROTOCOL_12Cx052]
PROTOSET_PARITY = [PROTOCOL_12C5A, PROTOCOL_12C52]
PROTOSET_15F2K=[PROTOCOL_15F2K ]
PROTOSET_8F2K=[PROTOCOL_8F2K]
class Programmer:
def __init__(self,parent, conn, protocol=None):
self.parent = parent
self.conn = conn
self.protocol = protocol
self.conn.timeout = 0.05
if self.protocol in PROTOSET_PARITY or self.protocol in PROTOSET_15F2K:
self.conn.parity = serial.PARITY_EVEN
else:
self.conn.parity = serial.PARITY_NONE
self.chkmode = 0
def __conn_read(self, size):
buf = bytearray()
while len(buf) < size:
s = bytearray(self.conn.read(size - len(buf)))
buf += s
logging.debug("recv: " + " ".join(["%02X" % i for i in s]))
if len(s) == 0:
raise IOError()
#self.parent.SetTipString("IOError in __conn_read")
return list(buf)
def __conn_write(self, s):
logging.debug("send: " + " ".join(["%02X" % i for i in s]))
self.conn.write(bytearray(s))
def __conn_baudrate(self, baud, flush=True):
logging.debug("baud: %d" % baud)
# 这里特别注意,在芯片工作时发送下载指令,flush 必须为 False,因为不能有延时。
if flush: # 我调试了大半天才找到原因
self.conn.flush()
time.sleep(0.2)
self.conn.baudrate = baud
def __model_database(self, model):
modelmap = {0xE0: ("12", 1, {(0x00, 0x1F): ("C54", ""),
(0x60, 0x7F): ("C54", "AD"),
(0x80, 0x9F): ("LE54", ""),
(0xE0, 0xFF): ("LE54", "AD"),
}),
0xE1: ("12", 1, {(0x00, 0x1F): ("C52", ""),
(0x20, 0x3F): ("C52", "PWM"),
(0x60, 0x7F): ("C52", "AD"),
(0x80, 0x9F): ("LE52", ""),
(0xA0, 0xBF): ("LE52", "PWM"),
(0xE0, 0xFF): ("LE52", "AD"),
}),
0xE2: ("11", 1, {(0x00, 0x1F): ("F", ""),
(0x20, 0x3F): ("F", "E"),
(0x70, 0x7F): ("F", ""),
(0x80, 0x9F): ("L", ""),
(0xA0, 0xBF): ("L", "E"),
(0xF0, 0xFF): ("L", ""),
}),
0xE6: ("12", 1, {(0x00, 0x1F): ("C56", ""),
(0x60, 0x7F): ("C56", "AD"),
(0x80, 0x9F): ("LE56", ""),
(0xE0, 0xFF): ("LE56", "AD"),
}),
0xD1: ("12", 2, {(0x20, 0x3F): ("C5A", "CCP"),
(0x40, 0x5F): ("C5A", "AD"),
(0x60, 0x7F): ("C5A", "S2"),
(0xA0, 0xBF): ("LE5A", "CCP"),
(0xC0, 0xDF): ("LE5A", "AD"),
(0xE0, 0xFF): ("LE5A", "S2"),
}),
0xD2: ("10", 1, {(0x00, 0x0F): ("F", ""),
(0x60, 0x6F): ("F", "XE"),
(0x70, 0x7F): ("F", "X"),
(0xA0, 0xAF): ("L", ""),
(0xE0, 0xEF): ("L", "XE"),
(0xF0, 0xFF): ("L", "X"),
}),
0xD3: ("11", 2, {(0x00, 0x1F): ("F", ""),
(0x40, 0x5F): ("F", "X"),
(0x60, 0x7F): ("F", "XE"),
(0xA0, 0xBF): ("L", ""),
(0xC0, 0xDF): ("L", "X"),
(0xE0, 0xFF): ("L", "XE"),
}),
0xF0: ("89", 4, {(0x00, 0x10): ("C5", "RC"),
(0x20, 0x30): ("C5", "RC"), #STC90C5xRC
}),
0xF1: ("89", 4, {(0x00, 0x10): ("C5", "RD+"),
(0x20, 0x30): ("C5", "RD+"), #STC90C5xRD+
}),
0xF2: ("12", 1, {(0x00, 0x0F): ("C", "052"),
(0x10, 0x1F): ("C", "052AD"),
(0x20, 0x2F): ("LE", "052"),
(0x30, 0x3F): ("LE", "052AD"),
}),
0xF4: ("15", 1, {(0x00, 0x10): ("F2K", "S2"), #STC15F2K
(0x20, 0x30): ("C5", "RC"),
}),
0xF6: ("8", 8, {(0x20, 0x28): ("A8K", "S4A12"),#STC 8A8K
(0x40, 0x4f): ("F2K", "S2"),#STC 8F2K
(0x50, 0x5f): ("A4K", "S2A12"),#STC 8A4K A12
}),
}
iapmcu = ((0xD1, 0x3F), (0xD1, 0x5F), (0xD1, 0x7F),
(0xD2, 0x7E), (0xD2, 0xFE),
(0xD3, 0x5F), (0xD3, 0xDF),
(0xE2, 0x76), (0xE2, 0xF6),
)
try:
model = tuple(model)
prefix, romratio, fixmap = modelmap[model[0]]
if model[0] in (0xF0, 0xF1) and 0x20 <= model[1] <= 0x30:
prefix = "90"
for key, value in fixmap.items():
if key[0] <= model[1] <= key[1]:
break
else:
self.parent.SetTipString("IOError in __model_database")
infix, postfix = value
if model[0] == 0xF4:
romsize = 60
else:
romsize = romratio * (model[1] - key[0])
try:
romsize = {(0xF0, 0x03): 13}[model]
except KeyError:
pass
if model[0] in (0xF0, 0xF1):
romfix = str(model[1] - key[0])
elif model[0] in (0xF2,):
romfix = str(romsize)
else:
romfix = "%02d" % romsize
name = "IAP" if model in iapmcu else "STC"
name += prefix + infix + romfix + postfix
return (name, romsize)
except KeyError:
return ("Unknown %02X %02X" % model, None)
def recv(self, timeout = 1, start = [0x46, 0xB9, 0x68]):
timeout += time.time()
while time.time() < timeout:
try:
if self.__conn_read(len(start)) == start:
break
except IOError:
continue
else:
logging.debug("recv(..): Timeout")
#return 0, 0
#self.parent.SetTipString("IOError in stcflash.py recv()")
raise IOError()
time.sleep(0.2)
chksum = start[-1]
s = self.__conn_read(2)
n = s[0] * 256 + s[1]
if n > 64:
logging.debug("recv(..): Incorrect packet size")
raise IOError()
chksum += sum(s)
s = self.__conn_read(n - 3)
if s[n - 4] != 0x16:
logging.debug("recv(..): Missing terminal symbol")
raise IOError()
chksum += sum(s[:-(1+self.chkmode)])
if self.chkmode > 0 and chksum & 0xFF != s[-2]:
logging.debug("recv(..): Incorrect checksum[0]")
raise IOError()
elif self.chkmode > 1 and (chksum >> 8) & 0xFF != s[-3]:
logging.debug("recv(..): Incorrect checksum[1]")
raise IOError()
return (s[0], s[1:-(1+self.chkmode)])
def send(self, cmd, dat):
buf = [0x46, 0xB9, 0x6A]
n = 1 + 2 + 1 + len(dat) + self.chkmode + 1
buf += [n >> 8, n & 0xFF, cmd]
buf += dat
chksum = sum(buf[2:])
if self.chkmode > 1: #stc89 帧格式中,只有一个字节的校验和,其他型号是2个字节
buf += [(chksum >> 8) & 0xFF]
buf += [chksum & 0xFF, 0x16]
self.__conn_write(buf)
def detect(self):
#1. 不停发送 0x7F,等待应答
for i in range(500):
try:
self.__conn_write([0x7F, 0x7F])
cmd, dat = self.recv(0.03, [0x68])
break
except IOError:
pass
else:
return False #raise IOError()
#2. 计算MCU 的晶振频率
if self.protocol in PROTOSET_15F2K: # dat[7:9] *0x100 Hz,/ 1000000 =MHz
self.fosc = (dat[7]*0x1000000 +dat[8]*0x10000+dat[9]*0x100) /1000000
logging.info("dat[7]:%02X dat[8]:%02X dat[9]%02X" % (dat[7], dat[8], dat[9]))
logging.info("self.fosc:%04f" % (self.fosc))
elif self.protocol in PROTOSET_8F2K: # dat[0:2] *0x100 Hz,/ 1000000 =MHz
self.fosc = (dat[0]*0x1000000 +dat[1]*0x10000+dat[2]*0x100) /1000000
else:
self.fosc = (float(sum(dat[0:16:2]) * 256 + sum(dat[1:16:2])) / 8
* self.conn.baudrate / 580974)
#3. 分析MCU 型号,固件版本,ROM容量
self.info = dat[16:]
self.version = "%d.%d%c" % (self.info[0] >> 4,
self.info[0] & 0x0F,
self.info[1])
self.model = self.info[3:5]
self.name, self.romsize = self.__model_database(self.model)
logging.info("Model ID: %02X %02X" % tuple(self.model))
logging.info("Model name: %s" % self.name)
logging.info("ROM size: %s" % self.romsize)
#4. 假如事先未知型号,现在确定,
if self.protocol is None:
try:
self.protocol = {0xF0: PROTOCOL_89, #STC89/90C5xRC
0xF1: PROTOCOL_89, #STC89/90C5xRD+
0xF2: PROTOCOL_12Cx052, #STC12Cx052
0xD1: PROTOCOL_12C5A, #STC12C5Ax
0xD2: PROTOCOL_12C5A, #STC10Fx
0xE1: PROTOCOL_12C52, #STC12C52x
0xE2: PROTOCOL_12C5A, #STC11Fx
0xE6: PROTOCOL_12C52, #STC12C56x
0X72:PROTOCOL_12Cx052, #stc12Cx052
0X74:PROTOCOL_15F2K, #stc15F2K
0X76:PROTOCOL_8F2K, #stc15F2K
}[self.model[0]]
except KeyError:
pass
#5. 根据MCU型号,确定校验和的是1 Byte还是 2Byte;还有串口的奇偶模式
if self.protocol in PROTOSET_PARITY or self.protocol in PROTOSET_15F2K \
or self.protocol in PROTOCOL_8F2K:
self.chkmode = 2
self.conn.parity = serial.PARITY_EVEN
else:
self.chkmode = 1
self.conn.parity = serial.PARITY_NONE
if self.protocol is not None:
del self.info[-self.chkmode:]
logging.info("Protocol ID: %s" % self.protocol)
logging.info("Checksum mode: %d" % self.chkmode)
logging.info("UART Parity: %s"
% {serial.PARITY_NONE: "NONE",
serial.PARITY_EVEN: "EVEN",
}[self.conn.parity])
for i in range(0, len(self.info), 16):
logging.info("Info string [%d]: %s"
% (i // 16,
" ".join(["%02X" % j for j in self.info[i:i+16]])))
return True
def print_info(self):
print(" FOSC: %.3fMHz" % self.fosc)
print(" Model: %s (ver%s) " % (self.name, self.version))
if self.romsize is not None:
print(" ROM: %dKB" % self.romsize)
if self.protocol == PROTOCOL_89:
switches = [( 2, 0x80, "Reset stops watchdog"),
( 2, 0x40, "Internal XRAM"),
( 2, 0x20, "Normal ALE pin"),
( 2, 0x10, "Full gain oscillator"),
( 2, 0x08, "Not erase data EEPROM"),
( 2, 0x04, "Download regardless of P1"),
( 2, 0x01, "12T mode")]
elif self.protocol == PROTOCOL_12C5A:
switches = [( 6, 0x40, "Disable reset2 low level detect"),
( 6, 0x01, "Reset pin not use as I/O port"),
( 7, 0x80, "Disable long power-on-reset latency"),
( 7, 0x40, "Oscillator high gain"),
( 7, 0x02, "External system clock source"),
( 8, 0x20, "WDT disable after power-on-reset"),
( 8, 0x04, "WDT count in idle mode"),
(10, 0x02, "Not erase data EEPROM"),
(10, 0x01, "Download regardless of P1")]
print(" WDT prescal: %d" % 2**((self.info[8] & 0x07) + 1))
elif self.protocol in PROTOSET_12B:
switches = [(8, 0x02, "Not erase data EEPROM")]
else:
switches = []
for pos, bit, desc in switches:
print(" [%c] %s" % ("X" if self.info[pos] & bit else " ", desc))
def handshake(self):
baud0 = self.conn.baudrate
if self.protocol in PROTOSET_15F2K or self.protocol in PROTOSET_8F2K:
for baud in [115200, 57600, 38400, 28800, 19200,
14400, 9600, 4800, 2400, 1200]:
t = self.fosc * 1000000 / baud / 2
#tcfg = 0x10000 - int(t + 0.5)
if self.protocol in PROTOSET_15F2K:
if self.fosc < 11.2 and self.fosc > 11:
baudstr = [0x6E, 0x40, 0xff,0xd0, 0x80,0x6E, 0x81]
elif self.fosc > 18.3 and self.fosc < 18.5:
baudstr = [0x6E, 0x40, 0xff,0xd0, 0x40,0x28, 0x81]
elif self.fosc > 5.4 and self.fosc < 5.6:
baudstr = [0x6f, 0x40, 0xff,0xd0, 0xC0,0x67, 0x81]
else: #elif self.fosc < 22.5 and self.fosc > 22: 默认为22.1184MHz
baudstr = [0x6E, 0x40, 0xff,0xd0, 0x40,0x6f, 0x81]
elif self.protocol in PROTOSET_8F2K:
if self.fosc < 11.2 and self.fosc > 11:
baudstr = [0x00, 0x00, 0xff,0xCC, 0x01,0x6A, 0x81]
elif self.fosc > 18.3 and self.fosc < 18.5:
baudstr = [0x00, 0x00, 0xff,0xCC, 0x01,0x28, 0x81]
elif self.fosc > 5.4 and self.fosc < 5.6:
baudstr = [0x00, 0x00, 0xff,0xCC, 0x01,0x06, 0x81]
else: #elif self.fosc < 22.5 and self.fosc > 22: 默认为22.1184MHz
baudstr = [0x00, 0x00, 0xff,0xCC, 0x01,0x6B, 0x81]
logging.info("Test baudrate %d (accuracy %0.4f) using config %s"
% (baud,
abs(round(t) - t) / t,
" ".join(["%02X" % i for i in baudstr])))
self.send(0x01, baudstr )
try:
cmd, dat = self.recv()
break
except Exception:
logging.info("Cannot use baudrate %d" % baud)
time.sleep(0.2)
self.conn.flushInput()
finally:
self.__conn_baudrate(baud0, False)
logging.info("Change baudrate to %d" % baud)
self.__conn_baudrate(baud)
self.baudrate = baud
else:
for baud in [115200, 57600, 38400, 28800, 19200,
14400, 9600, 4800, 2400, 1200]:
t = self.fosc * 1000000 / baud / 32
if self.protocol not in PROTOSET_89:
t *= 2
if abs(round(t) - t) / t > 0.03:
continue
if self.protocol in PROTOSET_89:
tcfg = 0x10000 - int(t + 0.5)
else:
if t > 0xFF:
continue
tcfg = 0xC000 + 0x100 - int(t + 0.5)
baudstr = [tcfg >> 8,
tcfg & 0xFF,
0xFF - (tcfg >> 8),
min((256 - (tcfg & 0xFF)) * 2, 0xFE),
int(baud0 / 60)]
logging.info("Test baudrate %d (accuracy %0.4f) using config %s"
% (baud,
abs(round(t) - t) / t,
" ".join(["%02X" % i for i in baudstr])))
if self.protocol in PROTOSET_89:
freqlist = (40, 20, 10, 5)
else:
freqlist = (30, 24, 20, 12, 6, 3, 2, 1)
for twait in range(0, len(freqlist)):
if self.fosc > freqlist[twait]:
break
logging.info("Waiting time config %02X" % (0x80 + twait))
self.send(0x8F, baudstr + [0x80 + twait])
try:
self.__conn_baudrate(baud)
cmd, dat = self.recv()
break
except Exception:
logging.info("Cannot use baudrate %d" % baud)
time.sleep(0.2)
self.conn.flushInput()
finally:
self.__conn_baudrate(baud0, False)
else:
self.parent.SetTipString("IOError in stcflash.py handshake()")#raise IOError()
logging.info("Change baudrate to %d" % baud)
self.send(0x8E, baudstr)
self.__conn_baudrate(baud)
self.baudrate = baud
cmd, dat = self.recv()
def erase(self):
if self.protocol in PROTOSET_89:
self.send(0x84, [0x01, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33])
cmd, dat = self.recv(10)
assert cmd == 0x80
elif self.protocol in PROTOSET_15F2K or self.protocol in PROTOSET_8F2K:
self.send(0x03, [0x00, 0x00, 0x5A, 0xA5])
cmd, dat = self.recv(10)
assert cmd == 0x03
else:
self.send(0x84, ([0x00, 0x00, self.romsize * 4,
0x00, 0x00, self.romsize * 4]
+ [0x00] * 12
+ [i for i in range(0x80, 0x0D, -1)]))
cmd, dat = self.recv(10)
if dat:
logging.info("Serial number: "
+ " ".join(["%02X" % j for j in dat]))
def flash(self, code):
code = list(code) + [0xFF] * (511 - (len(code) - 1) % 512)
for i in range(0, len(code), 128):
logging.info("Flash code region (%04X, %04X)" % (i, i + 127))
if self.protocol in PROTOCOL_15F2K or self.protocol in PROTOCOL_8F2K:
cmd =0x02
if self.protocol in PROTOCOL_8F2K and i ==0:
cmd =0x22
addr = [ i >> 8, i & 0xFF, 0x5A, 0xA5]
self.send(cmd, addr + code[i:i+128])
else:
addr = [0, 0, i >> 8, i & 0xFF, 0, 128]
self.send(0x00, addr + code[i:i+128])
cmd, dat = self.recv()
yield i+128
def options(self, **kwargs):
erase_eeprom = kwargs.get("erase_eeprom", None)
dat = []
fosc = list(bytearray(struct.pack(">I", int(self.fosc * 1000000))))
if self.protocol == PROTOCOL_89:
if erase_eeprom is not None:
self.info[2] &= 0xF7
self.info[2] |= 0x00 if erase_eeprom else 0x08
dat = self.info[2:3] + [0xFF]*3
elif self.protocol == PROTOCOL_12C5A:
if erase_eeprom is not None:
self.info[10] &= 0xFD
self.info[10] |= 0x00 if erase_eeprom else 0x02
dat = (self.info[6:9] + [0xFF]*5 + self.info[10:11]
+ [0xFF]*6 + fosc)
elif self.protocol in PROTOSET_12B:
if erase_eeprom is not None:
self.info[8] &= 0xFD
self.info[8] |= 0x00 if erase_eeprom else 0x02
dat = (self.info[6:11] + fosc + self.info[12:16] + [0xFF]*4
+ self.info[8:9] + [0xFF]*7 + fosc + [0xFF]*3)
elif erase_eeprom is not None:
logging.info("Modifying options is not supported for this target")
return False
if dat:
self.send(0x8D, dat)
cmd, dat = self.recv()
return True
def terminate(self):
logging.info("Send termination command")
if self.protocol in PROTOSET_15F2K or self.protocol in PROTOSET_8F2K:
self.send(0xFF, [])
else:
self.send(0x82, [])
self.conn.flush()
time.sleep(0.2)
#def unknown_packet_1(self):#comfirm MCU model,确认MCU型号
def comfirm_MCU_model(self):#comfirm MCU model,确认MCU型号
if self.protocol in PROTOSET_PARITY:
logging.info("Send unknown packet (50 00 00 36 01 ...)")
self.send(0x50, [0x00, 0x00, 0x36, 0x01] + self.model)
cmd, dat = self.recv()
assert cmd == 0x8F and not dat
#def unknown_packet_2(self)
def prepare_for_erase(self): #STC15F2K60S2 需要一个准备指令 0x05
if self.protocol in PROTOSET_15F2K or self.protocol in PROTOSET_8F2K:#
logging.info("Send prepare command (05 00 00 5A A5)")
self.send(0x05, [0x00, 0x00, 0x5A, 0xA5])
cmd, dat = self.recv(10)
assert cmd == 0x05 and not dat
elif self.protocol not in PROTOSET_PARITY:
for i in range(5):
logging.info("Send unknown packet (80 00 00 36 01 ...)")
self.send(0x80, [0x00, 0x00, 0x36, 0x01] + self.model)
cmd, dat = self.recv()
assert cmd == 0x80 and not dat
#
def unknown_packet_3(self):
if self.protocol in PROTOSET_PARITY: #此函数只有 STC12的一部分芯片需要
logging.info("Send unknown packet (69 00 00 36 01 ...)")
self.send(0x69, [0x00, 0x00, 0x36, 0x01] + self.model)
cmd, dat = self.recv()
assert cmd == 0x8D and not dat
def sendISPcmd(self, baud=115200, cmdstr='5a 3a 6c'):
#1. 发送ISP命令的波特率是单片机运行时的波特率
baud0 = self.conn.baudrate
self.conn.parity = serial.PARITY_NONE
self.__conn_baudrate(baud)
dat = []
hexList=cmdstr.split(' ')
for hex0 in hexList:
dat += binascii.a2b_hex(hex0)
self.__conn_write(dat)
#2.恢复原来波特率 ,即发送检测命令 0x7F 时的波特率
if self.protocol in PROTOSET_PARITY or self.protocol in PROTOSET_15F2K \
or self.protocol in PROTOSET_8F2K:
self.conn.parity = serial.PARITY_EVEN
self.__conn_baudrate(baud0, flush=False) #默认flush=True 将会产生0.2秒的延时
# 以下2个函数移到 《texteditor2.py》,这里的函数已经没有用
'''
def autoisp(conn, baud, magic):
if not magic:
return
bak = conn.baudrate
conn.baudrate = baud
conn.write(bytearray(ord(i) for i in magic))
conn.flush()
time.sleep(0.5) # 这里不能有延时,否则会错失握手机会
conn.baudrate = bak
def program(prog, code, erase_eeprom=None):
logging.basicConfig(filename="test.log", filemode="w",
format="%(asctime)s %(name)s:%(levelname)s:%(message)s",
datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG)
sys.stdout.write("Detecting target...")
sys.stdout.flush()
prog.detect()
print(" done")
prog.print_info()
if prog.protocol is None:
raise IOError("Unsupported target")
if code is None:
return
prog.comfirm_MCU_model()
sys.stdout.write("Baudrate: ")
sys.stdout.flush()
prog.handshake()
print(prog.baudrate)
prog.unknown_packet_2()
sys.stdout.write("Erasing target...")
sys.stdout.flush()
prog.erase()
print(" done")
print("Size of the binary: %d" % len(code))
# print("Programming: ", end="", flush=True)
sys.stdout.write("Programming: ")
sys.stdout.flush()
oldbar = 0
for progress in prog.flash(code):
bar = int(progress * 20)
sys.stdout.write("#" * (bar - oldbar))
sys.stdout.flush()
oldbar = bar
print(" done")
prog.unknown_packet_3()
sys.stdout.write("Setting options...")
sys.stdout.flush()
if prog.options(erase_eeprom=erase_eeprom):
print(" done")
else:
print(" failed")
prog.terminate()
# Convert Intel HEX code to binary format
def hex2bin(code):
buf = bytearray()
base = 0
line = 0
for rec in code.splitlines():
# Calculate the line number of the current record
line += 1
try:
# bytes(...) is to support python<=2.6
# bytearray(...) is to support python<=2.7
n = bytearray(binascii.a2b_hex(bytes(rec[1:3])))[0]
dat = bytearray(binascii.a2b_hex(bytes(rec[1:n*2+11])))
except:
raise Exception("Line %d: Invalid format" % line)
if rec[0] != ord(":"):
raise Exception("Line %d: Missing start code \":\"" % line)
if sum(dat) & 0xFF != 0:
raise Exception("Line %d: Incorrect checksum" % line)
if dat[3] == 0: # Data record
addr = base + (dat[1] << 8) + dat[2]
# Allocate memory space and fill it with 0xFF
buf[len(buf):] = [0xFF] * (addr + n - len(buf))
# Copy data to the buffer
buf[addr:addr+n] = dat[4:-1]
elif dat[3] == 1: # EOF record
if n != 0:
raise Exception("Line %d: Incorrect data length" % line)
elif dat[3] == 2: # Extended segment address record
if n != 2:
raise Exception("Line %d: Incorrect data length" % line)
base = ((dat[4] << 8) + dat[5]) << 4
elif dat[3] == 4: # Extended linear address record
if n != 2:
raise Exception("Line %d: Incorrect data length" % line)
base = ((dat[4] << 8) + dat[5]) << 16
else:
raise Exception("Line %d: Unsupported record type" % line)
return buf
'''
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。