initial commit

This commit is contained in:
Emil Lerch 2023-04-20 11:45:21 -07:00
commit 2f16907c9e
24 changed files with 12285 additions and 0 deletions

256
BLFlashCommand.py Normal file
View File

@ -0,0 +1,256 @@
# uncompyle6 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: BLFlashCommand.py
"""
Created on 20221216
@author: Dillon
"""
import os, re, sys, argparse, binascii, threading, configparser
from libs import bflb_utils
from libs.bflb_utils import get_serial_ports
from libs.bflb_interface_eflash_loader import InterfaceEflashLoader
def hex_to_dec(value):
try:
value = value.replace('0x', '')
int(value, 16)
return True
except ValueError:
return False
class ThreadIot(threading.Thread):
def __init__(self, config, act='download', callback=None):
threading.Thread.__init__(self)
self.obj = InterfaceEflashLoader()
self.config = config
self.callback = callback
self.act = act
def stop(self):
pass
def run(self):
self.obj.run(self.act, self.config, self.callback)
class MainClass:
def __init__(self):
self.dict_chip = {
'BL602': ('bl602', 'bl602'),
'BL702': ('bl702', 'bl702'),
'BL702L': ('bl702l', 'bl702l'),
'BL808': ('bl808', 'bl808'),
'BL606P': ('bl606p', 'bl808'),
'BL616': ('bl616', 'bl616')}
def get_addr_from_partition_by_name(self, name, parition_file, index):
try:
with open(parition_file, 'rb') as (fp):
data = bytearray(fp.read())
fp.close()
start = data.find(name.encode('utf-8'))
if start != -1:
addr = data[start + 9 + index * 4:start + 9 + 4 + index * 4]
addr.reverse()
addr = hex(int(binascii.hexlify(addr), 16))
return (True, addr)
print(data)
print(name.encode('utf-8'))
return (False, '0')
except Exception as e:
try:
bflb_utils.printf(e)
return (False, '0')
finally:
e = None
del e
def get_value(self, args):
self.config = dict()
self.config['param'] = dict()
self.config['check_box'] = dict()
self.config['input_path'] = dict()
self.config['param']['interface_type'] = args.interface
self.config['param']['comport_uart'] = args.port
self.config['param']['chip'] = args.chipname.lower()
if args.chipname.upper() not in self.dict_chip:
bflb_utils.printf('Error: chipname ' + args.chipname + ' is error!')
return
chip = self.dict_chip[args.chipname.upper()]
self.config['param']['chip_name'] = chip[0]
self.config['param']['chip_type'] = chip[1]
if args.interface.lower() == 'uart':
self.config['param']['speed_uart'] = str(args.baudrate)
self.config['param']['speed_jlink'] = '1000'
else:
self.config['param']['speed_uart'] = '2000000'
if str(args.baudrate) == '2000000':
self.config['param']['speed_jlink'] = '1000'
else:
self.config['param']['speed_jlink'] = str(args.baudrate)
if args.efuse:
self.config['check_box']['efuse'] = True
self.config['input_path']['efuse'] = os.path.abspath(args.efuse)
else:
self.config['check_box']['efuse'] = False
self.config['input_path']['efuse'] = ''
self.config['input_path']['config'] = args.config
try:
try:
self.erase = 1
self.skip_mode = '0x0, 0x0'
self.boot2_isp_mode = 0
config = configparser.ConfigParser()
if not os.path.exists(os.path.abspath(args.config)):
bflb_utils.printf('Error: Config File Not Found!')
return
config.read((os.path.abspath(args.config)), encoding='utf-8')
if config:
for item in config.sections():
if item == 'cfg':
self.erase = config.get('cfg', 'erase', fallback=1)
self.skip_mode = config.get('cfg', 'skip_mode', fallback='0x0, 0x0')
self.boot2_isp_mode = config.get('cfg', 'boot2_isp_mode', fallback=0)
except Exception as e:
try:
config = None
print('ConfigParser Error: ' + str(e))
finally:
e = None
del e
finally:
self.config['param']['erase'] = self.erase
self.config['param']['skip_mode'] = self.skip_mode
self.config['param']['boot2_isp_mode'] = self.boot2_isp_mode
if args.key:
self.config['check_box']['encrypt'] = True
self.config['param']['aes_key'] = args.key
self.config['param']['aes_iv'] = args.iv
else:
self.config['check_box']['encrypt'] = False
self.config['param']['aes_key'] = ''
self.config['param']['aes_iv'] = ''
if args.pk:
self.config['check_box']['sign'] = True
self.config['input_path']['publickey'] = args.pk
self.config['input_path']['privatekey'] = args.sk
else:
self.config['check_box']['sign'] = False
self.config['input_path']['publickey'] = ''
self.config['input_path']['privatekey'] = ''
return self.config
def get_value_file(self, name, path, addr, cpu_id=None):
name = str(name)
if os.path.isabs(path):
path = os.path.abspath(path)
else:
config_dir = os.path.dirname(os.path.abspath(self.config['input_path']['config']))
path = os.path.join(config_dir, path)
if cpu_id:
path = path.replace('$(CHIPNAME)', self.config['param']['chip_name'] + '_' + cpu_id)
else:
path = path.replace('$(CHIPNAME)', self.config['param']['chip_name'])
addr = str(addr)
self.config[name] = {}
self.config[name]['addr'] = addr
self.config[name]['path'] = path
if not os.path.exists(path):
dir_path = os.path.dirname(path)
file_name = os.path.basename(path)
try:
all_file_list = os.listdir(dir_path)
except Exception as e:
try:
bflb_utils.printf(e)
return False
finally:
e = None
del e
result = []
if '*' in file_name:
file_name = file_name.replace('.', '\\.').replace('*', '.*[一-龥]*')
for one_name in all_file_list:
pattern = re.compile(file_name)
temp_list = pattern.findall(one_name)
if one_name in temp_list:
result += temp_list
if len(result) > 1:
bflb_utils.printf('Error: ' + name + ' multiple files were matched! ')
return False
if len(result) == 0:
error = 'Error: ' + name + ':' + path + ' image file is not existed'
bflb_utils.printf(error)
return False
self.config[name]['path'] = os.path.join(dir_path, result[0])
if addr.find('@partition') != -1:
bflb_utils.printf('{0} get address from partiton file {1}'.format(name, self.config['partition']['path']))
success, addr_pt = self.get_addr_from_partition_by_name(name, self.config['partition']['path'], 0)
if not success:
bflb_utils.printf('Fail, not find ', name, ' in partition')
return False
self.config[name]['addr'] = addr_pt
bflb_utils.printf('Address=', addr_pt)
addr = addr_pt
if not hex_to_dec(addr):
error = 'Error: ' + addr + ' is invalid hexadecimal value'
bflb_utils.printf(error)
return False
return True
def main(self, argv):
port = None
ports = []
for item in get_serial_ports():
ports.append(item['port'])
if ports:
try:
port = sorted(ports, key=(lambda x: int(re.match('COM(\\d+)', x).group(1))))[0]
except Exception:
port = sorted(ports)[0]
else:
parser = argparse.ArgumentParser(description='flash-command')
parser.add_argument('--interface', dest='interface', default='uart', help='interface to use')
parser.add_argument('--port', dest='port', default=port, help='serial port to use')
parser.add_argument('--chipname', dest='chipname', default='BL602', help='chip name')
parser.add_argument('--baudrate', dest='baudrate', default=2000000, type=int, help='the speed at which to communicate')
parser.add_argument('--config', dest='config', default='', help='run config')
parser.add_argument('--cpu_id', dest='cpu_id', default='', help='cpu id')
parser.add_argument('--efuse', dest='efuse', default='', help='efuse options')
parser.add_argument('--key', dest='key', default='', help='aes key')
parser.add_argument('--iv', dest='iv', default='', help='aes iv')
parser.add_argument('--pk', dest='pk', help='ecc public key')
parser.add_argument('--sk', dest='sk', default='', help='ecc private key')
args = parser.parse_args(argv)
if args.port:
bflb_utils.printf('Serial port is ' + args.port)
else:
if port:
bflb_utils.printf('Serial port is ' + port)
else:
bflb_utils.printf('Serial port is not found')
bflb_utils.printf('==================================================')
config = self.get_value(args)
if config:
self.obj = InterfaceEflashLoader()
self.obj.run('download', config, None)
if __name__ == '__main__':
print(sys.argv)
app = MainClass()
app.main(sys.argv[1:])
# okay decompiling BLFlashCommand.pyc

60
libs/__init__.py Normal file
View File

@ -0,0 +1,60 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: libs/__init__.py
from . import bflb_utils
from . import bflb_interface_eflash_loader
from . import bflb_eflash_loader
from . import bflb_configobj
from . import bflb_interface_jlink
from . import bflb_interface_cklink
from . import bflb_interface_openocd
from .base import bflb_flash_select
from .base import bflb_efuse_boothd_create
from .base import bflb_base_eflash_loader
from .base import bflb_img_create
from .base import bflb_serial
from .base import bflb_img_loader
from base.bl602 import flash_select_do
from base.bl602 import bootheader_cfg_keys
from base.bl602 import jlink_load_cfg
from base.bl602 import cklink_load_cfg
from base.bl602 import openocd_load_cfg
from base.bl602 import img_create_do
from base.bl702 import chiptype_patch
from base.bl702 import flash_select_do
from base.bl702 import bootheader_cfg_keys
from base.bl702 import jlink_load_cfg
from base.bl702 import cklink_load_cfg
from base.bl702 import openocd_load_cfg
from base.bl702 import img_create_do
from base.bl808 import chiptype_patch
from base.bl808 import flash_select_do
from base.bl808 import bootheader_cfg_keys
from base.bl808 import jlink_load_cfg
from base.bl808 import cklink_load_cfg
from base.bl808 import openocd_load_cfg
from base.bl808 import img_create_do
from base.bl616 import chiptype_patch
from base.bl616 import flash_select_do
from base.bl616 import bootheader_cfg_keys
from base.bl616 import jlink_load_cfg
from base.bl616 import cklink_load_cfg
from base.bl616 import openocd_load_cfg
from base.bl616 import img_create_do
from base.wb03 import chiptype_patch
from base.wb03 import flash_select_do
from base.wb03 import bootheader_cfg_keys
from base.wb03 import jlink_load_cfg
from base.wb03 import cklink_load_cfg
from base.wb03 import openocd_load_cfg
from base.wb03 import img_create_do
from base.bl702l import chiptype_patch
from base.bl702l import flash_select_do
from base.bl702l import bootheader_cfg_keys
from base.bl702l import jlink_load_cfg
from base.bl702l import cklink_load_cfg
from base.bl702l import openocd_load_cfg
from base.bl702l import img_create_do
# okay decompiling ./libs/__init__.pyc

7
libs/base.py Normal file
View File

@ -0,0 +1,7 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: -
pass
# okay decompiling ./libs/base.pyc

2030
libs/bflb_configobj.py Normal file

File diff suppressed because it is too large Load Diff

32
libs/bflb_ecdh.py Normal file
View File

@ -0,0 +1,32 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: libs/bflb_ecdh.py
import binascii
from ecdsa import ECDH, NIST256p
from libs.bflb_utils import *
class BflbEcdh(object):
def __init__(self, curve=NIST256p):
self.ecdh = ECDH(curve)
self.local_public_key = None
self.sharedsecret = ''
def create_public_key(self):
self.ecdh.generate_private_key()
self.local_public_key = self.ecdh.get_public_key()
ret = binascii.hexlify(self.local_public_key.to_string()).decode('utf-8')
printf('local public key:')
printf(ret)
return ret
def create_shared_key(self, peer_pk):
self.ecdh.load_received_public_key_bytes(binascii.unhexlify(peer_pk))
self.sharedsecret = self.ecdh.generate_sharedsecret_bytes()
ret = binascii.hexlify(self.sharedsecret).decode('utf-8')
printf('secret key:')
printf(ret)
return ret
# okay decompiling ./libs/bflb_ecdh.pyc

523
libs/bflb_eflash_loader.py Normal file
View File

@ -0,0 +1,523 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: libs/bflb_eflash_loader.py
from libs.bflb_utils import *
from libs.bflb_configobj import BFConfigParser
from libs.base.bflb_base_eflash_loader import BaseEflashLoader
FLASH_ERASE_SHAKE_HAND = 'Flash erase shake hand'
FLASH_LOAD_SHAKE_HAND = 'Flash load shake hand'
class BL602EflashLoader(BaseEflashLoader):
__doc__ = '\n When chip is bl602, eflash Loader\n '
def __init__(self, chip_type, args, config, callback=None, macaddr_callback=None, create_simple_callback=None, create_img_callback=None, task_num=None):
super().__init__(chip_type, args, config, callback, macaddr_callback, create_simple_callback, create_img_callback, task_num)
self.chip_type = chip_type
def set_load_function(self):
self.load_function = 1
def get_flash_pin(self):
return 255
def show_identify_fail(self):
printf('eflash loader identify flash fail!')
self.error_code_print('0043')
return False
def set_temp_timeout(self):
self.bflb_serial_object.set_timeout(self._default_time_out)
def run_step(self):
result, content = self.first_run_step_load_parameter()
if not result or content != 'continue':
return (result, content)
result, content = self.second_run_step_shake_hand()
if not result or content != 'continue':
return (result, content)
result, content = self.third_run_step_read_mac_address()
if not result or content != 'continue':
return (result, content)
result, content = self.fourth_run_step_interact_chip()
if not result or content != 'continue':
return (result, content)
result, content = self.fifth_run_step_write_flash_and_check()
if not result or content != 'continue':
return (result, content)
result, content = self.sixth_run_step_write_efuse()
if not result or content != 'continue':
return (result, content)
result, content = self.seventh_run_step_erase()
if not result or content != 'continue':
return (result, content)
result, content = self.eighth_run_step_read()
if not result or content != 'continue':
return (result, content)
result, content = self.ninth_run_step_end()
return (
result, content)
class BL616EflashLoader(BaseEflashLoader):
__doc__ = '\n When chip is bl616, eflash Loader\n '
def __init__(self, chip_type, args, config, callback=None, macaddr_callback=None, create_simple_callback=None, create_img_callback=None, task_num=None):
super().__init__(chip_type, args, config, callback, macaddr_callback, create_simple_callback, create_img_callback, task_num)
self.chip_type = chip_type
def run_flash2(self):
"""
If chip is bl616 or wb03, it will run this function.
"""
if self.cfg.has_option('FLASH2_CFG', 'flash2_en'):
self._flash2_en = self.cfg.get('FLASH2_CFG', 'flash2_en') == 'true'
if self._flash2_en is True:
self._flash1_size = int(self.cfg.get('FLASH2_CFG', 'flash1_size')) * 1024 * 1024
self._flash2_size = int(self.cfg.get('FLASH2_CFG', 'flash2_size')) * 1024 * 1024
printf('flash2 set para')
flash2_pin = 0
flash2_clock_cfg = 0
flash2_io_mode = 0
flash2_clk_delay = 0
if self.cfg.get('FLASH2_CFG', 'flash2_pin'):
flash_pin_cfg = self.cfg.get('FLASH2_CFG', 'flash2_pin')
if flash_pin_cfg.startswith('0x'):
flash2_pin = int(flash_pin_cfg, 16)
else:
flash2_pin = int(flash_pin_cfg, 10)
if self.cfg.has_option('FLASH2_CFG', 'flash2_clock_cfg'):
clock_div_cfg = self.cfg.get('FLASH2_CFG', 'flash2_clock_cfg')
if clock_div_cfg.startswith('0x'):
flash2_clock_cfg = int(clock_div_cfg, 16)
else:
flash2_clock_cfg = int(clock_div_cfg, 10)
if self.cfg.has_option('FLASH2_CFG', 'flash2_io_mode'):
io_mode_cfg = self.cfg.get('FLASH2_CFG', 'flash2_io_mode')
if io_mode_cfg.startswith('0x'):
flash2_io_mode = int(io_mode_cfg, 16)
else:
flash2_io_mode = int(io_mode_cfg, 10)
if self.cfg.has_option('FLASH2_CFG', 'flash2_clock_delay'):
clk_delay_cfg = self.cfg.get('FLASH2_CFG', 'flash2_clock_delay')
if clk_delay_cfg.startswith('0x'):
flash2_clk_delay = int(clk_delay_cfg, 16)
else:
flash2_clk_delay = int(clk_delay_cfg, 10)
self.flash2_set = (flash2_pin << 0) + (flash2_clock_cfg << 8) + (flash2_io_mode << 16) + (flash2_clk_delay << 24)
if self.load_function == 2:
printf('set flash2 cfg: %X' % self.flash2_set)
ret = self.flash_set_para_main_process(self.flash2_set, bytearray(0))
self._need_shake_hand = False
if ret is False:
return (False, self.flash_burn_retry)
ret = self.flash_switch_bank_process(1)
self._need_shake_hand = False
if ret is False:
return (False, self.flash_burn_retry)
ret, data = self.flash_read_jedec_id_process()
if ret:
self._need_shake_hand = False
data = binascii.hexlify(data).decode('utf-8')
self.id2_valid_flag = data[6:]
read_id2 = data[0:6]
self.read_flash2_id = read_id2
if self.cfg.has_option('FLASH2_CFG', 'flash2_para'):
flash2_para_file = os.path.join(app_path, self.cfg.get('FLASH2_CFG', 'flash2_para'))
self.flash_para_update(flash2_para_file, read_id2)
fp = open_file(flash2_para_file, 'rb')
para_data = bytearray(fp.read())
fp.close()
para_data[0:1] = b'\x11'
fp = open_file(flash2_para_file, 'wb+')
fp.write(para_data)
fp.close()
else:
self.error_code_print('0030')
return (
False, self.flash_burn_retry)
ret = self.flash_switch_bank_process(0)
self._need_shake_hand = False
if ret is False:
return (False, self.flash_burn_retry)
return (True, 'continue')
def get_flash1_and_flash2(self, flash_file, address, size_current, i):
if self._flash1_size != 0:
if self._flash1_size < int(address[i], 16) + size_current:
if self._flash1_size > int(address[i], 16):
if self._flash2_select is False:
printf('%s file is overflow with flash1' % flash_file[i])
flash1_bin, flash1_bin_len, flash2_bin, flash2_bin_len = self.flash_loader_cut_flash_bin(flash_file[i], int(address[i], 16), self._flash1_size)
return (
flash1_bin, flash1_bin_len, flash2_bin, flash2_bin_len)
return ('', 0, '', 0)
def set_clear_boot_status(self, shakehand=0):
self.clear_boot_status(shakehand)
def get_new_bh_data(self, section, bh_data, fp):
if section == 'BOOTHEADER_GROUP0_CFG':
fp.write(bh_data[100:120])
def write_flash_data(self, file, start_addr, callback):
pass
def get_flash_pin_from_bootinfo(self, chiptype, bootinfo):
sw_usage_data = bootinfo[22:24] + bootinfo[20:22] + bootinfo[18:20] + bootinfo[16:18]
sw_usage_data = int(sw_usage_data, 16)
return sw_usage_data >> 14 & 63
def run_step(self):
result, content = self.first_run_step_load_parameter()
if not result or content != 'continue':
return (result, content)
result, content = self.second_run_step_shake_hand()
if not result or content != 'continue':
return (result, content)
result, content = self.third_run_step_read_mac_address()
if not result or content != 'continue':
return (result, content)
result, content = self.fourth_run_step_interact_chip()
if not result or content != 'continue':
return (result, content)
result, content = self.fifth_run_step_write_flash_and_check()
if not result or content != 'continue':
return (result, content)
result, content = self.sixth_run_step_write_efuse()
if not result or content != 'continue':
return (result, content)
result, content = self.seventh_run_step_erase()
if not result or content != 'continue':
return (result, content)
result, content = self.eighth_run_step_read()
if not result or content != 'continue':
return (result, content)
result, content = self.ninth_run_step_end()
return (
result, content)
class BL628EflashLoader(BaseEflashLoader):
__doc__ = '\n When chip is bl628, eflash Loader\n '
def __init__(self, chip_type, args, config, callback=None, macaddr_callback=None, create_simple_callback=None, create_img_callback=None, task_num=None):
super().__init__(chip_type, args, config, callback, macaddr_callback, create_simple_callback, create_img_callback, task_num)
self.chip_type = chip_type
def set_clear_boot_status(self, shakehand=0):
self.clear_boot_status(shakehand)
def get_new_bh_data(self, section, bh_data, fp):
if section == 'BOOTHEADER_GROUP0_CFG':
fp.write(bh_data[100:124])
def write_flash_data(self, file, start_addr, callback):
pass
def run_step(self):
result, content = self.first_run_step_load_parameter()
if not result or content != 'continue':
return (result, content)
result, content = self.second_run_step_shake_hand()
if not result or content != 'continue':
return (result, content)
result, content = self.third_run_step_read_mac_address()
if not result or content != 'continue':
return (result, content)
result, content = self.fourth_run_step_interact_chip()
if not result or content != 'continue':
return (result, content)
result, content = self.fifth_run_step_write_flash_and_check()
if not result or content != 'continue':
return (result, content)
result, content = self.sixth_run_step_write_efuse()
if not result or content != 'continue':
return (result, content)
result, content = self.seventh_run_step_erase()
if not result or content != 'continue':
return (result, content)
result, content = self.eighth_run_step_read()
if not result or content != 'continue':
return (result, content)
result, content = self.ninth_run_step_end()
return (
result, content)
class BL702EflashLoader(BaseEflashLoader):
__doc__ = '\n When chip is bl702, eflash Loader\n '
def __init__(self, chip_type, args, config, callback=None, macaddr_callback=None, create_simple_callback=None, create_img_callback=None, task_num=None):
super().__init__(chip_type, args, config, callback, macaddr_callback, create_simple_callback, create_img_callback, task_num)
self.chip_type = chip_type
def set_load_function(self):
if self.chip_type == 'bl702':
self.load_function = 0
def set_decompress_write(self):
self.decompress_write = False
def get_flash_pin(self):
return 255
def show_identify_fail(self):
printf('eflash loader identify flash fail!')
self.error_code_print('0043')
return False
def reset_cpu(self, shakehand=0):
printf('CPU Reset')
if shakehand != 0:
printf(FLASH_ERASE_SHAKE_HAND)
if self.img_load_shake_hand() is False:
return False
cmd_id = hexstr_to_bytearray(self._com_cmds.get('reset')['cmd_id'])
ret, dmy = self.com_process_one_cmd('reset', cmd_id, bytearray(0))
if ret.startswith('OK'):
return True
self.error_code_print('0004')
return False
def run_reset_cpu(self):
if self.isp_mode_sign is True:
self.reset_cpu()
def get_chip_id(self, bootinfo):
chip_id = bootinfo[32:34] + bootinfo[34:36] + bootinfo[36:38] + bootinfo[38:40] + bootinfo[40:42] + bootinfo[42:44] + bootinfo[44:46] + bootinfo[46:48]
return chip_id
def get_mac_len(self):
return 8
def set_temp_timeout(self):
self.bflb_serial_object.set_timeout(self._default_time_out)
def get_isp_sh_time(self):
return self._isp_shakehand_timeout
def run_step(self):
result, content = self.first_run_step_load_parameter()
if not result or content != 'continue':
return (result, content)
result, content = self.second_run_step_shake_hand()
if not result or content != 'continue':
return (result, content)
result, content = self.third_run_step_read_mac_address()
if not result or content != 'continue':
return (result, content)
result, content = self.fourth_run_step_interact_chip()
if not result or content != 'continue':
return (result, content)
result, content = self.fifth_run_step_write_flash_and_check()
if not result or content != 'continue':
return (result, content)
result, content = self.sixth_run_step_write_efuse()
if not result or content != 'continue':
return (result, content)
result, content = self.seventh_run_step_erase()
if not result or content != 'continue':
return (result, content)
result, content = self.eighth_run_step_read()
if not result or content != 'continue':
return (result, content)
result, content = self.ninth_run_step_end()
return (
result, content)
class BL702LEflashLoader(BaseEflashLoader):
__doc__ = '\n When chip is bl702l, eflash Loader\n '
def __init__(self, chip_type, args, config, callback=None, macaddr_callback=None, create_simple_callback=None, create_img_callback=None, task_num=None):
super().__init__(chip_type, args, config, callback, macaddr_callback, create_simple_callback, create_img_callback, task_num)
self.chip_type = chip_type
def reset_cpu(self, shakehand=0):
printf('CPU Reset')
if shakehand != 0:
printf(FLASH_ERASE_SHAKE_HAND)
if self.img_load_shake_hand() is False:
return False
cmd_id = hexstr_to_bytearray(self._com_cmds.get('reset')['cmd_id'])
ret, dmy = self.com_process_one_cmd('reset', cmd_id, bytearray(0))
if ret.startswith('OK'):
return True
self.error_code_print('0004')
return False
def run_reset_cpu(self):
if self.isp_mode_sign is True:
self.reset_cpu()
def get_chip_id(self, bootinfo):
chip_id = bootinfo[32:34] + bootinfo[34:36] + bootinfo[36:38] + bootinfo[38:40] + bootinfo[40:42] + bootinfo[42:44] + bootinfo[44:46] + bootinfo[46:48]
return chip_id
def get_new_bh_data(self, section, bh_data, fp):
if section == 'BOOTHEADER_CFG':
fp.write(bh_data[100:116])
def get_mac_len(self):
return 8
def set_temp_timeout(self):
self.bflb_serial_object.set_timeout(self._default_time_out)
def get_isp_sh_time(self):
return self._isp_shakehand_timeout
def get_flash_pin_from_bootinfo(self, chiptype, bootinfo):
dev_info_data = bootinfo[30:32] + bootinfo[28:30] + bootinfo[26:28] + bootinfo[24:26]
dev_info_data = int(dev_info_data, 16)
flash_cfg = dev_info_data >> 26 & 7
sf_reverse = dev_info_data >> 29 & 1
sf_swap_cfg = dev_info_data >> 22 & 3
if flash_cfg == 0:
return 0
if sf_reverse == 0:
return sf_swap_cfg + 1
return sf_swap_cfg + 5
def run_step(self):
result, content = self.first_run_step_load_parameter()
if not result or content != 'continue':
return (result, content)
result, content = self.second_run_step_shake_hand()
if not result or content != 'continue':
return (result, content)
result, content = self.third_run_step_read_mac_address()
if not result or content != 'continue':
return (result, content)
result, content = self.fourth_run_step_interact_chip()
if not result or content != 'continue':
return (result, content)
result, content = self.fifth_run_step_write_flash_and_check()
if not result or content != 'continue':
return (result, content)
result, content = self.sixth_run_step_write_efuse()
if not result or content != 'continue':
return (result, content)
result, content = self.seventh_run_step_erase()
if not result or content != 'continue':
return (result, content)
result, content = self.eighth_run_step_read()
if not result or content != 'continue':
return (result, content)
result, content = self.ninth_run_step_end()
return (
result, content)
class BL808EflashLoader(BaseEflashLoader):
__doc__ = '\n When chip is bl808, eflash Loader\n '
def __init__(self, chip_type, args, config, callback=None, macaddr_callback=None, create_simple_callback=None, create_img_callback=None, task_num=None):
super().__init__(chip_type, args, config, callback, macaddr_callback, create_simple_callback, create_img_callback, task_num)
self.chip_type = chip_type
def set_clear_boot_status(self, shakehand=0):
self.clear_boot_status(shakehand)
def get_new_bh_data(self, section, bh_data, fp):
if section == 'BOOTHEADER_GROUP0_CFG':
fp.write(bh_data[100:128])
def write_flash_data(self, file, start_addr, callback):
fp = open_file(file, 'rb')
flash_data = bytearray(fp.read())
fp.close()
flash_data_len = len(flash_data)
end_addr = start_addr + flash_data_len - 1
if start_addr <= 4096:
if end_addr > 4096:
ret, flash_read_data = self.flash_read_main_process(4096, 4096, 0, None, callback)
if flash_read_data[0:4] == int_to_4bytearray_b(1112298054):
printf('RF para already write at flash 0x1000 addr, replace it.')
flash_data[4096:8192] = flash_read_data[0:4096]
fp = open_file(file, 'wb')
fp.write(flash_data)
fp.close()
def is_conf_exist(self, flash_id):
cfg_dir = app_path + '/utils/flash/bl808/'
conf_name = self.get_suitable_conf_name(cfg_dir, flash_id)
if os.path.isfile(cfg_dir + conf_name) is False:
return False
return True
def get_flash_pin_from_bootinfo(self, chiptype, bootinfo):
sw_usage_data = bootinfo[22:24] + bootinfo[20:22] + bootinfo[18:20] + bootinfo[16:18]
sw_usage_data = int(sw_usage_data, 16)
return sw_usage_data >> 14 & 31
def run_step(self):
result, content = self.first_run_step_load_parameter()
if not result or content != 'continue':
return (result, content)
result, content = self.second_run_step_shake_hand()
if not result or content != 'continue':
return (result, content)
result, content = self.third_run_step_read_mac_address()
if not result or content != 'continue':
return (result, content)
result, content = self.fourth_run_step_interact_chip()
if not result or content != 'continue':
return (result, content)
result, content = self.fifth_run_step_write_flash_and_check()
if not result or content != 'continue':
return (result, content)
result, content = self.sixth_run_step_write_efuse()
if not result or content != 'continue':
return (result, content)
result, content = self.seventh_run_step_erase()
if not result or content != 'continue':
return (result, content)
result, content = self.eighth_run_step_read()
if not result or content != 'continue':
return (result, content)
result, content = self.ninth_run_step_end()
return (
result, content)
class OtherEflashLoader(BaseEflashLoader):
__doc__ = '\n When chip is not bl602,bl702,bl702l,bl808,bl616.wb03, eflash Loader\n '
def __init__(self, chip_type, args, config, callback=None, macaddr_callback=None, create_simple_callback=None, create_img_callback=None, task_num=None):
super().__init__(chip_type, args, config, callback, macaddr_callback, create_simple_callback, create_img_callback, task_num)
self.chip_type = chip_type
def run_step(self):
result, content = self.first_run_step_load_parameter()
if not result or content != 'continue':
return (result, content)
if self.isp_mode_sign is True:
self.load_function = 1
result, content = self.second_run_step_shake_hand()
if not result or content != 'continue':
return (result, content)
result, content = self.third_run_step_read_mac_address()
if not result or content != 'continue':
return (result, content)
result, content = self.fourth_run_step_interact_chip()
if not result or content != 'continue':
return (result, content)
result, content = self.fifth_run_step_write_flash_and_check()
if not result or content != 'continue':
return (result, content)
result, content = self.sixth_run_step_write_efuse()
if not result or content != 'continue':
return (result, content)
result, content = self.seventh_run_step_erase()
if not result or content != 'continue':
return (result, content)
result, content = self.eighth_run_step_read()
if not result or content != 'continue':
return (result, content)
result, content = self.ninth_run_step_end()
return (
result, content)
# okay decompiling ./libs/bflb_eflash_loader.pyc

View File

@ -0,0 +1,337 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: libs/bflb_interface_cklink.py
import os, time, binascii, subprocess, config as gol, cklink
from libs import bflb_utils
from libs.bflb_utils import app_path
dir_dll = os.path.join(app_path, 'utils/cklink')
class BflbCKLinkPort(object):
def __init__(self, vid=0, pid=0):
self._speed = 5000
self._rx_timeout = 10000
self._cklink_shake_hand_addr = '20000000'
self._cklink_data_addr = '20000004'
self._cklink_run_addr = '22010000'
self._cklink_reg_pc = 32
self._inited = False
self._chiptype = 'bl808'
self._chipname = 'bl808'
self.vid = vid
self.pid = pid
self.link = gol.obj_cklink
def if_init(self, device, sn, rate, chiptype='bl808', chipname='bl808'):
if self._inited is False:
dev = device.split('|')
vid = int(dev[0].replace('0x', ''), 16)
pid = int(dev[1].replace('0x', ''), 16)
serial = str(sn)
bflb_utils.printf('SN is ' + serial)
sub_module = __import__(('libs.base.' + chiptype), fromlist=[chiptype])
self._cklink_shake_hand_addr = sub_module.cklink_load_cfg.cklink_shake_hand_addr
self._cklink_data_addr = sub_module.cklink_load_cfg.cklink_data_addr
self._cklink_run_addr = sub_module.cklink_load_cfg.cklink_run_addr
self._cklink_vid = vid
self._cklink_pid = pid
self._speed = rate
self._inited = True
self._chiptype = chiptype
self._chipname = chipname
if not self.link:
self.link = cklink.CKLink(dlldir=dir_dll, vid=(self._cklink_vid), pid=(self._cklink_pid), sn=serial, arch=2, cdi=0)
gol.obj_cklink = self.link
self.link.open()
if self.link.connected():
self.link.reset(1)
return False
def repeat_init(self, device, sn, rate, chiptype='bl808', chipname='bl808'):
if self._inited is False:
dev = device.split('|')
vid = int(dev[0].replace('0x', ''), 16)
pid = int(dev[1].replace('0x', ''), 16)
serial = str(sn)
bflb_utils.printf('SN is ' + serial)
sub_module = __import__(('libs.base.' + chiptype), fromlist=[chiptype])
self._cklink_shake_hand_addr = sub_module.cklink_load_cfg.cklink_shake_hand_addr
self._cklink_data_addr = sub_module.cklink_load_cfg.cklink_data_addr
self._cklink_run_addr = sub_module.cklink_load_cfg.cklink_run_addr
self._cklink_vid = vid
self._cklink_pid = pid
self._speed = rate
self._inited = True
self._chiptype = chiptype
self._chipname = chipname
if not self.link:
self.link = cklink.CKLink(dlldir=dir_dll, vid=(self._cklink_vid), pid=(self._cklink_pid), sn=serial, arch=2, cdi=0)
gol.obj_cklink = self.link
self.link.open()
if self.link.connected():
self.link.reset(1)
return False
def if_close(self):
if self.link:
try:
try:
self.link.close()
except Exception as e:
try:
print(e)
finally:
e = None
del e
finally:
self._inited = False
def close(self):
if self.link:
try:
try:
self.link.close()
except Exception as e:
try:
print(e)
finally:
e = None
del e
finally:
self._inited = False
def if_clear_buf(self):
pass
def clear_buf(self):
pass
def if_set_rx_timeout(self, val):
self._rx_timeout = val * 1000
def set_timeout(self, val):
self._rx_timeout = val * 1000
def if_get_rate(self):
return self._speed
def halt_cpu(self):
return self.link.halt()
def resume_cpu(self):
return self.link.resume()
def reset_cpu(self):
return self.link.reset(1)
def set_pc_msp(self, pc, msp):
self.halt_cpu()
if self._chiptype == 'bl602' or self._chiptype == 'bl702' or self._chiptype == 'bl702l':
addr = int(self._cklink_run_addr, 16)
self.link.write_cpu_reg(self._cklink_reg_pc, addr)
def if_raw_write(self, addr, data_send):
self.halt_cpu()
addr_int = int(addr, 16)
data_send = bytes(data_send)
self.link.write_memory(addr_int, data_send)
self.resume_cpu()
def if_write(self, data_send):
self.if_raw_write(self._cklink_data_addr, data_send)
self.if_raw_write(self._cklink_shake_hand_addr, binascii.unhexlify('48524459'))
def write(self, data_send):
self.if_raw_write(self._cklink_data_addr, data_send)
self.if_raw_write(self._cklink_shake_hand_addr, binascii.unhexlify('48524459'))
def if_read(self, data_len):
start_time = time.time() * 1000
while True:
self.halt_cpu()
ready = self.link.read_memory(int(self._cklink_shake_hand_addr, 16), 4)
if len(ready) >= 1:
ready = binascii.hexlify(ready).decode()
if ready == '5341434b':
self.resume_cpu()
break
elapsed = time.time() * 1000 - start_time
if elapsed >= self._rx_timeout:
return (0, 'waiting response time out'.encode('utf-8'))
else:
self.resume_cpu()
time.sleep(0.001)
data = self.if_raw_read(self._cklink_data_addr, data_len)
if len(data) != data_len:
return (0, data)
return (1, data)
def read(self, data_len):
start_time = time.time() * 1000
while True:
self.halt_cpu()
ready = self.link.read_memory(int(self._cklink_shake_hand_addr, 16), 4)
if len(ready) >= 1:
ready = binascii.hexlify(ready).decode()
if ready == '5341434b':
self.resume_cpu()
break
elapsed = time.time() * 1000 - start_time
if elapsed >= self._rx_timeout:
return (0, 'waiting response time out'.encode('utf-8'))
else:
self.resume_cpu()
time.sleep(0.001)
data = self.if_raw_read(self._cklink_data_addr, data_len)
if len(data) != data_len:
return (0, data)
return (1, data)
def if_raw_read(self, addr, data_len):
return self.if_raw_read8(addr, data_len)
def if_raw_read8(self, addr, data_len):
self.halt_cpu()
data = self.link.read_memory(int(addr, 16), data_len)
self.resume_cpu()
return bytearray(data)
def if_shakehand(self, do_reset=False, reset_hold_time=100, shake_hand_delay=100, reset_revert=True, cutoff_time=0, shake_hand_retry=2, isp_timeout=0, boot_load=False):
self.if_write(bytearray(1))
success, ack = self.if_read(2)
bflb_utils.printf(binascii.hexlify(ack))
if ack.find(b'O') != -1 or ack.find(b'K') != -1:
time.sleep(0.03)
return 'OK'
return 'FL'
def if_deal_ack(self):
success, ack = self.if_read(2)
if success == 0:
bflb_utils.printf('ack:' + str(binascii.hexlify(ack)))
return ack.decode('utf-8')
if ack.find(b'O') != -1 or ack.find(b'K') != -1:
return 'OK'
if ack.find(b'P') != -1 or ack.find(b'D') != -1:
return 'PD'
success, err_code = self.if_read(4)
if success == 0:
bflb_utils.printf('err_code:' + str(binascii.hexlify(err_code)))
return 'FL'
err_code_str = str(binascii.hexlify(err_code[3:4] + err_code[2:3]).decode('utf-8'))
ack = 'FL'
try:
ret = ack + err_code_str + '(' + bflb_utils.get_bflb_error_code(err_code_str) + ')'
except Exception:
ret = ack + err_code_str + ' unknown'
bflb_utils.printf(ret)
return ret
def deal_ack(self):
success, ack = self.if_read(2)
if success == 0:
bflb_utils.printf('ack:' + str(binascii.hexlify(ack)))
return ack.decode('utf-8')
if ack.find(b'O') != -1 or ack.find(b'K') != -1:
return 'OK'
if ack.find(b'P') != -1 or ack.find(b'D') != -1:
return 'PD'
success, err_code = self.if_read(4)
if success == 0:
bflb_utils.printf('err_code:' + str(binascii.hexlify(err_code)))
return 'FL'
err_code_str = str(binascii.hexlify(err_code[3:4] + err_code[2:3]).decode('utf-8'))
ack = 'FL'
try:
ret = ack + err_code_str + '(' + bflb_utils.get_bflb_error_code(err_code_str) + ')'
except Exception:
ret = ack + err_code_str + ' unknown'
bflb_utils.printf(ret)
return ret
def if_deal_response(self):
ack = self.if_deal_ack()
if ack == 'OK':
success, len_bytes = self.if_read(16)
if success == 0:
bflb_utils.printf('Get length error')
bflb_utils.printf(binascii.hexlify(len_bytes))
return (
'Get length error', len_bytes)
tmp = bflb_utils.bytearray_reverse(len_bytes[2:4])
data_len = bflb_utils.bytearray_to_int(tmp)
success, data_bytes = self.if_read(data_len + 4)
if success == 0:
bflb_utils.printf('Read data error')
return (
'Read data error', data_bytes)
data_bytes = data_bytes[4:]
if len(data_bytes) != data_len:
bflb_utils.printf('Not get excepted length')
return (
'Not get excepted length', data_bytes)
return (ack, data_bytes)
bflb_utils.printf('Not ack OK')
bflb_utils.printf(ack)
return (
ack, None)
def deal_response(self):
ack = self.if_deal_ack()
if ack == 'OK':
success, len_bytes = self.if_read(16)
if success == 0:
bflb_utils.printf('Get length error')
bflb_utils.printf(binascii.hexlify(len_bytes))
return (
'Get length error', len_bytes)
tmp = bflb_utils.bytearray_reverse(len_bytes[2:4])
data_len = bflb_utils.bytearray_to_int(tmp)
success, data_bytes = self.if_read(data_len + 4)
if success == 0:
bflb_utils.printf('Read data error')
return (
'Read data error', data_bytes)
data_bytes = data_bytes[4:]
if len(data_bytes) != data_len:
bflb_utils.printf('Not get excepted length')
return (
'Not get excepted length', data_bytes)
return (ack, data_bytes)
bflb_utils.printf('Not ack OK')
bflb_utils.printf(ack)
return (
ack, None)
if __name__ == '__main__':
eflash_loader_t = BflbCKLinkPort()
eflash_loader_t.if_init('', 100, 'bl702')
bflb_utils.printf('read test')
bflb_utils.printf(eflash_loader_t.if_raw_read('21000000', 2))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000000', 4))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000000', 10))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000000', 16))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000001', 2))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000001', 4))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000001', 10))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000001', 16))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000002', 2))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000002', 4))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000002', 10))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000002', 16))
bflb_utils.printf('write test')
data = bytearray([
1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,
4])
eflash_loader_t.if_raw_write('42020000', data)
bflb_utils.printf(eflash_loader_t.if_raw_read('42020000', 62))
# okay decompiling ./libs/bflb_interface_cklink.pyc

View File

@ -0,0 +1,631 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: libs/bflb_interface_eflash_loader.py
__doc__ = '\nCreated on 20220909\n\n@author: Dillon\n'
import os, sys, time, traceback, binascii
from libs.base import bflb_img_loader
from libs.bflb_utils import *
from libs.bflb_eflash_loader import *
class InterfaceEflashLoader(object):
def __init__(self):
self._temp_task_num = None
def error_code_print(self, code):
set_error_code(code, self._temp_task_num)
printf('{"ErrorCode": "' + code + '","ErrorMsg":"' + eflash_loader_error_code[code] + '"}')
def get_chip_type(self, interface, device, chip_type, callback):
if interface.lower() == 'uart' or interface == 'sdio':
boot_speed = 500000
else:
if chip_type == 'bl606p':
return 'bl808'
return chip_type
_bflb_com_img_loader = bflb_img_loader.BflbImgLoader(device, boot_speed, boot_speed, (interface.lower()), callback=callback)
bflb_serial_object = _bflb_com_img_loader.bflb_serial_object
try:
ret, bootinfo = _bflb_com_img_loader.img_get_bootinfo(boot_speed, boot_speed,
callback=callback,
do_reset=True,
reset_hold_time=5,
shake_hand_delay=100,
reset_revert=False,
cutoff_time=100,
shake_hand_retry=2,
isp_mode_sign=False,
isp_timeout=0,
boot_load=True)
bootinfo = bootinfo.decode('utf-8')
bflb_serial_object.close()
if ret is False:
_bflb_com_img_loader = bflb_img_loader.BflbImgLoader(device, boot_speed, boot_speed, (interface.lower()), 'bl808', callback=callback)
bflb_serial_object = _bflb_com_img_loader.bflb_serial_object
ret, bootinfo = _bflb_com_img_loader.img_get_bootinfo(boot_speed, boot_speed,
callback=callback,
do_reset=True,
reset_hold_time=5,
shake_hand_delay=100,
reset_revert=False,
cutoff_time=100,
shake_hand_retry=2,
isp_mode_sign=False,
isp_timeout=0,
boot_load=True)
bootinfo = bootinfo.decode('utf-8')
bflb_serial_object.close()
if ret is False:
self.error_code_print('0003')
return 'Error: Can not get chip type!!'
if '01000000' in bootinfo:
return 'bl602'
if '01000207' in bootinfo:
return 'bl702'
if '01001606' in bootinfo:
return 'bl616'
if '01000808' in bootinfo:
return 'bl808'
return 'Error: Can not get chip type!!'
except Exception as e:
try:
self.error_code_print('0003')
return 'Error: Can not get chip type!!'
finally:
e = None
del e
def judge_result(self, temp_eflash_obj, result, args, start_time):
do_reset = True
reset_hold_time = 100
shake_hand_delay = 100
reset_revert = True
cutoff_time = 0
shake_hand_retry = 2
if result == 'repeat_burn':
temp_eflash_obj.close_serial()
return 'repeat_burn'
if temp_eflash_obj.cpu_reset is True:
printf('Reset cpu')
temp_eflash_obj.base_reset_cpu()
if temp_eflash_obj.retry_delay_after_cpu_reset > 0:
printf('delay for uart timeout: ', temp_eflash_obj.retry_delay_after_cpu_reset)
time.sleep(temp_eflash_obj.retry_delay_after_cpu_reset)
if result is True:
printf('All time cost(ms): ', time.time() * 1000 - start_time)
time.sleep(0.1)
if not args.none:
if temp_eflash_obj.bflb_serial_object is not None:
temp_eflash_obj.close_serial()
printf('close interface')
printf('[All Success]')
local_log_save('log', temp_eflash_obj.input_macaddr)
if temp_eflash_obj.bflb_serial_object is not None:
temp_eflash_obj.close_serial()
return True
if temp_eflash_obj.bflb_serial_object is not None:
temp_eflash_obj.close_serial()
return False
def run(self, act, config, callback=None):
interface = config['param']['interface_type'].lower()
error = None
flash_burn_retry = 1
clear_global()
try:
try:
device = config['param']['comport_uart']
if interface.lower() == 'uart':
speed = config['param']['speed_uart']
else:
speed = config['param']['speed_jlink']
if not speed.isdigit():
error = '{"ErrorCode":"FFFF","ErrorMsg":"BAUDRATE MUST BE DIGIT"}'
printf(error)
return error
chip_type = config['param']['chip_type']
if act == 'download':
options = [
'--write', '--flash']
try:
if config['check_box']['efuse']:
options.extend(['--efuse'])
except:
pass
parser = eflash_loader_parser_init()
args = parser.parse_args(options)
start_time = time.time() * 1000
if 'Error' in chip_type:
error = '{"ErrorCode":"FFFF","ErrorMsg":"BFLB CAN NOT GET CHIP TYPE"}'
printf(error)
return error
config['param']['chip_xtal'] = 'auto'
if chip_type == 'bl602':
config['param']['chip_xtal'] = '40m'
temp_eflash_obj = BL602EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl702':
config['param']['chip_xtal'] = '32m'
temp_eflash_obj = BL702EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl702l':
config['param']['chip_xtal'] = '32m'
temp_eflash_obj = BL702LEflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl808' or chip_type == 'bl606p':
temp_eflash_obj = BL808EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl616' or chip_type == 'wb03':
temp_eflash_obj = BL616EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl628':
temp_eflash_obj = BL628EflashLoader(chip_type, args, config, callback)
else:
temp_eflash_obj = OtherEflashLoader(chip_type, args, config, callback)
while flash_burn_retry:
retry = -1
if temp_eflash_obj.bflb_serial_object is not None:
temp_eflash_obj.close_serial()
else:
printf('Program Start')
result, content = temp_eflash_obj.run_step()
self._temp_task_num = temp_eflash_obj.task_num
temp_result = self.judge_result(temp_eflash_obj, result, args, start_time)
if temp_result:
return True
printf('Burn Retry')
flash_burn_retry -= 1
printf('Burn return with retry fail')
local_log_save('log', temp_eflash_obj.input_macaddr)
error = errorcode_msg(self._temp_task_num)
except Exception as e:
try:
traceback.print_exc(limit=10, file=(sys.stdout))
error = str(e)
finally:
e = None
del e
finally:
return error
def program_read_id(self, config, callback=None):
flash_burn_retry = 1
interface = config['param']['interface_type']
device = config['param']['comport_uart']
if interface.lower() == 'uart':
speed = config['param']['speed_uart']
else:
speed = config['param']['speed_jlink']
chip_type = config['param']['chip_type']
try:
if not (config['param']['speed_uart'].isdigit() and config['param']['speed_jlink'].isdigit()):
ret = '{"ErrorCode":"FFFF","ErrorMsg":"BAUDRATE MUST BE DIGIT"}'
printf(ret)
return (
False, ret)
set_error_code('FFFF')
start_time = time.time() * 1000
eflash_loader_cfg_tmp = os.path.join(chip_path, chip_type, 'eflash_loader/eflash_loader_cfg.ini')
options = ['--none', '--flash', '-c', eflash_loader_cfg_tmp]
parser_eflash = eflash_loader_parser_init()
args = parser_eflash.parse_args(options)
config['param']['chip_xtal'] = 'auto'
if chip_type == 'bl602':
config['param']['chip_xtal'] = '40m'
temp_eflash_obj = BL602EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl702':
config['param']['chip_xtal'] = '32m'
temp_eflash_obj = BL702EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl702l':
config['param']['chip_xtal'] = '32m'
temp_eflash_obj = BL702LEflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl808' or chip_type == 'bl606p':
temp_eflash_obj = BL808EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl616' or chip_type == 'wb03':
temp_eflash_obj = BL616EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl628':
temp_eflash_obj = BL628EflashLoader(chip_type, args, config, callback)
else:
temp_eflash_obj = OtherEflashLoader(chip_type, args, config, callback)
result, content = temp_eflash_obj.run_step()
ret, data = temp_eflash_obj.flash_read_jedec_id_process()
temp_eflash_obj.object_status_clear()
self._temp_task_num = temp_eflash_obj.task_num
if ret:
data = binascii.hexlify(data).decode('utf-8')
if temp_eflash_obj.bflb_serial_object is not None:
temp_eflash_obj.close_serial()
return (ret, data)
except Exception as e:
try:
ret = str(e)
printf('error:' + ret)
return (
False, ret)
finally:
e = None
del e
def program_read_reg(self, config, callback=None):
flash_burn_retry = 1
interface = config['param']['interface_type']
device = config['param']['comport_uart']
if interface.lower() == 'uart':
speed = config['param']['speed_uart']
else:
speed = config['param']['speed_jlink']
chip_type = config['param']['chip_type']
try:
if not (config['param']['speed_uart'].isdigit() and config['param']['speed_jlink'].isdigit()):
ret = '{"ErrorCode":"FFFF","ErrorMsg":"BAUDRATE MUST BE DIGIT"}'
printf(ret)
return (
False, ret)
set_error_code('FFFF')
start_time = time.time() * 1000
eflash_loader_cfg_tmp = os.path.join(chip_path, chip_type, 'eflash_loader/eflash_loader_cfg.ini')
options = ['--none', '--flash', '-c', eflash_loader_cfg_tmp]
parser_eflash = eflash_loader_parser_init()
args = parser_eflash.parse_args(options)
config['param']['chip_xtal'] = 'auto'
if chip_type == 'bl602':
config['param']['chip_xtal'] = '40m'
temp_eflash_obj = BL602EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl702':
config['param']['chip_xtal'] = '32m'
temp_eflash_obj = BL702EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl702l':
config['param']['chip_xtal'] = '32m'
temp_eflash_obj = BL702LEflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl808' or chip_type == 'bl606p':
temp_eflash_obj = BL808EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl616' or chip_type == 'wb03':
temp_eflash_obj = BL616EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl628':
temp_eflash_obj = BL628EflashLoader(chip_type, args, config, callback)
else:
temp_eflash_obj = OtherEflashLoader(chip_type, args, config, callback)
result, content = temp_eflash_obj.run_step()
temp_eflash_obj.object_status_clear()
cmd = config['cmd']
length = int(config['len'])
cmd_value = int(cmd, 16)
if cmd_value != 5:
if cmd_value != 53:
if cmd_value != 21:
temp_eflash_obj.close_serial()
ret = 'read register command value not recognize'
printf(ret)
return (
False, ret)
if length > 3:
temp_eflash_obj.close_serial()
ret = 'read register len is too long'
printf(ret)
return (
False, ret)
ret, data = temp_eflash_obj.flash_read_status_reg_process(cmd, length)
if ret:
data = binascii.hexlify(data).decode('utf-8')
if temp_eflash_obj.bflb_serial_object is not None:
temp_eflash_obj.close_serial()
self._temp_task_num = temp_eflash_obj.task_num
return (
ret, data)
except Exception as e:
try:
ret = str(e)
printf('error:' + ret)
return (
False, ret)
finally:
e = None
del e
def program_write_reg(self, config, callback=None):
ret = None
flash_burn_retry = 1
interface = config['param']['interface_type']
device = config['param']['comport_uart']
if interface.lower() == 'uart':
speed = config['param']['speed_uart']
else:
speed = config['param']['speed_jlink']
chip_type = config['param']['chip_type']
try:
if not device:
if interface.lower() == 'uart':
ret = '{"ErrorCode":"FFFF","ErrorMsg":"BFLB INTERFACE HAS NO COM PORT"}'
printf(ret)
return (
False, ret)
if not (config['param']['speed_uart'].isdigit() and config['param']['speed_jlink'].isdigit()):
ret = '{"ErrorCode":"FFFF","ErrorMsg":"BAUDRATE MUST BE DIGIT"}'
printf(ret)
return (
False, ret)
set_error_code('FFFF')
start_time = time.time() * 1000
eflash_loader_cfg_tmp = os.path.join(chip_path, chip_type, 'eflash_loader/eflash_loader_cfg.ini')
options = ['--none', '--flash', '-c', eflash_loader_cfg_tmp]
parser_eflash = eflash_loader_parser_init()
args = parser_eflash.parse_args(options)
config['param']['chip_xtal'] = 'auto'
if chip_type == 'bl602':
config['param']['chip_xtal'] = '40m'
temp_eflash_obj = BL602EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl702':
config['param']['chip_xtal'] = '32m'
temp_eflash_obj = BL702EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl702l':
config['param']['chip_xtal'] = '32m'
temp_eflash_obj = BL702LEflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl808' or chip_type == 'bl606p':
temp_eflash_obj = BL808EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl616' or chip_type == 'wb03':
temp_eflash_obj = BL616EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl628':
temp_eflash_obj = BL628EflashLoader(chip_type, args, config, callback)
else:
temp_eflash_obj = OtherEflashLoader(chip_type, args, config, callback)
result, content = temp_eflash_obj.run_step()
temp_eflash_obj.object_status_clear()
cmd = config['cmd']
length = int(config['len'])
val = config['val']
cmd_value = int(cmd, 16)
if cmd_value != 1:
if cmd_value != 49:
if cmd_value != 17:
temp_eflash_obj.close_serial()
ret = 'write register command value not recognize'
printf(ret)
return (
False, ret)
if length > 3:
temp_eflash_obj.close_serial()
ret = 'write register len is too long'
printf(ret)
return (
False, ret)
ret, data = temp_eflash_obj.flash_write_status_reg_process(cmd, length, val)
temp_eflash_obj.close_serial()
self._temp_task_num = temp_eflash_obj.task_num
return (
ret, data)
except Exception as e:
try:
ret = str(e)
printf('error:' + ret)
return (
False, ret)
finally:
e = None
del e
def read_flash_thread(self, config, callback=None):
ret = None
flash_burn_retry = 1
interface = config['param']['interface_type']
device = config['param']['comport_uart']
if interface.lower() == 'uart':
speed = config['param']['speed_uart']
else:
speed = config['param']['speed_jlink']
chip_type = config['param']['chip_type']
try:
try:
if not device:
if interface.lower() == 'uart':
ret = '{"ErrorCode":"FFFF","ErrorMsg":"BFLB INTERFACE HAS NO COM PORT"}'
printf(ret)
return (
False, ret)
if not (config['param']['speed_uart'].isdigit() and config['param']['speed_jlink'].isdigit()):
ret = '{"ErrorCode":"FFFF","ErrorMsg":"BAUDRATE MUST BE DIGIT"}'
printf(ret)
return (
False, ret)
set_error_code('FFFF')
start_time = time.time() * 1000
eflash_loader_cfg_tmp = os.path.join(chip_path, chip_type, 'eflash_loader/eflash_loader_cfg.ini')
if verify_hex_num(config['start_addr'][2:]) is True:
if config['start_addr'][0:2] == '0x':
start = config['start_addr'][2:]
else:
printf('Error, start_addr is HEX data, must begin with 0x')
ret = 'start_addr is HEX data, must begin with 0x'
else:
printf('Error, Please check start_addr hex data')
ret = 'Please check start_addr hex data'
if verify_hex_num(config['end_addr'][2:]) is True:
if config['end_addr'][0:2] == '0x':
end = config['end_addr'][2:]
else:
printf('Error, end_addr is HEX data, must begin with 0x')
ret = 'end_addr is HEX data, must begin with 0x'
else:
printf('Error, Please check end_addr hex data')
ret = 'Please check end_addr hex data'
if int(start, 16) >= int(end, 16):
printf('Error, Start addr must less than end addr')
ret = 'Start addr must less than end addr'
if ret is not None:
return ret
printf('Save as flash.bin')
options = ['--read', '--flash', '--start=' + start, '--end=' + end, '--file=flash.bin', '-c', eflash_loader_cfg_tmp]
parser_eflash = eflash_loader_parser_init()
args = parser_eflash.parse_args(options)
config['param']['chip_xtal'] = 'auto'
if chip_type == 'bl602':
config['param']['chip_xtal'] = '40m'
temp_eflash_obj = BL602EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl702':
config['param']['chip_xtal'] = '32m'
temp_eflash_obj = BL702EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl702l':
config['param']['chip_xtal'] = '32m'
temp_eflash_obj = BL702LEflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl808' or chip_type == 'bl606p':
temp_eflash_obj = BL808EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl616' or chip_type == 'wb03':
temp_eflash_obj = BL616EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl628':
temp_eflash_obj = BL628EflashLoader(chip_type, args, config, callback)
else:
temp_eflash_obj = OtherEflashLoader(chip_type, args, config, callback)
result, content = temp_eflash_obj.run_step()
temp_eflash_obj.object_status_clear()
self._temp_task_num = temp_eflash_obj.task_num
temp_result = self.judge_result(temp_eflash_obj, result, args, start_time)
if temp_result:
return True
printf('Burn Retry')
flash_burn_retry -= 1
printf('Burn return with retry fail')
local_log_save('log', temp_eflash_obj.input_macaddr)
ret = errorcode_msg(self._temp_task_num)
except Exception as e:
try:
ret = str(e)
finally:
e = None
del e
finally:
return ret
def erase_flash_thread(self, config, callback=None):
options = ''
start = ''
end = ''
ret = None
flash_burn_retry = 1
interface = config['param']['interface_type']
device = config['param']['comport_uart']
if interface.lower() == 'uart':
speed = config['param']['speed_uart']
else:
speed = config['param']['speed_jlink']
chip_type = config['param']['chip_type']
start_time = time.time() * 1000
try:
try:
if verify_hex_num(config['start_addr'][2:]) is True:
if config['start_addr'][0:2] == '0x':
start = config['start_addr'][2:]
else:
printf('Error, start_addr is HEX data, must begin with 0x')
ret = 'start_addr is HEX data, must begin with 0x'
else:
if config['whole_chip'] is False:
printf('Error, Please check start_addr hex data')
ret = 'Please check start_addr hex data'
if verify_hex_num(config['end_addr'][2:]) is True:
if config['end_addr'][0:2] == '0x':
end = config['end_addr'][2:]
else:
printf('Error, end_addr is HEX data, must begin with 0x')
ret = 'end_addr is HEX data, must begin with 0x'
else:
if config['whole_chip'] is False:
printf('Error, Please check end_addr hex data')
ret = 'Please check end_addr hex data'
if config['whole_chip'] is False:
if int(start, 16) >= int(end, 16):
printf('Error, Start addr must less than end addr')
ret = 'Start addr must less than end addr'
if ret is not None:
return ret
eflash_loader_cfg_tmp = os.path.join(chip_path, chip_type, 'eflash_loader/eflash_loader_cfg.ini')
if config['whole_chip'] is True:
options = [
'--erase','--flash','--end=0','-c',eflash_loader_cfg_tmp]
else:
options = [
'--erase', '--flash', '--start=' + start, '--end=' + end, '-c', eflash_loader_cfg_tmp]
parser_eflash = eflash_loader_parser_init()
args = parser_eflash.parse_args(options)
config['param']['chip_xtal'] = 'auto'
if chip_type == 'bl602':
config['param']['chip_xtal'] = '40m'
temp_eflash_obj = BL602EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl702':
config['param']['chip_xtal'] = '32m'
temp_eflash_obj = BL702EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl702l':
config['param']['chip_xtal'] = '32m'
temp_eflash_obj = BL702LEflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl808' or chip_type == 'bl606p':
temp_eflash_obj = BL808EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl616' or chip_type == 'wb03':
temp_eflash_obj = BL616EflashLoader(chip_type, args, config, callback)
else:
if chip_type == 'bl628':
temp_eflash_obj = BL628EflashLoader(chip_type, args, config, callback)
else:
temp_eflash_obj = OtherEflashLoader(chip_type, args, config, callback)
result, content = temp_eflash_obj.run_step()
temp_eflash_obj.object_status_clear()
self._temp_task_num = temp_eflash_obj.task_num
temp_result = self.judge_result(temp_eflash_obj, result, args, start_time)
if temp_result:
return True
printf('Burn Retry')
flash_burn_retry -= 1
printf('Burn return with retry fail')
local_log_save('log', temp_eflash_obj.input_macaddr)
ret = errorcode_msg(self._temp_task_num)
except Exception as e:
try:
ret = str(e)
finally:
e = None
del e
finally:
return ret
if __name__ == '__main__':
act = 'download'
config_value_dict = {
'interface_type': 'uart',
'comport_uart': 'COM28',
'speed_uart': '2000000',
'chip_xtal': '40M',
'verify': 'False',
'ckb_erase_all': 'False'}
config = {'param': config_value_dict}
iel = InterfaceEflashLoader()
iel.run(act, config)
# okay decompiling ./libs/bflb_interface_eflash_loader.pyc

View File

@ -0,0 +1,401 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: libs/bflb_interface_jlink.py
import re, os, sys, time, binascii, traceback, struct, subprocess, pylink
from libs import bflb_utils
from libs.bflb_utils import app_path
python_version = struct.calcsize('P') * 8
if python_version == 64:
path_dll = os.path.join(app_path, 'utils/jlink', 'JLink_x64.dll')
else:
path_dll = os.path.join(app_path, 'utils/jlink', 'JLinkARM.dll')
class BflbJLinkPort(object):
def __init__(self):
self._speed = 5000
self._rx_timeout = 10000
self._jlink_shake_hand_addr = '20000000'
self._jlink_data_addr = '20000004'
self._inited = False
self._chiptype = 'bl60x'
self._chipname = 'bl60x'
self._jlink_run_addr = '22010000'
def if_init(self, device, rate, chiptype='bl60x', chipname='bl60x'):
if self._inited is False:
sub_module = __import__(('libs.base.' + chiptype), fromlist=[chiptype])
self._jlink_shake_hand_addr = sub_module.jlink_load_cfg.jlink_shake_hand_addr
self._jlink_data_addr = sub_module.jlink_load_cfg.jlink_data_addr
if sys.platform == 'win32':
obj_dll = pylink.Library(dllpath=path_dll)
self._jlink = pylink.JLink(lib=obj_dll)
self.jlink_path = os.path.join(app_path, 'utils/jlink', 'JLink.exe')
else:
self._jlink = pylink.JLink()
self.jlink_path = 'JLinkExe'
match = re.search('\\d{8,10}', device, re.I)
if match is not None:
bflb_utils.printf(device)
self._jlink.open(serial_no=(int(device)))
else:
self._jlink.open()
tif_set = sub_module.jlink_load_cfg.jlink_set_tif
self._jlink.set_tif(tif_set)
self._speed = rate
core_type = sub_module.jlink_load_cfg.jlink_core_type
self._jlink.connect(core_type, rate)
self._inited = True
self._chiptype = chiptype
self._chipname = chipname
self._jlink_run_addr = sub_module.jlink_load_cfg.jlink_run_addr
self._device = device
def repeat_init(self, device, rate, chiptype='bl60x', chipname='bl60x'):
if self._inited is False:
sub_module = __import__(('libs.base.' + chiptype), fromlist=[chiptype])
self._jlink_shake_hand_addr = sub_module.jlink_load_cfg.jlink_shake_hand_addr
self._jlink_data_addr = sub_module.jlink_load_cfg.jlink_data_addr
if sys.platform == 'win32':
obj_dll = pylink.Library(dllpath=path_dll)
self._jlink = pylink.JLink(lib=obj_dll)
self.jlink_path = os.path.join(app_path, 'utils/jlink', 'JLink.exe')
else:
self._jlink = pylink.JLink()
self.jlink_path = 'JLinkExe'
match = re.search('\\d{8,10}', device, re.I)
if match is not None:
bflb_utils.printf(device)
self._jlink.open(serial_no=(int(device)))
else:
self._jlink.open()
tif_set = sub_module.jlink_load_cfg.jlink_set_tif
self._jlink.set_tif(tif_set)
self._speed = rate
core_type = sub_module.jlink_load_cfg.jlink_core_type
self._jlink.connect(core_type, rate)
self._inited = True
self._chiptype = chiptype
self._chipname = chipname
self._jlink_run_addr = sub_module.jlink_load_cfg.jlink_run_addr
self._device = device
def if_clear_buf(self):
pass
def clear_buf(self):
pass
def if_set_rx_timeout(self, val):
self._rx_timeout = val * 1000
def set_timeout(self, val):
self._rx_timeout = val * 1000
def if_get_rate(self):
return self._speed
def halt_cpu(self):
if self._jlink.halted() is False:
self._jlink.halt()
if self._jlink.halted():
return True
bflb_utils.printf("couldn't halt cpu")
return False
def reset_cpu(self, ms=0, halt=True):
if self._chiptype != 'bl60x':
self._jlink.set_reset_pin_low()
self._jlink.set_reset_pin_high()
return self._jlink.reset(ms, False)
def set_pc_msp(self, pc, msp):
if self._jlink.halted() is False:
self._jlink.halt()
if self._jlink.halted():
if self._chiptype == 'bl602' or self._chiptype == 'bl702' or self._chiptype == 'bl702l':
jlink_script = 'jlink.cmd'
fp = open(jlink_script, 'w+')
cmd = 'h\r\nSetPC ' + str(self._jlink_run_addr) + '\r\nexit'
bflb_utils.printf(cmd)
fp.write(cmd)
fp.close()
if self._device:
jlink_cmd = self.jlink_path + ' -device RISC-V -Speed {0} -SelectEmuBySN {1} -IF JTAG -jtagconf -1,-1 -autoconnect 1 -CommanderScript jlink.cmd'.format(str(self._speed), str(self._device))
else:
jlink_cmd = self.jlink_path + ' -device RISC-V -Speed {0} -IF JTAG -jtagconf -1,-1 -autoconnect 1 -CommanderScript jlink.cmd'.format(str(self._speed))
bflb_utils.printf(jlink_cmd)
p = subprocess.Popen(jlink_cmd, shell=True, stdin=(subprocess.PIPE), stdout=(subprocess.PIPE), stderr=(subprocess.PIPE))
out, err = p.communicate()
bflb_utils.printf(out, err)
os.remove(jlink_script)
else:
self._jlink.register_write(15, int(pc, 16))
self._jlink.register_write(13, int(msp, 16))
self._jlink.restart()
else:
bflb_utils.printf("couldn't halt cpu")
def if_write(self, data_send):
self.if_raw_write(self._jlink_data_addr, data_send)
data_list = []
data_list.append(int('59445248', 16))
self._jlink.memory_write((int(self._jlink_shake_hand_addr, 16)), data_list, nbits=32)
def write(self, data_send):
self.if_raw_write(self._jlink_data_addr, data_send)
data_list = []
data_list.append(int('59445248', 16))
self._jlink.memory_write((int(self._jlink_shake_hand_addr, 16)), data_list, nbits=32)
def if_raw_write(self, addr, data_send):
addr_int = int(addr, 16)
len2 = len(data_send) % 4
len1 = len(data_send) - len2
if len1 != 0:
data_list = []
for i in range(int(len1 / 4)):
data_list.append(data_send[4 * i] + (data_send[4 * i + 1] << 8) + (data_send[4 * i + 2] << 16) + (data_send[4 * i + 3] << 24))
self._jlink.memory_write(addr_int, data_list, nbits=32)
if len2 != 0:
data_list = []
for i in range(len2):
data_list.append(data_send[len1 + i])
self._jlink.memory_write((addr_int + len1), data_list, nbits=8)
def if_raw_write8(self, addr, data_send):
data_list = []
for data in data_send:
data_list.append(data)
self._jlink.memory_write((int(addr, 16)), data_list, nbits=8)
def if_raw_write16(self, addr, data_send):
data_list = []
for i in range(int(len(data_send) / 2)):
data_list.append(data_send[2 * i] + (data_send[2 * i + 1] << 8))
self._jlink.memory_write((int(addr, 16)), data_list, nbits=16)
def if_raw_write32(self, addr, data_send):
data_list = []
for i in range(int(len(data_send) / 4)):
data_list.append(data_send[4 * i] + (data_send[4 * i + 1] << 8) + (data_send[4 * i + 2] << 16) + (data_send[4 * i + 3] << 24))
self._jlink.memory_write((int(addr, 16)), data_list, nbits=32)
def if_read(self, data_len):
start_time = time.time() * 1000
while True:
ready = self._jlink.memory_read((int(self._jlink_shake_hand_addr, 16)), 1, nbits=32)
if len(ready) >= 1:
if ready[0] == int('4B434153', 16):
break
elapsed = time.time() * 1000 - start_time
if elapsed >= self._rx_timeout:
return (0, 'waiting response time out'.encode('utf-8'))
else:
time.sleep(0.001)
data = self.if_raw_read(self._jlink_data_addr, data_len)
if len(data) != data_len:
return (0, data)
return (1, data)
def read(self, data_len):
start_time = time.time() * 1000
while True:
ready = self._jlink.memory_read((int(self._jlink_shake_hand_addr, 16)), 1, nbits=32)
if len(ready) >= 1:
if ready[0] == int('4B434153', 16):
break
elapsed = time.time() * 1000 - start_time
if elapsed >= self._rx_timeout:
return (0, 'waiting response time out'.encode('utf-8'))
else:
time.sleep(0.001)
data = self.if_raw_read(self._jlink_data_addr, data_len)
if len(data) != data_len:
return (0, data)
return (1, data)
def if_raw_read(self, addr, data_len):
addr_int = int(addr, 16)
if addr_int % 4 == 0:
len2 = data_len % 4
len1 = data_len - len2
data1 = bytearray(0)
data2 = bytearray(0)
if len1 != 0:
data1 = self._jlink.memory_read(addr_int, (int(len1 / 4)), nbits=32)
if len2 != 0:
data2 = self._jlink.memory_read((addr_int + len1), len2, nbits=8)
data = bytearray(0)
for tmp in data1:
data += bflb_utils.int_to_4bytearray_l(tmp)
data += bytearray(data2)
return data
return self.if_raw_read8(addr, data_len)
def if_raw_read8(self, addr, data_len):
data = self._jlink.memory_read((int(addr, 16)), data_len, nbits=8)
return bytearray(data)
def if_raw_read16(self, addr, data_len):
raw_data = self._jlink.memory_read((int(addr, 16)), (data_len / 2), nbits=16)
data = bytearray(0)
for tmp in raw_data:
data += bflb_utils.int_to_2bytearray_l(tmp)
return bytearray(data)
def if_raw_read32(self, addr, data_len):
raw_data = self._jlink.memory_read((int(addr, 16)), (data_len / 4), nbits=32)
data = bytearray(0)
for tmp in raw_data:
data += bflb_utils.int_to_4bytearray_l(tmp)
return bytearray(data)
def if_shakehand(self, do_reset=False, reset_hold_time=100, shake_hand_delay=100, reset_revert=True, cutoff_time=0, shake_hand_retry=2, isp_timeout=0, boot_load=False):
self.if_write(bytearray(1))
success, ack = self.if_read(2)
bflb_utils.printf(binascii.hexlify(ack))
if ack.find(b'O') != -1 or ack.find(b'K') != -1:
time.sleep(0.03)
return 'OK'
return 'FL'
def if_close(self):
if self._jlink:
self._jlink.close()
self._inited = False
def close(self):
if self._jlink:
self._jlink.close()
self._inited = False
def if_deal_ack(self):
success, ack = self.if_read(2)
if success == 0:
bflb_utils.printf('ack:' + str(binascii.hexlify(ack)))
return ack.decode('utf-8')
if ack.find(b'O') != -1 or ack.find(b'K') != -1:
return 'OK'
if ack.find(b'P') != -1 or ack.find(b'D') != -1:
return 'PD'
success, err_code = self.if_read(4)
if success == 0:
bflb_utils.printf('err_code:' + str(binascii.hexlify(err_code)))
return 'FL'
err_code_str = str(binascii.hexlify(err_code[3:4] + err_code[2:3]).decode('utf-8'))
ack = 'FL'
try:
ret = ack + err_code_str + '(' + bflb_utils.get_bflb_error_code(err_code_str) + ')'
except Exception:
ret = ack + err_code_str + ' unknown'
bflb_utils.printf(ret)
return ret
def deal_ack(self):
success, ack = self.if_read(2)
if success == 0:
bflb_utils.printf('ack:' + str(binascii.hexlify(ack)))
return ack.decode('utf-8')
if ack.find(b'O') != -1 or ack.find(b'K') != -1:
return 'OK'
if ack.find(b'P') != -1 or ack.find(b'D') != -1:
return 'PD'
success, err_code = self.if_read(4)
if success == 0:
bflb_utils.printf('err_code:' + str(binascii.hexlify(err_code)))
return 'FL'
err_code_str = str(binascii.hexlify(err_code[3:4] + err_code[2:3]).decode('utf-8'))
ack = 'FL'
try:
ret = ack + err_code_str + '(' + bflb_utils.get_bflb_error_code(err_code_str) + ')'
except Exception:
ret = ack + err_code_str + ' unknown'
bflb_utils.printf(ret)
return ret
def if_deal_response(self):
ack = self.if_deal_ack()
if ack == 'OK':
success, len_bytes = self.if_read(4)
if success == 0:
bflb_utils.printf('Get length error')
bflb_utils.printf(binascii.hexlify(len_bytes))
return (
'Get length error', len_bytes)
tmp = bflb_utils.bytearray_reverse(len_bytes[2:4])
data_len = bflb_utils.bytearray_to_int(tmp)
success, data_bytes = self.if_read(data_len + 4)
if success == 0:
bflb_utils.printf('Read data error')
return (
'Read data error', data_bytes)
data_bytes = data_bytes[4:]
if len(data_bytes) != data_len:
bflb_utils.printf('Not get excepted length')
return (
'Not get excepted length', data_bytes)
return (ack, data_bytes)
bflb_utils.printf('Not ack OK')
bflb_utils.printf(ack)
return (
ack, None)
def deal_response(self):
ack = self.if_deal_ack()
if ack == 'OK':
success, len_bytes = self.if_read(4)
if success == 0:
bflb_utils.printf('Get length error')
bflb_utils.printf(binascii.hexlify(len_bytes))
return (
'Get length error', len_bytes)
tmp = bflb_utils.bytearray_reverse(len_bytes[2:4])
data_len = bflb_utils.bytearray_to_int(tmp)
success, data_bytes = self.if_read(data_len + 4)
if success == 0:
bflb_utils.printf('Read data error')
return (
'Read data error', data_bytes)
data_bytes = data_bytes[4:]
if len(data_bytes) != data_len:
bflb_utils.printf('Not get excepted length')
return (
'Not get excepted length', data_bytes)
return (ack, data_bytes)
bflb_utils.printf('Not ack OK')
bflb_utils.printf(ack)
return (
ack, None)
if __name__ == '__main__':
try:
eflash_loader_t = BflbJLinkPort()
eflash_loader_t.if_init('', 1000, 'bl602')
bflb_utils.printf('reset test')
res = eflash_loader_t.reset_cpu(0, False)
bflb_utils.printf(res)
except Exception as e:
try:
NUM_ERR = 5
bflb_utils.printf(e)
traceback.print_exc(limit=NUM_ERR, file=(sys.stdout))
finally:
e = None
del e
# okay decompiling ./libs/bflb_interface_jlink.pyc

View File

@ -0,0 +1,425 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: libs/bflb_interface_openocd.py
import os, time, binascii, subprocess, threading, telnetlib, serial
from libs import bflb_utils
from libs.bflb_utils import app_path
openocd_path = os.path.join(app_path, 'utils/openocd', 'openocd.exe')
class ThreadOpenocdServer(threading.Thread):
def __init__(self, chiptype='bl602', device='rv_dbg_plus', serial=None):
threading.Thread.__init__(self)
self.timeToQuit = threading.Event()
self.timeToQuit.clear()
self._chiptype = chiptype
self._device = device
self._serial = serial
bflb_utils.printf('SN is ' + str(self._serial))
def stop(self):
self.timeToQuit.set()
def run(self):
cmd = ''
if self._serial:
cmd_ftdi_serial = ' -c "ftdi_serial \\"' + self._serial + '\\""'
else:
cmd_ftdi_serial = ''
if self._device == 'rv_dbg_plus':
if self._chiptype == 'bl602':
cmd = openocd_path + ' -f ' + app_path + '/utils/openocd/if_rv_dbg_plus.cfg ' + cmd_ftdi_serial + ' -f ' + app_path + '/utils/openocd/tgt_602.cfg'
else:
cmd = openocd_path + ' -f ' + app_path + '/utils/openocd/if_rv_dbg_plus.cfg' + cmd_ftdi_serial + ' -f ' + app_path + '/utils/openocd/tgt_702.cfg'
else:
if self._device == 'ft2232hl':
if self._chiptype == 'bl602':
cmd = openocd_path + ' -f ' + app_path + '/utils/openocd/if_bflb_dbg.cfg' + cmd_ftdi_serial + ' -f ' + app_path + '/utils/openocd/tgt_602.cfg'
else:
cmd = openocd_path + ' -f ' + app_path + '/utils/openocd/if_bflb_dbg.cfg' + cmd_ftdi_serial + ' -f ' + app_path + '/utils/openocd/tgt_702.cfg'
else:
cmd = openocd_path + ' -f ' + app_path + '/utils/openocd/openocd-usb-sipeed.cfg ' + cmd_ftdi_serial
bflb_utils.printf(cmd)
p = subprocess.Popen(cmd, shell=True, stdin=(subprocess.PIPE), stdout=(subprocess.PIPE), stderr=(subprocess.PIPE))
out, err = p.communicate()
bflb_utils.printf(out)
class BflbOpenocdPort(object):
def __init__(self):
self._speed = 5000
self._rx_timeout = 10000
self._openocd_shake_hand_addr = '20000000'
self._openocd_data_addr = '20000004'
self._inited = False
self._chiptype = 'bl60x'
self._chipname = 'bl60x'
self._openocd_run_addr = '22010000'
self.tn = telnetlib.Telnet()
def if_init(self, device, sn, rate, chiptype='bl60x', chipname='bl60x'):
if self._inited is False:
sub_module = __import__(('libs.base.' + chiptype), fromlist=[chiptype])
self._openocd_shake_hand_addr = sub_module.openocd_load_cfg.openocd_shake_hand_addr
self._openocd_data_addr = sub_module.openocd_load_cfg.openocd_data_addr
self._openocd_run_addr = sub_module.openocd_load_cfg.openocd_run_addr
self._speed = rate
self._inited = True
self._chiptype = chiptype
self._chipname = chipname
if sn:
serial = 'FactoryAIOT Prog ' + str(sn)
else:
serial = None
self._openocd_th = None
self._openocd_th = ThreadOpenocdServer(chiptype, device, serial)
self._openocd_th.setDaemon(True)
self._openocd_th.start()
try:
self.tn.open('127.0.0.1', port=4444, timeout=10)
self.tn.write(('adapter speed ' + str(rate)).encode('ascii') + b'\n')
self.tn.write('WaitCmd\n'.encode('ascii'))
self.tn.read_until(('"WaitCmd"'.encode('ascii')), timeout=10)
except Exception:
bflb_utils.printf('Failed to connect openocd server')
bflb_utils.set_error_code('0009')
self.if_close()
return False
def repeat_init(self, device, sn, rate, chiptype='bl60x', chipname='bl60x'):
if self._inited is False:
sub_module = __import__(('libs.base.' + chiptype), fromlist=[chiptype])
self._openocd_shake_hand_addr = sub_module.openocd_load_cfg.openocd_shake_hand_addr
self._openocd_data_addr = sub_module.openocd_load_cfg.openocd_data_addr
self._openocd_run_addr = sub_module.openocd_load_cfg.openocd_run_addr
self._speed = rate
self._inited = True
self._chiptype = chiptype
self._chipname = chipname
if sn:
serial = 'FactoryAIOT Prog ' + str(sn)
else:
serial = None
self._openocd_th = None
self._openocd_th = ThreadOpenocdServer(chiptype, device, serial)
self._openocd_th.setDaemon(True)
self._openocd_th.start()
try:
self.tn.open('127.0.0.1', port=4444, timeout=10)
self.tn.write(('adapter speed ' + str(rate)).encode('ascii') + b'\n')
self.tn.write('WaitCmd\n'.encode('ascii'))
self.tn.read_until(('"WaitCmd"'.encode('ascii')), timeout=10)
except Exception:
bflb_utils.printf('Failed to connect openocd server')
bflb_utils.set_error_code('0009')
self.if_close()
return False
def if_clear_buf(self):
pass
def clear_buf(self):
pass
def if_set_rx_timeout(self, val):
self._rx_timeout = val * 1000
def set_timeout(self, val):
self._rx_timeout = val * 1000
def if_get_rate(self):
return self._speed
def halt_cpu(self):
self.tn.write('halt'.encode('ascii') + b'\n')
return True
def reset_cpu(self, ms=0, halt=True):
if halt:
self.halt_cpu()
self.tn.write('reset'.encode('ascii') + b'\n')
def set_pc_msp(self, pc, msp):
self.halt_cpu()
if self._chiptype == 'bl602' or self._chiptype == 'bl702' or self._chiptype == 'bl702l':
self.tn.write(('reg pc 0x' + self._openocd_run_addr).encode('ascii') + b'\n')
self.tn.write('resume'.encode('ascii') + b'\n')
def if_raw_write(self, addr, data_send):
addr_int = int(addr, 16)
if len(data_send) > 32:
fp = open('openocd_load_data.bin', 'wb+')
fp.write(data_send)
fp.close()
self.tn.write(('load_image openocd_load_data.bin ' + hex(addr_int)).encode('ascii') + b'\n')
else:
for data in data_send:
self.tn.write(('mwb ' + hex(addr_int) + ' ' + hex(data)).encode('ascii') + b'\n')
addr_int += 1
def if_write(self, data_send):
self.if_raw_write(self._openocd_data_addr, data_send)
self.if_raw_write(self._openocd_shake_hand_addr, bytearray.fromhex('48524459'))
def write(self, data_send):
self.if_raw_write(self._openocd_data_addr, data_send)
self.if_raw_write(self._openocd_shake_hand_addr, bytearray.fromhex('48524459'))
def read_data_parse(self, buff, aligned):
strdata = buff.decode().strip()
data = bytearray(0)
index = strdata.find(': ')
if aligned is True:
lstr = strdata[index + 2:strdata.find('WaitCmd') - 6].split('0x')
for l in lstr:
ldata = []
if l.find(': ') != -1:
ldata = l[9:].split(' ')
else:
ldata = l.split(' ')
for d in ldata:
if len(d) != 8:
continue
else:
hexstr = d[6:8] + d[4:6] + d[2:4] + d[0:2]
data += bflb_utils.hexstr_to_bytearray(hexstr)
else:
data += bflb_utils.hexstr_to_bytearray(strdata[index + 2:strdata.find('WaitCmd') - 6].replace(' ', ''))
return data
def if_addr_unaligned_read(self, addr, data_len):
addr_int = int(addr, 16)
data = bytearray(0)
dummy = self.tn.read_very_eager().decode('utf-8')
self.tn.write(('mdb ' + hex(addr_int) + ' ' + hex(data_len) + '\n').encode('ascii'))
self.tn.write('WaitCmd\n'.encode('ascii'))
ret = self.tn.read_until(('"WaitCmd"'.encode('ascii')), timeout=10)
data += self.read_data_parse(ret, False)
return data
def if_addr_aligned_read(self, addr, data_len):
addr_int = int(addr, 16)
leftlen = data_len
data = bytearray(0)
dummy = self.tn.read_very_eager().decode('utf-8')
self.tn.write(('mdw ' + hex(addr_int) + ' ' + hex(data_len // 4) + '\n').encode('ascii'))
self.tn.write('WaitCmd\n'.encode('ascii'))
ret = self.tn.read_until(('"WaitCmd"'.encode('ascii')), timeout=10)
data += self.read_data_parse(ret, True)
addr_int = addr_int + data_len // 4 * 4
leftlen = data_len - data_len // 4 * 4
if leftlen != 0:
data += self.if_addr_unaligned_read(hex(addr_int)[2:], leftlen)
return data
def if_raw_read(self, addr, data_len):
data = bytearray(0)
if data_len <= 4:
return self.if_addr_unaligned_read(addr, data_len)
addr_int = int(addr, 16)
pre_read_len = 4 - addr_int % 4
if pre_read_len != 0:
data += self.if_addr_unaligned_read(addr, pre_read_len)
data += self.if_addr_aligned_read(hex(addr_int + pre_read_len), data_len - pre_read_len)
return data[:data_len]
def if_read(self, data_len):
start_time = time.time() * 1000
while True:
ready = self.if_raw_read(self._openocd_shake_hand_addr, 16)
if ready[0:4] == bytearray([83, 65, 67, 75]):
break
else:
elapsed = time.time() * 1000 - start_time
if elapsed >= self._rx_timeout:
return (0, 'waiting response time out'.encode('utf-8'))
time.sleep(0.001)
data = self.if_raw_read(self._openocd_data_addr, data_len)
if len(data) != data_len:
return (0, data)
return (1, data)
def read(self, data_len):
start_time = time.time() * 1000
while True:
ready = self.if_raw_read(self._openocd_shake_hand_addr, 16)
if ready[0:4] == bytearray([83, 65, 67, 75]):
break
else:
elapsed = time.time() * 1000 - start_time
if elapsed >= self._rx_timeout:
return (0, 'waiting response time out'.encode('utf-8'))
time.sleep(0.001)
data = self.if_raw_read(self._openocd_data_addr, data_len)
if len(data) != data_len:
return (0, data)
return (1, data)
def if_clear_buff(self):
self.tn.write('WaitCmd\n'.encode('ascii'))
self.tn.read_until(('"WaitCmd"'.encode('ascii')), timeout=10)
def clear_buff(self):
self.tn.write('WaitCmd\n'.encode('ascii'))
self.tn.read_until(('"WaitCmd"'.encode('ascii')), timeout=10)
def if_shakehand(self, do_reset=False, reset_hold_time=100, shake_hand_delay=100, reset_revert=True, cutoff_time=0, shake_hand_retry=2, isp_timeout=0, boot_load=False):
self.if_clear_buff()
self.if_write(bytearray(1))
success, ack = self.if_read(2)
bflb_utils.printf(binascii.hexlify(ack))
if ack.find(b'O') != -1 or ack.find(b'K') != -1:
time.sleep(0.03)
return 'OK'
return 'FL'
def if_close(self):
if self.tn.get_socket():
self.tn.write('shutdown\n'.encode('ascii'))
time.sleep(0.05)
self.tn.close()
if self._openocd_th:
self._openocd_th.stop()
self._inited = False
def close(self):
if self.tn.get_socket():
self.tn.write('shutdown\n'.encode('ascii'))
time.sleep(0.05)
self.tn.close()
if self._openocd_th:
self._openocd_th.stop()
self._inited = False
def if_deal_ack(self):
success, ack = self.if_read(2)
if success == 0:
bflb_utils.printf('ack:' + str(binascii.hexlify(ack)))
return ack.decode('utf-8')
if ack.find(b'O') != -1 or ack.find(b'K') != -1:
return 'OK'
if ack.find(b'P') != -1 or ack.find(b'D') != -1:
return 'PD'
success, err_code = self.if_read(4)
if success == 0:
bflb_utils.printf('err_code:' + str(binascii.hexlify(err_code)))
return 'FL'
err_code_str = str(binascii.hexlify(err_code[3:4] + err_code[2:3]).decode('utf-8'))
ack = 'FL'
try:
ret = ack + err_code_str + '(' + bflb_utils.get_bflb_error_code(err_code_str) + ')'
except Exception:
ret = ack + err_code_str + ' unknown'
bflb_utils.printf(ret)
return ret
def deal_ack(self):
success, ack = self.if_read(2)
if success == 0:
bflb_utils.printf('ack:' + str(binascii.hexlify(ack)))
return ack.decode('utf-8')
if ack.find(b'O') != -1 or ack.find(b'K') != -1:
return 'OK'
if ack.find(b'P') != -1 or ack.find(b'D') != -1:
return 'PD'
success, err_code = self.if_read(4)
if success == 0:
bflb_utils.printf('err_code:' + str(binascii.hexlify(err_code)))
return 'FL'
err_code_str = str(binascii.hexlify(err_code[3:4] + err_code[2:3]).decode('utf-8'))
ack = 'FL'
try:
ret = ack + err_code_str + '(' + bflb_utils.get_bflb_error_code(err_code_str) + ')'
except Exception:
ret = ack + err_code_str + ' unknown'
bflb_utils.printf(ret)
return ret
def if_deal_response(self):
ack = self.if_deal_ack()
if ack == 'OK':
success, len_bytes = self.if_read(4)
if success == 0:
bflb_utils.printf('Get length error')
bflb_utils.printf(binascii.hexlify(len_bytes))
return (
'Get length error', len_bytes)
tmp = bflb_utils.bytearray_reverse(len_bytes[2:4])
data_len = bflb_utils.bytearray_to_int(tmp)
success, data_bytes = self.if_read(data_len + 4)
if success == 0:
bflb_utils.printf('Read data error')
return (
'Read data error', data_bytes)
data_bytes = data_bytes[4:]
if len(data_bytes) != data_len:
bflb_utils.printf('Not get excepted length')
return (
'Not get excepted length', data_bytes)
return (ack, data_bytes)
bflb_utils.printf('Not ack OK')
bflb_utils.printf(ack)
return (
ack, None)
def deal_response(self):
ack = self.if_deal_ack()
if ack == 'OK':
success, len_bytes = self.if_read(4)
if success == 0:
bflb_utils.printf('Get length error')
bflb_utils.printf(binascii.hexlify(len_bytes))
return (
'Get length error', len_bytes)
tmp = bflb_utils.bytearray_reverse(len_bytes[2:4])
data_len = bflb_utils.bytearray_to_int(tmp)
success, data_bytes = self.if_read(data_len + 4)
if success == 0:
bflb_utils.printf('Read data error')
return (
'Read data error', data_bytes)
data_bytes = data_bytes[4:]
if len(data_bytes) != data_len:
bflb_utils.printf('Not get excepted length')
return (
'Not get excepted length', data_bytes)
return (ack, data_bytes)
bflb_utils.printf('Not ack OK')
bflb_utils.printf(ack)
return (
ack, None)
if __name__ == '__main__':
eflash_loader_t = BflbOpenocdPort()
eflash_loader_t.if_init('', 100, 'bl60x')
bflb_utils.printf('read test')
bflb_utils.printf(eflash_loader_t.if_raw_read('21000000', 2))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000000', 4))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000000', 10))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000000', 16))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000001', 2))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000001', 4))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000001', 10))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000001', 16))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000002', 2))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000002', 4))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000002', 10))
bflb_utils.printf(eflash_loader_t.if_raw_read('21000002', 16))
bflb_utils.printf('write test')
data = bytearray([
1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,
4])
eflash_loader_t.if_raw_write('42020000', data)
bflb_utils.printf(eflash_loader_t.if_raw_read('42020000', 62))
# okay decompiling ./libs/bflb_interface_openocd.pyc

476
libs/bflb_utils.py Normal file
View File

@ -0,0 +1,476 @@
import os
import sys
import re
import time
import shutil
import binascii
import struct
import random
import socket
import threading
import datetime
import hashlib
import argparse
import traceback
import platform
import codecs
from glob import glob
import pylink
from serial import Serial
from Crypto.Util import Counter
from Crypto.Cipher import AES
try:
from PySide2 import QtCore
qt_sign = True
except ImportError:
qt_sign = False
try:
from serial.tools.list_ports import comports
except ImportError:
pass
if getattr(sys, 'frozen', False):
app_path = os.path.dirname(sys.executable)
else:
app_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
chip_path = os.path.join(app_path, 'chips')
python_version = struct.calcsize('P')*8
if python_version == 64:
path_dll = os.path.join(app_path, 'utils/jlink', 'JLink_x64.dll')
else:
path_dll = os.path.join(app_path, 'utils/jlink', 'JLinkARM.dll')
try:
import changeconf as cgc
conf_sign = True
except ImportError:
cgc = None
conf_sign = False
PY2 = sys.version_info[0] == 2
udp_clinet_dict = {}
udp_send_log = False
udp_log_local_echo = False
udp_socket_server = None
error_code_num = 'FFFF'
error_code_num_task = ['FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF', 'FFFF']
local_log_en = True
local_log_data = ''
if conf_sign:
bflb_error_code = {'0000': 'SUCCESS', '0001': 'FLASH_INIT_ERROR', '0002': 'FLASH_ERASE_PARA_ERROR', '0003': 'FLASH_ERASE_ERROR', '0004': 'FLASH_WRITE_PARA_ERROR', '0005': 'FLASH_WRITE_ADDR_ERROR', '0006': 'FLASH_WRITE_ERROR', '0007': 'FLASH_BOOT_PARA_ERROR', '0008': 'FLASH_SET_PARA_ERROR', '0009': 'FLASH_READ_STATUS_REG_ERROR', '000a': 'FLASH_WRITE_STATUS_REG_ERROR', '000b': 'FLASH_DECOMPRESS_WRITE_ERROR', '000c': 'FLASH_WRITE_XZ_ERROR', '000d': 'FLASH_SWITCH_BANK_ERROR', '0101': 'CMD_ID_ERROR', '0102': 'CMD_LEN_ERROR', '0103': 'CMD_CRC_ERROR', '0104': 'CMD_SEQ_ERROR', '0201': 'IMG_BOOTHEADER_LEN_ERROR', '0202': 'IMG_BOOTHEADER_NOT_LOAD_ERROR', '0203': 'IMG_BOOTHEADER_MAGIC_ERROR', '0204': 'IMG_BOOTHEADER_CRC_ERROR', '0205': 'IMG_BOOTHEADER_ENCRYPT_NOTFIT', '0206': 'IMG_BOOTHEADER_SIGN_NOTFIT', '0207': 'IMG_SEGMENT_CNT_ERROR', '0208': 'IMG_AES_IV_LEN_ERROR', '0209': 'IMG_AES_IV_CRC_ERROR', '020a': 'IMG_PK_LEN_ERROR', '020b': 'IMG_PK_CRC_ERROR', '020c': 'IMG_PK_HASH_ERROR', '020d': 'IMG_SIGNATURE_LEN_ERROR', '020e': 'IMG_SIGNATURE_CRC_ERROR', '020f': 'IMG_SECTIONHEADER_LEN_ERROR', '0210': 'IMG_SECTIONHEADER_CRC_ERROR', '0211': 'IMG_SECTIONHEADER_DST_ERROR', '0212': 'IMG_SECTIONDATA_LEN_ERROR', '0213': 'IMG_SECTIONDATA_DEC_ERROR', '0214': 'IMG_SECTIONDATA_TLEN_ERROR', '0215': 'IMG_SECTIONDATA_CRC_ERROR', '0216': 'IMG_HALFBAKED_ERROR', '0217': 'IMG_HASH_ERROR', '0218': 'IMG_SIGN_PARSE_ERROR', '0219': 'IMG_SIGN_ERROR', '021a': 'IMG_DEC_ERROR', '021b': 'IMG_ALL_INVALID_ERROR', '0301': 'IF_RATE_LEN_ERROR', '0302': 'IF_RATE_PARA_ERROR', '0303': 'IF_PASSWORDERROR', '0304': 'IF_PASSWORDCLOSE', '0401': 'EFUSE_WRITE_PARA_ERROR', '0402': 'EFUSE_WRITE_ADDR_ERROR', '0403': 'EFUSE_WRITE_ERROR', '0404': 'EFUSE_READ_PARA_ERROR', '0405': 'EFUSE_READ_ADDR_ERROR', '0406': 'EFUSE_READ_ERROR', '0407': 'EFUSE_READ_MAC_ERROR', '0408': 'EFUSE_WRITE_MAC_ERROR', '0501': 'MEMORY_WRITE_PARA_ERROR', '0502': 'MEMORY_WRITE_ADDR_ERROR', '0503': 'MEMORY_WRITE_ERROR', '0504': 'MEMORY_READ_PARA_ERROR', '0505': 'MEMORY_READ_ADDR_ERROR', '0506': 'MEMORY_READ_ERROR', '0508': 'REG_WRITE_PARA_ERROR', '0509': 'REG_WRITE_ADDR_ERROR', '050a': 'REG_WRITE_ERROR', '050b': 'REG_READ_PARA_ERROR', '050c': 'REG_READ_ADDR_ERROR', '050d': 'REG_READ_ERROR', '0601': 'ECDH_PARA_ERROR', '0602': 'ECDH_PRIVATE_KEY_ERROR', '0603': 'ECDH_SHARED_KEY_ERROR', '0604': 'ECDH_RANDOM_VAL_ERROR', '0605': 'ECDH_DECRYPT_ERROR', '0606': 'ECDH_ENCRYPT_ERROR', 'fffc': 'PLL_ERROR', 'fffd': 'INVASION_ERROR', 'fffe': 'POLLING', 'ffff': 'FAIL'}
eflash_loader_error_code = {'0000': 'SUCCESS', '0001': 'EFLASH LOADER SHAKEHAND FAIL', '0002': 'OPTION SET UNSUPPORTED', '0003': 'LOAD HELP BIN FAIL', '0004': 'RESET CPU FAIL', '0005': 'BURN RETRY FAIL', '0006': 'LOG READ FAIL', '0009': 'CONNECT OPENOCD SERVER FAIL', '000A': 'REPEAT BURN', '000B': 'CONFIG FILE NOT FOUND', '000C': 'SET CLOCK PLL FAIL', '000D': 'SET OPT FINISH FAIL', '000E': 'IMPORT PACKET FAIL', '0020': 'EFUSE READ FAIL', '0021': 'EFUSE WRITE FAIL', '0022': 'EFUSE COMPARE FAIL', '0023': 'EFUSE READ MAC ADDR FAIL', '0024': 'EFUSE WRITE MAC ADDR FAIL', '0025': 'EFUSE MAC ADDR CRC FAIL', '0030': 'READ FLASH JEDEC ID FAIL', '0031': 'READ FLASH STATUS REGISTER FAIL', '0032': 'WRITE FLASH STATUS REGISTER FAIL', '0033': 'FLASH CHIP ERASE FAIL', '0034': 'FLASH ERASE FAIL', '0035': 'FLASH READ FAIL', '0036': 'FLASH WRITE FAIL', '0037': 'FLASH WRITE CHECK FAIL', '0038': 'FLASH READ SHA FAIL', '0039': 'FLASH XIP MODE ENTER FAIL', '003A': 'FLASH XIP MODE EXIT FAIL', '003B': 'FLASH SET PARA FAIL', '003C': 'FLASH LOAD FIRMWARE BIN FAIL', '003D': 'FLASH MATCH TYPE FAIL', '003E': 'FLASH LOAD VERIFY FAIL', '003F': 'FLASH BOOT FAIL', '0040': 'FLASH CFG NOT FIT WITH BOOTHEADER', '0041': 'FLASH LOAD ROMFS FAIL', '0042': 'FLASH SWITCH BANK FAIL', '0043': 'FLASH IDENTIFY FAIL', '0044': 'FLASH CHIPERASE CONFLICT WITH SKIP MODE', '0050': 'IMG LOAD SHAKEHAND FAIL', '0051': 'IMG LOAD BOOT CHECK FAIL', '0060': 'IMG CREATE FAIL', '0061': 'IMG FILE NOT SET', '0062': 'IMG ADDR NOT SET', '0063': 'BOOTINFO ADDR NOT SET', '0064': 'AES KEY NOT SET', '0065': 'AES IV NOT SET', '0066': 'PUBLIC KEY NOT SET', '0067': 'PRIVATE KEY NOT SET', '0068': 'RAW DATA NOT NEED CREATE', '0069': 'FLASH ID NOT SUPPORT', '0070': 'FLASH ID NOT FOUND', '0071': 'ENCRYPT KEY LEN ERROR', '0072': 'AES IV LEN ERROR', '0073': 'AES IV SHOULD END WITH 00000000', '0074': 'IMG TYPE NOT FIT', '0075': 'IMG CREATE ENTER EXCEPT', '0076': 'PT NOT SET', '0077': 'AES KEY DATA OR LEN ERROR', '0078': 'AES IV DATA OR LEN ERROR', '0079': 'FACTORY IMG NOT FOUND', '007A': 'GENERATE ROMFS FAIL', '007B': 'PT PARCEL IS NULL', '007C': 'PT TABLE NOT SET', '007D': 'BOOT2 BIN NOT SET', '007E': 'FW BIN NOT SET', '007F': 'MEDIA NOT SET', '0080': 'ROMFS NOT SET', '0081': 'MFG BIN NOT SET', '0082': 'PT CHECK FAIL', '0083': 'D0 FW BIN NOT SET', '0084': 'IMTB BIN NOT SET', '0085': 'IMG LOADER BIN NOT SET', '0086': 'SBI BIN NOT SET', '0087': 'KERNEL BIN NOT SET', '0088': 'ROOTFS BIN NOT SET', '0089': 'KV BIN NOT SET', '0090': 'YOCBOOT BIN NOT SET', '0091': 'DTB BIN NOT SET', 'FFFF': 'BURN RETRY FAIL'}
else:
bflb_error_code = {'0000': 'BFLB_SUCCESS', '0001': 'BFLB_FLASH_INIT_ERROR', '0002': 'BFLB_FLASH_ERASE_PARA_ERROR', '0003': 'BFLB_FLASH_ERASE_ERROR', '0004': 'BFLB_FLASH_WRITE_PARA_ERROR', '0005': 'BFLB_FLASH_WRITE_ADDR_ERROR', '0006': 'BFLB_FLASH_WRITE_ERROR', '0007': 'BFLB_FLASH_BOOT_PARA_ERROR', '0008': 'BFLB_FLASH_SET_PARA_ERROR', '0009': 'BFLB_FLASH_READ_STATUS_REG_ERROR', '000a': 'BFLB_FLASH_WRITE_STATUS_REG_ERROR', '000b': 'BFLB_FLASH_DECOMPRESS_WRITE_ERROR', '000c': 'BFLB_FLASH_WRITE_XZ_ERROR', '000d': 'BFLB_FLASH_SWITCH_BANK_ERROR', '0101': 'BFLB_CMD_ID_ERROR', '0102': 'BFLB_CMD_LEN_ERROR', '0103': 'BFLB_CMD_CRC_ERROR', '0104': 'BFLB_CMD_SEQ_ERROR', '0201': 'BFLB_IMG_BOOTHEADER_LEN_ERROR', '0202': 'BFLB_IMG_BOOTHEADER_NOT_LOAD_ERROR', '0203': 'BFLB_IMG_BOOTHEADER_MAGIC_ERROR', '0204': 'BFLB_IMG_BOOTHEADER_CRC_ERROR', '0205': 'BFLB_IMG_BOOTHEADER_ENCRYPT_NOTFIT', '0206': 'BFLB_IMG_BOOTHEADER_SIGN_NOTFIT', '0207': 'BFLB_IMG_SEGMENT_CNT_ERROR', '0208': 'BFLB_IMG_AES_IV_LEN_ERROR', '0209': 'BFLB_IMG_AES_IV_CRC_ERROR', '020a': 'BFLB_IMG_PK_LEN_ERROR', '020b': 'BFLB_IMG_PK_CRC_ERROR', '020c': 'BFLB_IMG_PK_HASH_ERROR', '020d': 'BFLB_IMG_SIGNATURE_LEN_ERROR', '020e': 'BFLB_IMG_SIGNATURE_CRC_ERROR', '020f': 'BFLB_IMG_SECTIONHEADER_LEN_ERROR', '0210': 'BFLB_IMG_SECTIONHEADER_CRC_ERROR', '0211': 'BFLB_IMG_SECTIONHEADER_DST_ERROR', '0212': 'BFLB_IMG_SECTIONDATA_LEN_ERROR', '0213': 'BFLB_IMG_SECTIONDATA_DEC_ERROR', '0214': 'BFLB_IMG_SECTIONDATA_TLEN_ERROR', '0215': 'BFLB_IMG_SECTIONDATA_CRC_ERROR', '0216': 'BFLB_IMG_HALFBAKED_ERROR', '0217': 'BFLB_IMG_HASH_ERROR', '0218': 'BFLB_IMG_SIGN_PARSE_ERROR', '0219': 'BFLB_IMG_SIGN_ERROR', '021a': 'BFLB_IMG_DEC_ERROR', '021b': 'BFLB_IMG_ALL_INVALID_ERROR', '0301': 'BFLB_IF_RATE_LEN_ERROR', '0302': 'BFLB_IF_RATE_PARA_ERROR', '0303': 'BFLB_IF_PASSWORDERROR', '0304': 'BFLB_IF_PASSWORDCLOSE', '0401': 'BFLB_EFUSE_WRITE_PARA_ERROR', '0402': 'BFLB_EFUSE_WRITE_ADDR_ERROR', '0403': 'BFLB_EFUSE_WRITE_ERROR', '0404': 'BFLB_EFUSE_READ_PARA_ERROR', '0405': 'BFLB_EFUSE_READ_ADDR_ERROR', '0406': 'BFLB_EFUSE_READ_ERROR', '0407': 'BFLB_EFUSE_READ_MAC_ERROR', '0408': 'BFLB_EFUSE_WRITE_MAC_ERROR', '0501': 'BFLB_MEMORY_WRITE_PARA_ERROR', '0502': 'BFLB_MEMORY_WRITE_ADDR_ERROR', '0503': 'BFLB_MEMORY_WRITE_ERROR', '0504': 'BFLB_MEMORY_READ_PARA_ERROR', '0505': 'BFLB_MEMORY_READ_ADDR_ERROR', '0506': 'BFLB_MEMORY_READ_ERROR', '0508': 'BFLB_REG_WRITE_PARA_ERROR', '0509': 'BFLB_REG_WRITE_ADDR_ERROR', '050a': 'BFLB_REG_WRITE_ERROR', '050b': 'BFLB_REG_READ_PARA_ERROR', '050c': 'BFLB_REG_READ_ADDR_ERROR', '050d': 'BFLB_REG_READ_ERROR', '0601': 'BFLB_ECDH_PARA_ERROR', '0602': 'BFLB_ECDH_PRIVATE_KEY_ERROR', '0603': 'BFLB_ECDH_SHARED_KEY_ERROR', '0604': 'BFLB_ECDH_RANDOM_VAL_ERROR', '0605': 'BFLB_ECDH_DECRYPT_ERROR', '0606': 'BFLB_ECDH_ENCRYPT_ERROR', 'fffc': 'BFLB_PLL_ERROR', 'fffd': 'BFLB_INVASION_ERROR', 'fffe': 'BFLB_POLLING', 'ffff': 'BFLB_FAIL'}
eflash_loader_error_code = {'0000': 'BFLB SUCCESS', '0001': 'BFLB EFLASH LOADER SHAKEHAND FAIL', '0002': 'BFLB OPTION SET UNSUPPORTED', '0003': 'BFLB LOAD HELP BIN FAIL', '0004': 'BFLB RESET CPU FAIL', '0005': 'BFLB BURN RETRY FAIL', '0006': 'BFLB LOG READ FAIL', '0009': 'BFLB CONNECT OPENOCD SERVER FAIL', '000A': 'BFLB REPEAT BURN', '000B': 'BFLB CONFIG FILE NOT FOUND', '000C': 'BFLB SET CLOCK PLL FAIL', '000D': 'BFLB SET OPT FINISH FAIL', '000E': 'BFLB IMPORT PACKET FAIL', '0020': 'BFLB EFUSE READ FAIL', '0021': 'BFLB EFUSE WRITE FAIL', '0022': 'BFLB EFUSE COMPARE FAIL', '0023': 'BFLB EFUSE READ MAC ADDR FAIL', '0024': 'BFLB EFUSE WRITE MAC ADDR FAIL', '0025': 'BFLB EFUSE MAC ADDR CRC FAIL', '0030': 'BFLB READ FLASH JEDEC ID FAIL', '0031': 'BFLB READ FLASH STATUS REGISTER FAIL', '0032': 'BFLB WRITE FLASH STATUS REGISTER FAIL', '0033': 'BFLB FLASH CHIP ERASE FAIL', '0034': 'BFLB FLASH ERASE FAIL', '0035': 'BFLB FLASH READ FAIL', '0036': 'BFLB FLASH WRITE FAIL', '0037': 'BFLB FLASH WRITE CHECK FAIL', '0038': 'BFLB FLASH READ SHA FAIL', '0039': 'BFLB FLASH XIP MODE ENTER FAIL', '003A': 'BFLB FLASH XIP MODE EXIT FAIL', '003B': 'BFLB FLASH SET PARA FAIL', '003C': 'BFLB FLASH LOAD FIRMWARE BIN FAIL', '003D': 'BFLB FLASH MATCH TYPE FAIL', '003E': 'BFLB FLASH LOAD VERIFY FAIL', '003F': 'BFLB FLASH BOOT FAIL', '0040': 'BFLB FLASH CFG NOT FIT WITH BOOTHEADER', '0041': 'BFLB FLASH LOAD ROMFS FAIL', '0042': 'BFLB FLASH SWITCH BANK FAIL', '0043': 'BFLB FLASH IDENTIFY FAIL', '0044': 'BFLB FLASH CHIPERASE CONFLICT WITH SKIP MODE', '0050': 'BFLB IMG LOAD SHAKEHAND FAIL', '0051': 'BFLB IMG LOAD BOOT CHECK FAIL', '0060': 'BFLB IMG CREATE FAIL', '0061': 'BFLB IMG FILE NOT SET', '0062': 'BFLB IMG ADDR NOT SET', '0063': 'BFLB BOOTINFO ADDR NOT SET', '0064': 'BFLB AES KEY NOT SET', '0065': 'BFLB AES IV NOT SET', '0066': 'BFLB PUBLIC KEY NOT SET', '0067': 'BFLB PRIVATE KEY NOT SET', '0068': 'BFLB RAW DATA NOT NEED CREATE', '0069': 'BFLB FLASH ID NOT SUPPORT', '0070': 'BFLB FLASH ID NOT FOUND', '0071': 'BFLB ENCRYPT KEY LEN ERROR', '0072': 'BFLB AES IV LEN ERROR', '0073': 'BFLB AES IV SHOULD END WITH 00000000', '0074': 'BFLB IMG TYPE NOT FIT', '0075': 'BFLB IMG CREATE ENTER EXCEPT', '0076': 'BFLB PT NOT SET', '0077': 'BFLB AES KEY DATA OR LEN ERROR', '0078': 'BFLB AES IV DATA OR LEN ERROR', '0079': 'BFLB FACTORY IMG NOT FOUND', '007A': 'BFLB GENERATE ROMFS FAIL', '007B': 'BFLB PT PARCEL IS NULL', '007C': 'BFLB PT TABLE NOT SET', '007D': 'BFLB BOOT2 BIN NOT SET', '007E': 'BFLB FW BIN NOT SET', '007F': 'BFLB MEDIA NOT SET', '0080': 'BFLB ROMFS NOT SET', '0081': 'BFLB MFG BIN NOT SET', '0082': 'BFLB PT CHECK FAIL', '0083': 'D0 FW BIN NOT SET', '0084': 'IMTB BIN NOT SET', '0085': 'IMG LOADER BIN NOT SET', '0086': 'SBI BIN NOT SET', '0087': 'KERNEL BIN NOT SET', '0088': 'ROOTFS BIN NOT SET', '0089': 'KV BIN NOT SET', '0090': 'YOCBOOT BIN NOT SET', 'FFFF': 'BFLB BURN RETRY FAIL'}
def convert_path(path:str) -> str:
return path.replace('\\/'.replace(os.sep, ''), os.sep)
def printf(*args):
global local_log_data
data = ''
for arg in args:
data += str(arg)
if data:
if conf_sign:
for (key, value) in cgc.replace_name_list.items():
data = data.replace(key, value)
now_time = datetime.datetime.now().strftime('[%H:%M:%S.%f')[:-3] + '] - '
data = now_time + data
if local_log_en is True:
local_log_data += data + '\n'
else:
local_log_data = ''
if udp_send_log:
tid = str(threading.get_ident())
if udp_log_local_echo:
print('[' + tid + ':]' + data.strip())
try:
udp_socket_server.sendto((data.strip() + '\r\n').encode('utf-8'), udp_clinet_dict[tid])
except Exception as e:
print(e)
elif qt_sign and QtCore.QThread.currentThread().objectName():
print('[Task%s]' % str(QtCore.QThread.currentThread().objectName()) + data.strip())
else:
print(data.strip())
sys.stdout.flush()
def local_log_enable(en=False):
global local_log_en
if en is True:
local_log_en = True
else:
local_log_en = False
def local_log_save(local_path='log', key_word=''):
global local_log_data
log_dir = os.path.join(app_path, local_path)
if not os.path.exists(log_dir):
os.makedirs(log_dir)
if local_log_en is True:
try:
rq = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
log_name = rq + '_' + key_word + '.log'
log_path = os.path.join(log_dir, log_name)
with codecs.open(log_path, 'w', encoding='utf-8') as fp:
fp.write(local_log_data)
except Exception as e:
printf(e)
traceback.print_exc(limit=5, file=sys.stdout)
local_log_data = ''
def get_bflb_error_code(code):
return bflb_error_code[code]
def clear_global():
global error_code_num, error_code_num_task
error_code_num = 'FFFF'
error_code_num_task = []
def set_error_code(num_str, task=None):
global error_code_num
if task != None:
if len(error_code_num_task) == 0:
for i in range(66):
error_code_num_task.append('FFFF')
if error_code_num_task[task] == 'FFFF':
error_code_num_task[task] = num_str
if num_str == 'FFFF':
error_code_num_task[task] = num_str
else:
if error_code_num == 'FFFF':
error_code_num = num_str
if num_str == 'FFFF':
error_code_num = num_str
def get_error_code(task=None):
if task != None:
return error_code_num_task[task]
return error_code_num
def errorcode_msg(task=None):
if task != None:
return '{"ErrorCode": "' + error_code_num_task[task] + '", "ErrorMsg":"' + eflash_loader_error_code[error_code_num_task[task]] + '"}'
return '{"ErrorCode": "' + error_code_num + '", "ErrorMsg":"' + eflash_loader_error_code[error_code_num] + '"}'
def get_security_key():
return (hexstr_to_bytearray('424F554646414C4F4C41424B45594956'), hexstr_to_bytearray('424F554646414C4F4C41424B00000000'))
def hexstr_to_bytearray_b(hexstring):
return bytearray.fromhex(hexstring)
def hexstr_to_bytearray(hexstring):
return bytearray.fromhex(hexstring)
def hexstr_to_bytearray_l(hexstring):
b = bytearray.fromhex(hexstring)
b.reverse()
return b
def int_to_2bytearray_l(intvalue):
return struct.pack('<H', intvalue)
def int_to_2bytearray_b(intvalue):
return struct.pack('>H', intvalue)
def int_to_4bytearray_l(intvalue):
src = bytearray(4)
src[3] = intvalue >> 24 & 255
src[2] = intvalue >> 16 & 255
src[1] = intvalue >> 8 & 255
src[0] = intvalue >> 0 & 255
return src
def int_to_4bytearray_b(intvalue):
val = int_to_4bytearray_l(intvalue)
val.reverse()
return val
def bytearray_reverse(a):
length = len(a)
b = bytearray(length)
i = 0
while i < length:
b[i] = a[length - i - 1]
i = i + 1
return b
def bytearray_to_int(b):
return int(binascii.hexlify(b), 16)
def string_to_bytearray(string):
return bytes(string, encoding='utf8')
def bytearray_to_str(bytesarray):
return str(bytesarray)
def get_random_hexstr(n_bytes):
hextring = ''
i = 0
while i < n_bytes:
hextring = hextring + str(binascii.hexlify(random.randint(0, 255)))
i = i + 1
return hextring
def get_crc32_bytearray(data):
crc = binascii.crc32(data)
return int_to_4bytearray_l(crc)
def add_to_16(par):
while len(par) % 16 != 0:
par += b'\x00'
return par
def enable_udp_send_log(local_echo):
global udp_send_log, udp_log_local_echo, udp_socket_server
udp_send_log = True
udp_log_local_echo = local_echo
udp_socket_server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
def add_udp_client(tid, upd_client):
udp_clinet_dict[tid] = upd_client
def remove_udp_client(tid):
del udp_clinet_dict[tid]
def update_cfg(cfg, section, key, value):
if cfg.has_option(section, key):
cfg.set(section, key, str(value))
def get_byte_array(string):
return string.encode('utf-8')
def verify_hex_num(string):
length = len(string)
i = 0
while True:
if re.match('\\A[0-9a-fA-F]+\\Z', string[i:i + 1]) is None:
return False
i += 1
if i >= length:
break
return True
def get_eflash_loader(xtal):
xtal_suffix = str(xtal).lower().replace('.', 'p').replace('M', 'm').replace('RC', 'rc')
return 'eflash_loader_' + xtal_suffix + '.bin'
def str_endian_switch(string):
s = string[6:8] + string[4:6] + string[2:4] + string[0:2]
return s
def img_create_sha256_data(data_bytearray):
hashfun = hashlib.sha256()
hashfun.update(data_bytearray)
return hexstr_to_bytearray(hashfun.hexdigest())
def img_create_encrypt_data(data_bytearray, key_bytearray, iv_bytearray, flash_img):
if flash_img == 0:
cryptor = AES.new(key_bytearray, AES.MODE_CBC, iv_bytearray)
ciphertext = cryptor.encrypt(data_bytearray)
else:
iv = Counter.new(128, initial_value=int(binascii.hexlify(iv_bytearray), 16))
cryptor = AES.new(key_bytearray, AES.MODE_CTR, counter=iv)
ciphertext = cryptor.encrypt(data_bytearray)
return ciphertext
def aes_decrypt_data(data, key_bytearray, iv_bytearray, flash_img):
if flash_img == 0:
cryptor = AES.new(key_bytearray, AES.MODE_CBC, iv_bytearray)
plaintext = cryptor.decrypt(data)
else:
iv = Counter.new(128, initial_value=int(binascii.hexlify(iv_bytearray), 16))
cryptor = AES.new(key_bytearray, AES.MODE_CTR, counter=iv)
plaintext = cryptor.decrypt(data)
return plaintext
def open_file(file, mode='rb'):
fp = open(os.path.join(app_path, file), mode)
return fp
def copyfile(srcfile, dstfile):
if os.path.isfile(srcfile):
(fpath, fname) = os.path.split(dstfile)
if not os.path.exists(fpath):
os.makedirs(fpath)
shutil.copyfile(srcfile, dstfile)
else:
printf('Src file not exists')
def get_systype():
type_ = platform.system().lower()
arch = platform.machine().lower()
if type_ == 'windows':
arch = 'amd64' if platform.architecture()[0] == '64bit' else 'x86'
if arch:
return '%s_%s' % (type_, arch)
return type_
def get_serial_ports():
try:
from serial.tools.list_ports import comports
except ImportError:
return
WINDOWS = sys.platform.startswith('win')
result = []
for (p, d, h) in comports():
if not p:
continue
if WINDOWS and PY2:
try:
d = unicode(d, errors='ignore')
except TypeError:
pass
if 'VID:PID' in h:
result.append({'port': p, 'description': d, 'hwid': h})
if not result:
if 'darwin' in get_systype():
for p in glob('/dev/tty.*'):
result.append({'port': p, 'description': 'n/a', 'hwid': 'n/a'})
return result
def serial_enumerate():
prog_ports = []
sdio_ports = []
sdio_file_ser_dict = {}
uart_ports = []
file_dict = {}
ports = []
if sys.platform.startswith('win'):
for (p, d, h) in comports():
if not ('Virtual' in d or not p) and 'STM' not in d:
continue
if 'PID=1D6B' in h.upper():
ser_value = h.split(' ')[2][4:]
if ser_value not in sdio_file_ser_dict:
sdio_file_ser_dict[ser_value] = p
elif 'LOCATION' in h.upper():
file_dict[sdio_file_ser_dict[ser_value]] = p
sdio_ports.append(sdio_file_ser_dict[ser_value] + ' (SDIO)')
else:
file_dict[p] = sdio_file_ser_dict[ser_value]
sdio_ports.append(p + ' (SDIO)')
if 'FACTORYAIOT_PROG' in h.upper() or 'PID=42BF:B210' in h.upper():
prog_ports.append(p + ' (PROG)')
else:
uart_ports.append(p)
elif 'FACTORYAIOT_PROG' in h.upper() or 'PID=42BF:B210' in h.upper():
prog_ports.append(p + ' (PROG)')
else:
uart_ports.append(p)
try:
uart_ports = sorted(uart_ports, key=lambda x: int(re.match('COM(\\d+)', x).group(1)))
except Exception:
uart_ports = sorted(uart_ports)
ports = sorted(prog_ports) + sorted(sdio_ports) + uart_ports
elif sys.platform.startswith('linux'):
for (p, d, h) in comports():
if not p:
continue
if 'PID=1D6B' in h.upper():
ser_value = h.split(' ')[2][4:]
if ser_value not in sdio_file_ser_dict:
sdio_file_ser_dict[ser_value] = p
elif sdio_file_ser_dict[ser_value] > p:
file_dict[p] = sdio_file_ser_dict[ser_value]
sdio_ports.append(p + ' (SDIO)')
else:
file_dict[sdio_file_ser_dict[ser_value]] = p
sdio_ports.append(sdio_file_ser_dict[ser_value] + ' (SDIO)')
elif 'FACTORYAIOT PROG' in h.upper():
prog_ports.append(p + ' (PROG)')
else:
uart_ports.append(p)
ports = sorted(prog_ports) + sorted(sdio_ports) + sorted(uart_ports)
elif sys.platform.startswith('darwin'):
for dev in glob('/dev/tty.usb*'):
ports.append(dev)
return ports
def pylink_enumerate():
try:
if sys.platform == 'win32':
obj_dll = pylink.Library(dllpath=path_dll)
obj = pylink.JLink(lib=obj_dll)
else:
obj = pylink.JLink()
except Exception:
return []
else:
return obj.connected_emulators()
def cklink_openocd_enumerate():
ports_cklink = []
ports_openocd = []
if sys.platform.startswith('win'):
for (p, d, h) in comports():
if not p:
continue
if 'FACTORYAIOT_PROG' in h.upper():
match1 = re.search('FACTORYAIOT_PROG_([a-zA-Z0-9]{6}) LOCATION', h.upper(), re.I)
match2 = re.search('FACTORYAIOT_PROG_([a-zA-Z0-9]{6})$', h.upper(), re.I)
if match1 is not None:
ports_cklink.append(match1.group(1))
if match2 is not None:
ports_openocd.append(match2.group(1))
elif sys.platform.startswith('linux'):
for (p, d, h) in comports():
if not p:
continue
if 'FactoryAIOT Prog' in h:
match1 = re.search('FactoryAIOT Prog ([a-zA-Z0-9]{6}) LOCATION', h, re.I)
if match1 is not None:
ports_cklink.append(match1.group(1))
return (ports_cklink, ports_openocd)
def image_create_parser_init():
parser = argparse.ArgumentParser(description='bouffalolab image create command')
parser.add_argument('--chipname', dest='chipname', help='chip name')
parser.add_argument('--imgfile', dest='imgfile', help='image file')
parser.add_argument('--security', dest='security', help='security save efusedata')
parser.add_argument('-i', '--image', dest='image', help='image type: media or if')
parser.add_argument('-c', '--cpu', dest='cpu', help='cpu type: cpu0 cpu1 or all')
parser.add_argument('-g', '--group', dest='group', help='group type')
parser.add_argument('-s', '--signer', dest='signer', help='signer')
return parser
def eflash_loader_parser_init():
parser = argparse.ArgumentParser(description='bouffalolab eflash loader command')
parser.add_argument('--chipname', dest='chipname', help='chip name')
parser.add_argument('--chipid', dest='chipid', action='store_true', help='chip id')
parser.add_argument('--usage', dest='usage', action='store_true', help='display usage')
parser.add_argument('--flash', dest='flash', action='store_true', help='target is flash')
parser.add_argument('--efuse', dest='efuse', action='store_true', help='target is efuse')
parser.add_argument('--ram', dest='ram', action='store_true', help='target is ram')
parser.add_argument('-w', '--write', dest='write', action='store_true', help='write to flash/efuse')
parser.add_argument('-e', '--erase', dest='erase', action='store_true', help='erase flash')
parser.add_argument('-r', '--read', dest='read', action='store_true', help='read from flash/efuse')
parser.add_argument('-n', '--none', dest='none', action='store_true', help='eflash loader environment init')
parser.add_argument('-p', '--port', dest='port', help='serial port to use')
parser.add_argument('-b', '--baudrate', dest='baudrate', type=int, help='the speed at which to communicate')
parser.add_argument('-c', '--config', dest='config', help='eflash loader config file')
parser.add_argument('-i', '--interface', dest='interface', help='interface type: uart/jlink/openocd')
parser.add_argument('--xtal', dest='xtal', help='xtal type')
parser.add_argument('--start', dest='start', help='start address')
parser.add_argument('--end', dest='end', help='end address')
parser.add_argument('--addr', dest='addr', help='address to write')
parser.add_argument('--mac', dest='mac', help='mac address to write')
parser.add_argument('--file', dest='file', help='file to store read data or file to write')
parser.add_argument('--skip', dest='skip', help='skip write file to flash')
parser.add_argument('--packet', dest='packet', help=' import packet to replace burn file')
parser.add_argument('--efusefile', dest='efusefile', help='efuse file to write efuse')
parser.add_argument('--data', dest='data', help='data to write')
parser.add_argument('--mass', dest='mass', help='load mass bin')
parser.add_argument('--loadstr', dest='loadstr', help='')
parser.add_argument('--loadfile', dest='loadfile', help='')
parser.add_argument('--userarea', dest='userarea', help='user area')
parser.add_argument('--romfs', dest='romfs', help='romfs data to write')
parser.add_argument('--csvfile', dest='csvfile', help='csv file contains 3/5 tuples')
parser.add_argument('--csvaddr', dest='csvaddr', help='address to write for csv file')
parser.add_argument('--para', dest='para', help='efuse para')
parser.add_argument('--isp', dest='isp', action='store_true', help='isp config')
parser.add_argument('--createcfg', dest='createcfg', help='img create cfg file')
parser.add_argument('--key', dest='key', help='aes key for socket')
parser.add_argument('--ecdh', dest='ecdh', action='store_true', help='open ecdh function')
parser.add_argument('--echo', dest='echo', action='store_true', help='open local log echo')
parser.add_argument('-a', '--auto', dest='auto', action='store_true', help='auto flash')
parser.add_argument('-v', '--version', dest='version', action='store_true', help='display version')
return parser

21
pylink/__init__.py Normal file
View File

@ -0,0 +1,21 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: pylink/__init__.py
__version__ = '0.5.0'
__title__ = 'pylink'
__author__ = 'Square Embedded Software Team'
__author_email__ = 'esw-team@squareup.com'
__copyright__ = 'Copyright 2017 Square, Inc.'
__license__ = 'Apache 2.0'
__url__ = 'http://www.github.com/Square/pylink'
__description__ = 'Python interface for SEGGER J-Link.'
__long_description__ = "This module provides a Python implementation of the\nJ-Link SDK by leveraging the SDK's DLL.\n"
from .enums import *
from .errors import *
from .jlink import *
from .library import *
from .structs import *
from .unlockers import *
# okay decompiling ./pylink/__init__.pyc

57
pylink/binpacker.py Normal file
View File

@ -0,0 +1,57 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: pylink/binpacker.py
import ctypes, math
BITS_PER_BYTE = 8
def pack_size(value):
"""Returns the number of bytes required to represent a given value.
Args:
value (int): the natural number whose size to get
Returns:
The minimal number of bytes required to represent the given integer.
Raises:
ValueError: if ``value < 0``.
TypeError: if ``value`` is not a number.
"""
if value == 0:
return 1
if value < 0:
raise ValueError('Expected non-negative integer.')
return int(math.log(value, 256)) + 1
def pack(value, nbits=None):
"""Packs a given value into an array of 8-bit unsigned integers.
If ``nbits`` is not present, calculates the minimal number of bits required
to represent the given ``value``. The result is little endian.
Args:
value (int): the integer value to pack
nbits (int): optional number of bits to use to represent the value
Returns:
An array of ``ctypes.c_uint8`` representing the packed ``value``.
Raises:
ValueError: if ``value < 0`` and ``nbits`` is ``None`` or ``nbits <= 0``.
TypeError: if ``nbits`` or ``value`` are not numbers.
"""
if nbits is None:
nbits = pack_size(value) * BITS_PER_BYTE
else:
if nbits <= 0:
raise ValueError('Given number of bits must be greater than 0.')
buf_size = int(math.ceil(nbits / float(BITS_PER_BYTE)))
buf = (ctypes.c_uint8 * buf_size)()
for idx, _ in enumerate(buf):
buf[idx] = value >> idx * BITS_PER_BYTE & 255
return buf
# okay decompiling ./pylink/binpacker.pyc

52
pylink/decorators.py Normal file
View File

@ -0,0 +1,52 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: pylink/decorators.py
from . import threads
import functools
def async_decorator(func):
"""Asynchronous function decorator. Interprets the function as being
asynchronous, so returns a function that will handle calling the
Function asynchronously.
Args:
func (function): function to be called asynchronously
Returns:
The wrapped function.
Raises:
AttributeError: if ``func`` is not callable
"""
@functools.wraps(func)
def async_wrapper(*args, **kwargs):
if not ('callback' not in kwargs or kwargs['callback']):
return func(*args, **kwargs)
callback = kwargs.pop('callback')
if not callable(callback):
raise TypeError("Expected 'callback' is not callable.")
def thread_func(*args, **kwargs):
exception, res = (None, None)
try:
res = func(*args, **kwargs)
except Exception as e:
try:
exception = e
finally:
e = None
del e
return callback(exception, res)
thread = threads.ThreadReturn(target=thread_func, args=args,
kwargs=kwargs)
thread.daemon = True
thread.start()
return thread
return async_wrapper
# okay decompiling ./pylink/decorators.pyc

528
pylink/enums.py Normal file
View File

@ -0,0 +1,528 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: pylink/enums.py
import ctypes
class JLinkGlobalErrors(object):
__doc__ = 'Enumeration for the error codes which any J-Link SDK DLL API-function\n can have as a return value.'
UNSPECIFIED_ERROR = -1
EMU_NO_CONNECTION = -256
EMU_COMM_ERROR = -257
DLL_NOT_OPEN = -258
VCC_FAILURE = -259
INVALID_HANDLE = -260
NO_CPU_FOUND = -261
EMU_FEATURE_UNSUPPORTED = -262
EMU_NO_MEMORY = -263
TIF_STATUS_ERROR = -264
FLASH_PROG_COMPARE_FAILED = -265
FLASH_PROG_PROGRAM_FAILED = -266
FLASH_PROG_VERIFY_FAILED = -267
OPEN_FILE_FAILED = -268
UNKNOWN_FILE_FORMAT = -269
WRITE_TARGET_MEMORY_FAILED = -270
DEVICE_FEATURE_NOT_SUPPORTED = -271
WRONG_USER_CONFIG = -272
NO_TARGET_DEVICE_SELECTED = -273
CPU_IN_LOW_POWER_MODE = -274
@classmethod
def to_string(cls, error_code):
"""Returns the string message for the given ``error_code``.
Args:
cls (JlinkGlobalErrors): the ``JLinkGlobalErrors`` class
error_code (int): error code to convert
Returns:
An error string corresponding to the error code.
Raises:
ValueError: if the error code is invalid.
"""
if error_code == cls.EMU_NO_CONNECTION:
return 'No connection to emulator.'
if error_code == cls.EMU_COMM_ERROR:
return 'Emulator connection error.'
if error_code == cls.DLL_NOT_OPEN:
return "DLL has not been opened. Did you call '.connect()'?"
if error_code == cls.VCC_FAILURE:
return 'Target system has no power.'
if error_code == cls.INVALID_HANDLE:
return 'Given file / memory handle is invalid.'
if error_code == cls.NO_CPU_FOUND:
return 'Could not find supported CPU.'
if error_code == cls.EMU_FEATURE_UNSUPPORTED:
return 'Emulator does not support the selected feature.'
if error_code == cls.EMU_NO_MEMORY:
return 'Emulator out of memory.'
if error_code == cls.TIF_STATUS_ERROR:
return 'Target interface error.'
if error_code == cls.FLASH_PROG_COMPARE_FAILED:
return 'Programmed data differs from source data.'
if error_code == cls.FLASH_PROG_PROGRAM_FAILED:
return 'Programming error occured.'
if error_code == cls.FLASH_PROG_VERIFY_FAILED:
return 'Error while verifying programmed data.'
if error_code == cls.OPEN_FILE_FAILED:
return 'Specified file could not be opened.'
if error_code == cls.UNKNOWN_FILE_FORMAT:
return 'File format of selected file is not supported.'
if error_code == cls.WRITE_TARGET_MEMORY_FAILED:
return 'Could not write target memory.'
if error_code == cls.DEVICE_FEATURE_NOT_SUPPORTED:
return 'Feature not supported by connected device.'
if error_code == cls.WRONG_USER_CONFIG:
return 'User configured DLL parameters incorrectly.'
if error_code == cls.NO_TARGET_DEVICE_SELECTED:
return 'User did not specify core to connect to.'
if error_code == cls.CPU_IN_LOW_POWER_MODE:
return 'Target CPU is in low power mode.'
if error_code == cls.UNSPECIFIED_ERROR:
return 'Unspecified error.'
raise ValueError('Invalid error code: %d' % error_code)
class JLinkEraseErrors(JLinkGlobalErrors):
__doc__ = 'Enumeration for the error codes generated during an erase operation.'
ILLEGAL_COMMAND = -5
@classmethod
def to_string(cls, error_code):
if error_code == cls.ILLEGAL_COMMAND:
return 'Failed to erase sector.'
return super(JLinkEraseErrors, cls).to_string(error_code)
class JLinkFlashErrors(JLinkGlobalErrors):
__doc__ = 'Enumeration for the error codes generated during a flash operation.'
COMPARE_ERROR = -2
PROGRAM_ERASE_ERROR = -3
VERIFICATION_ERROR = -4
@classmethod
def to_string(cls, error_code):
if error_code == cls.COMPARE_ERROR:
return 'Error comparing flash content to programming data.'
if error_code == cls.PROGRAM_ERASE_ERROR:
return 'Error during program/erase phase.'
if error_code == cls.VERIFICATION_ERROR:
return 'Error verifying programmed data.'
return super(JLinkFlashErrors, cls).to_string(error_code)
class JLinkWriteErrors(JLinkGlobalErrors):
__doc__ = 'Enumeration for the error codes generated during a write.'
ZONE_NOT_FOUND_ERROR = -5
@classmethod
def to_string(cls, error_code):
if error_code == cls.ZONE_NOT_FOUND_ERROR:
return 'Zone not found'
return super(JLinkWriteErrors, cls).to_string(error_code)
class JLinkReadErrors(JLinkGlobalErrors):
__doc__ = 'Enumeration for the error codes generated during a read.'
ZONE_NOT_FOUND_ERROR = -5
@classmethod
def to_string(cls, error_code):
if error_code == cls.ZONE_NOT_FOUND_ERROR:
return 'Zone not found'
return super(JLinkReadErrors, cls).to_string(error_code)
class JLinkDataErrors(JLinkGlobalErrors):
__doc__ = 'Enumeration for the error codes generated when setting a data event.'
ERROR_UNKNOWN = 2147483648
ERROR_NO_MORE_EVENTS = 2147483649
ERROR_NO_MORE_ADDR_COMP = 2147483650
ERROR_NO_MORE_DATA_COMP = 2147483652
ERROR_INVALID_ADDR_MASK = 2147483680
ERROR_INVALID_DATA_MASK = 2147483712
ERROR_INVALID_ACCESS_MASK = 2147483776
@classmethod
def to_string(cls, error_code):
if error_code == cls.ERROR_UNKNOWN:
return 'Unknown error.'
if error_code == cls.ERROR_NO_MORE_EVENTS:
return 'There are no more available watchpoint units.'
if error_code == cls.ERROR_NO_MORE_ADDR_COMP:
return 'No more address comparisons can be set.'
if error_code == cls.ERROR_NO_MORE_DATA_COMP:
return 'No more data comparisons can be set.'
if error_code == cls.ERROR_INVALID_ADDR_MASK:
return 'Invalid flags passed for the address mask.'
if error_code == cls.ERROR_INVALID_DATA_MASK:
return 'Invalid flags passed for the data mask.'
if error_code == cls.ERROR_INVALID_ACCESS_MASK:
return 'Invalid flags passed for the access mask.'
return super(JLinkDataErrors, cls).to_string(error_code)
class JLinkRTTErrors(JLinkGlobalErrors):
__doc__ = 'Enumeration for error codes from RTT.'
RTT_ERROR_CONTROL_BLOCK_NOT_FOUND = -2
@classmethod
def to_string(cls, error_code):
if error_code == cls.RTT_ERROR_CONTROL_BLOCK_NOT_FOUND:
return 'The RTT Control Block has not yet been found (wait?)'
return super(JLinkRTTErrors, cls).to_string(error_code)
class JLinkHost(object):
__doc__ = 'Enumeration for the different JLink hosts: currently only IP and USB.'
USB = 1
IP = 2
USB_OR_IP = USB | IP
class JLinkInterfaces(object):
__doc__ = 'Target interfaces for the J-Link.'
JTAG = 0
SWD = 1
FINE = 3
ICSP = 4
SPI = 5
C2 = 6
class JLinkResetStrategyCortexM3(object):
__doc__ = 'Target reset strategies for the J-Link.\n\n Attributes:\n NORMAL: default reset strategy, does whatever is best to reset.\n CORE: only the core is reset via the ``VECTRESET`` bit.\n RESETPIN: pulls the reset pin low to reset the core and peripherals.\n CONNECT_UNDER_RESET: J-Link connects to target while keeping reset\n active. This is recommented for STM32 devices.\n HALT_AFTER_BTL: halt the core after the bootloader is executed.\n HALT_BEFORE_BTL: halt the core before the bootloader is executed.\n KINETIS: performs a normal reset, but also disables the watchdog.\n ADI_HALT_AFTER_KERNEL: sets the ``SYSRESETREQ`` bit in the ``AIRCR`` in\n order to reset the device.\n CORE_AND_PERIPHERALS: sets the ``SYSRESETREQ`` bit in the ``AIRCR``, and\n the ``VC_CORERESET`` bit in the ``DEMCR`` to make sure that the CPU is\n halted immediately after reset.\n LPC1200: reset for LPC1200 devices.\n S3FN60D: reset for Samsung S3FN60D devices.\n\n Note:\n Please see the J-Link SEGGER Documentation, UM8001, for full information\n about the different reset strategies.\n '
NORMAL = 0
CORE = 1
RESETPIN = 2
CONNECT_UNDER_RESET = 3
HALT_AFTER_BTL = 4
HALT_BEFORE_BTL = 5
KINETIS = 6
ADI_HALT_AFTER_KERNEL = 7
CORE_AND_PERIPHERALS = 8
LPC1200 = 9
S3FN60D = 10
class JLinkFunctions(object):
__doc__ = 'Collection of function prototype and type builders for the J-Link SDK\n API calls.'
LOG_PROTOTYPE = ctypes.CFUNCTYPE(None, ctypes.c_char_p)
UNSECURE_HOOK_PROTOTYPE = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_uint32)
FLASH_PROGRESS_PROTOTYPE = ctypes.CFUNCTYPE(None, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int)
class JLinkCore(object):
__doc__ = 'Enumeration for the different CPU core identifiers.\n\n These are the possible cores for targets the J-Link is connected to.\n Note that these are bitfields.'
NONE = 0
ANY = 4294967295
CORTEX_M1 = 16777471
COLDFIRE = 50331647
CORTEX_M3 = 50331903
CORTEX_M3_R1P0 = 50331664
CORTEX_M3_R1P1 = 50331665
CORTEX_M3_R2P0 = 50331680
SIM = 83886079
XSCALE = 100663295
CORTEX_M0 = 100663551
CORTEX_M_V8BASEL = 100729087
ARM7 = 134217727
ARM7TDMI = 117440767
ARM7TDMI_R3 = 117440575
ARM7TDMI_R4 = 117440591
ARM7TDMI_S = 117441023
ARM7TDMI_S_R3 = 117440831
ARM7TDMI_S_R4 = 117440847
CORTEX_A8 = 134217983
CORTEX_A7 = 134742271
CORTEX_A9 = 134807807
CORTEX_A12 = 134873343
CORTEX_A15 = 134938879
CORTEX_A17 = 135004415
ARM9 = 167772159
ARM9TDMI_S = 150995455
ARM920T = 153092351
ARM922T = 153223423
ARM926EJ_S = 153485823
ARM946E_S = 155582975
ARM966E_S = 157680127
ARM968E_S = 157811199
ARM11 = 201326591
ARM1136 = 188153855
ARM1136J = 188089087
ARM1136J_S = 188089343
ARM1136JF = 188090111
ARM1136JF_S = 188090367
ARM1156 = 190251007
ARM1176 = 192348159
ARM1176J = 192283391
ARM1176J_S = 192283647
ARM1176JF = 192284415
ARM1176JF_S = 192284671
CORTEX_R4 = 201326847
CORTEX_R5 = 201392383
RX = 234881023
RX610 = 218169343
RX62N = 218234879
RX62T = 218300415
RX63N = 218365951
RX630 = 218431487
RX63T = 218497023
RX621 = 218562559
RX62G = 218628095
RX631 = 218693631
RX210 = 219217919
RX21A = 219283455
RX220 = 219348991
RX230 = 219414527
RX231 = 219480063
RX23T = 219545599
RX111 = 220266495
RX110 = 220332031
RX113 = 220397567
RX64M = 221315071
RX71M = 221380607
CORTEX_M4 = 234881279
CORTEX_M7 = 234946815
CORTEX_M_V8MAINL = 235012351
CORTEX_A5 = 251658495
POWER_PC = 285212671
POWER_PC_N1 = 285147391
POWER_PC_N2 = 285147647
MIPS = 301989887
MIPS_M4K = 285278207
MIPS_MICROAPTIV = 285343743
EFM8_UNSPEC = 318767103
CIP51 = 302055423
class JLinkDeviceFamily(object):
__doc__ = 'Enumeration for the difference device families.\n\n These are the possible device families for targets that the J-Link is\n connected to.'
AUTO = 0
CORTEX_M1 = 1
COLDFIRE = 2
CORTEX_M3 = 3
SIMULATOR = 4
XSCALE = 5
CORTEX_M0 = 6
ARM7 = 7
CORTEX_A8 = 8
CORTEX_A9 = 8
ARM9 = 9
ARM10 = 10
ARM11 = 11
CORTEX_R4 = 12
RX = 13
CORTEX_M4 = 14
CORTEX_A5 = 15
POWERPC = 16
MIPS = 17
EFM8 = 18
ANY = 255
class JLinkFlags(object):
__doc__ = 'Enumeration for the different flags that are passed to the J-Link C SDK\n API methods.'
GO_OVERSTEP_BP = 1
DLG_BUTTON_YES = 1
DLG_BUTTON_NO = 2
DLG_BUTTON_OK = 4
DLG_BUTTON_CANCEL = 8
HW_PIN_STATUS_LOW = 0
HW_PIN_STATUS_HIGH = 1
HW_PIN_STATUS_UNKNOWN = 255
class JLinkSWOInterfaces(object):
__doc__ = 'Serial Wire Output (SWO) interfaces.'
UART = 0
MANCHESTER = 1
class JLinkSWOCommands(object):
__doc__ = 'Serial Wire Output (SWO) commands.'
START = 0
STOP = 1
FLUSH = 2
GET_SPEED_INFO = 3
GET_NUM_BYTES = 10
SET_BUFFERSIZE_HOST = 20
SET_BUFFERSIZE_EMU = 21
class JLinkCPUCapabilities(object):
__doc__ = 'Target CPU Cabilities.'
READ_MEMORY = 2
WRITE_MEMORY = 4
READ_REGISTERS = 8
WRITE_REGISTERS = 16
GO = 32
STEP = 64
HALT = 128
IS_HALTED = 256
RESET = 512
RUN_STOP = 1024
TERMINAL = 2048
DCC = 16384
HSS = 32768
class JLinkHaltReasons(object):
__doc__ = 'Halt reasons for the CPU.\n\n Attributes:\n DBGRQ: CPU has been halted because DBGRQ signal asserted.\n CODE_BREAKPOINT: CPU has been halted because of code breakpoint match.\n DATA_BREAKPOINT: CPU has been halted because of data breakpoint match.\n VECTOR_CATCH: CPU has been halted because of vector catch.\n '
DBGRQ = 0
CODE_BREAKPOINT = 1
DATA_BREAKPOINT = 2
VECTOR_CATCH = 3
class JLinkVectorCatchCortexM3(object):
__doc__ = 'Vector catch types for the ARM Cortex M3.\n\n Attributes:\n CORE_RESET: The CPU core reset.\n MEM_ERROR: A memory management error occurred.\n COPROCESSOR_ERROR: Usage fault error accessing the Coprocessor.\n CHECK_ERROR: Usage fault error on enabled check.\n STATE_ERROR: Usage fault state error.\n BUS_ERROR: Normal bus error.\n INT_ERROR: Interrupt or exception service error.\n HARD_ERROR: Hard fault error.\n '
CORE_RESET = 1
MEM_ERROR = 16
COPROCESSOR_ERROR = 32
CHECK_ERROR = 64
STATE_ERROR = 128
BUS_ERROR = 256
INT_ERROR = 512
HARD_ERROR = 1024
class JLinkBreakpoint(object):
__doc__ = 'J-Link breakpoint types.\n\n Attributes:\n SW_RAM: Software breakpont located in RAM.\n SW_FLASH: Software breakpoint located in flash.\n SW: Software breakpoint located in RAM or flash.\n HW: Hardware breakpoint.\n ANY: Allows specifying any time of breakpoint.\n ARM: Breakpoint in ARM mode (only available on ARM 7/9 cores).\n THUMB: Breakpoint in THUMB mode (only available on ARM 7/9 cores).\n '
SW_RAM = 16
SW_FLASH = 32
SW = 240
HW = 4294967040
ANY = 4294967280
ARM = 1
THUMB = 2
class JLinkBreakpointImplementation(object):
__doc__ = 'J-Link breakpoint implementation types.\n\n Attributes:\n HARD: Hardware breakpoint using a breakpoint unit.\n SOFT: Software breakpoint using a breakpoint instruction.\n PENDING: Breakpoint has not been set yet.\n FLASH: Breakpoint set in flash.\n '
HARD = 1
SOFT = 2
PENDING = 4
FLASH = 16
class JLinkEventTypes(object):
__doc__ = 'J-Link data event types.\n\n Attributes:\n BREAKPOINT: breakpoint data event.\n '
BREAKPOINT = 1
class JLinkAccessFlags(object):
__doc__ = 'J-Link access types for data events.\n\n These access types allow specifying the different types of access events\n that should be monitored.\n\n Attributes:\n READ: specifies to monitor read accesses.\n WRITE: specifies to monitor write accesses.\n PRIVILEGED: specifies to monitor privileged accesses.\n SIZE_8BIT: specifies to monitor an 8-bit access width.\n SIZE_16BIT: specifies to monitor an 16-bit access width.\n SIZE_32BIT: specifies to monitor an 32-bit access width.\n '
READ = 0
WRITE = 1
PRIV = 16
SIZE_8BIT = 0
SIZE_16BIT = 2
SIZE_32BIT = 4
class JLinkAccessMaskFlags(object):
__doc__ = 'J-Link access mask flags.\n\n Attributes:\n SIZE: specifies to not care about the access size of the event.\n DIR: specifies to not care about the access direction of the event.\n PRIV: specifies to not care about the access privilege of the event.\n '
SIZE = 6
DIR = 1
PRIV = 16
class JLinkStraceCommand(object):
__doc__ = 'STRACE commmands.'
TRACE_EVENT_SET = 0
TRACE_EVENT_CLR = 1
TRACE_EVENT_CLR_ALL = 2
SET_BUFFER_SIZE = 3
class JLinkStraceEvent(object):
__doc__ = 'STRACE events.'
CODE_FETCH = 0
DATA_ACCESS = 1
DATA_LOAD = 2
DATA_STORE = 3
class JLinkStraceOperation(object):
__doc__ = 'STRACE operation specifiers.'
TRACE_START = 0
TRACE_STOP = 1
TRACE_INCLUDE_RANGE = 2
TRACE_EXCLUDE_RANGE = 3
class JLinkTraceSource(object):
__doc__ = 'Sources for tracing.'
ETB = 0
ETM = 1
MTB = 2
class JLinkTraceCommand(object):
__doc__ = 'J-Link trace commands.'
START = 0
STOP = 1
FLUSH = 2
GET_NUM_SAMPLES = 16
GET_CONF_CAPACITY = 17
SET_CAPACITY = 18
GET_MIN_CAPACITY = 19
GET_MAX_CAPACITY = 20
SET_FORMAT = 32
GET_FORMAT = 33
GET_NUM_REGIONS = 48
GET_REGION_PROPS = 49
GET_REGION_PROPS_EX = 50
class JLinkTraceFormat(object):
__doc__ = 'J-Link trace formats.\n\n Attributes:\n FORMAT_4BIT: 4-bit data.\n FORMAT_8BIT: 8-bit data.\n FORMAT_16BIT: 16-bit data.\n FORMAT_MULTIPLEXED: multiplexing on ETM / buffer link.\n FORMAT_DEMULTIPLEXED: de-multiplexing on ETM / buffer link.\n FORMAT_DOUBLE_EDGE: clock data on both ETM / buffer link edges.\n FORMAT_ETM7_9: ETM7/ETM9 protocol.\n FORMAT_ETM10: ETM10 protocol.\n FORMAT_1BIT: 1-bit data.\n FORMAT_2BIT: 2-bit data.\n '
FORMAT_4BIT = 1
FORMAT_8BIT = 2
FORMAT_16BIT = 4
FORMAT_MULTIPLEXED = 8
FORMAT_DEMULTIPLEXED = 16
FORMAT_DOUBLE_EDGE = 32
FORMAT_ETM7_9 = 64
FORMAT_ETM10 = 128
FORMAT_1BIT = 256
FORMAT_2BIT = 512
class JLinkROMTable(object):
__doc__ = 'The J-Link ROM tables.'
NONE = 256
ETM = 257
MTB = 258
TPIU = 259
ITM = 260
DWT = 261
FPB = 262
NVIC = 263
TMC = 264
TF = 265
PTM = 266
ETB = 267
DBG = 268
APBAP = 269
AHBAP = 270
SECURE = 271
class JLinkRTTCommand(object):
__doc__ = 'RTT commands.'
START = 0
STOP = 1
GETDESC = 2
GETNUMBUF = 3
GETSTAT = 4
class JLinkRTTDirection(object):
__doc__ = 'RTT Direction.'
UP = 0
DOWN = 1
# okay decompiling ./pylink/enums.pyc

44
pylink/errors.py Normal file
View File

@ -0,0 +1,44 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: pylink/errors.py
from . import enums
from . import util
class JLinkException(enums.JLinkGlobalErrors, Exception):
__doc__ = 'Generic J-Link exception.'
def __init__(self, code):
message = code
self.code = None
if util.is_integer(code):
message = self.to_string(code)
self.code = code
super(JLinkException, self).__init__(message)
self.message = message
class JLinkEraseException(enums.JLinkEraseErrors, JLinkException):
__doc__ = 'J-Link erase exception.'
class JLinkFlashException(enums.JLinkFlashErrors, JLinkException):
__doc__ = 'J-Link flash exception.'
class JLinkWriteException(enums.JLinkWriteErrors, JLinkException):
__doc__ = 'J-Link write exception.'
class JLinkReadException(enums.JLinkReadErrors, JLinkException):
__doc__ = 'J-Link read exception.'
class JLinkDataException(enums.JLinkDataErrors, JLinkException):
__doc__ = 'J-Link data event exception.'
class JLinkRTTException(enums.JLinkRTTErrors, JLinkException):
__doc__ = 'J-Link RTT exception.'
# okay decompiling ./pylink/errors.pyc

4629
pylink/jlink.py Normal file

File diff suppressed because it is too large Load Diff

114
pylink/jlock.py Normal file
View File

@ -0,0 +1,114 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: pylink/jlock.py
import psutil, errno, tempfile, os
class JLock(object):
__doc__ = 'Lockfile for accessing a particular J-Link.\n\n The J-Link SDK does not prevent accessing the same J-Link multiple times\n from the same process or multiple processes. As a result, a user can\n have the same J-Link being accessed by multiple processes. This class\n provides an interface to a lock-file like structure for the physical\n J-Links to ensure that any instance of a ``JLink`` with an open emulator\n connection will be the only one accessing that emulator.\n\n This class uses a PID-style lockfile to allow acquiring of the lockfile in\n the instances where the lockfile exists, but the process which created it\n is no longer running.\n\n To share the same emulator connection between multiple threads, processes,\n or functions, a single instance of a ``JLink`` should be created and passed\n between the threads and processes.\n\n Attributes:\n name: the name of the lockfile.\n path: full path to the lockfile.\n fd: file description of the lockfile.\n acquired: boolean indicating if the lockfile lock has been acquired.\n '
SERIAL_NAME_FMT = '.pylink-usb-{}.lck'
IPADDR_NAME_FMT = '.pylink-ip-{}.lck'
def __init__(self, serial_no):
"""Creates an instance of a ``JLock`` and populates the name.
Note:
This method may fail if there is no temporary directory in which to
have the lockfile placed.
Args:
self (JLock): the ``JLock`` instance
serial_no (int): the serial number of the J-Link
Returns:
``None``
"""
self.name = self.SERIAL_NAME_FMT.format(serial_no)
self.acquired = False
self.fd = None
self.path = None
self.path = os.path.join(tempfile.tempdir, self.name)
def __del__(self):
"""Cleans up the lockfile instance if it was acquired.
Args:
self (JLock): the ``JLock`` instance
Returns:
``None``
"""
self.release()
def acquire(self):
"""Attempts to acquire a lock for the J-Link lockfile.
If the lockfile exists but does not correspond to an active process,
the lockfile is first removed, before an attempt is made to acquire it.
Args:
self (Jlock): the ``JLock`` instance
Returns:
``True`` if the lock was acquired, otherwise ``False``.
Raises:
OSError: on file errors.
"""
if os.path.exists(self.path):
try:
pid = None
with open(self.path, 'r') as f:
line = f.readline().strip()
pid = int(line)
if not psutil.pid_exists(pid):
os.remove(self.path)
except ValueError as e:
try:
os.remove(self.path)
finally:
e = None
del e
except IOError as e:
try:
pass
finally:
e = None
del e
try:
self.fd = os.open(self.path, os.O_CREAT | os.O_EXCL | os.O_RDWR)
to_write = '%s%s' % (os.getpid(), os.linesep)
os.write(self.fd, to_write.encode())
except OSError as e:
try:
if not os.path.exists(self.path):
raise
return False
finally:
e = None
del e
self.acquired = True
return True
def release(self):
"""Cleans up the lockfile if it was acquired.
Args:
self (JLock): the ``JLock`` instance
Returns:
``False`` if the lock was not released or the lock is not acquired,
otherwise ``True``.
"""
if not self.acquired:
return False
os.close(self.fd)
if os.path.exists(self.path):
os.remove(self.path)
self.acquired = False
return True
# okay decompiling ./pylink/jlock.pyc

346
pylink/library.py Normal file
View File

@ -0,0 +1,346 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: pylink/library.py
from . import util
import ctypes
import ctypes.util as ctypes_util
import os, sys, tempfile
class Library(object):
__doc__ = 'Wrapper to provide easy access to loading the J-Link SDK DLL.\n\n This class provides a convenience for finding and loading the J-Link DLL\n across multiple platforms, and accounting for the inconsistencies between\n Windows and nix-based platforms.\n\n Attributes:\n _standard_calls_: list of names of the methods for the API calls that\n must be converted to standard calling convention on the Windows\n platform.\n JLINK_SDK_NAME: name of the J-Link DLL on nix-based platforms.\n WINDOWS_JLINK_SDK_NAME: name of the J-Link DLL on Windows platforms.\n '
_standard_calls_ = [
'JLINK_Configure',
'JLINK_DownloadFile',
'JLINK_GetAvailableLicense',
'JLINK_GetPCode',
'JLINK_PrintConfig',
'JLINK_EraseChip',
'JLINK_SPI_Transfer',
'JLINK_GetpFunc',
'JLINK_GetMemZones',
'JLINK_ReadMemZonedEx',
'JLINK_SetHookUnsecureDialog',
'JLINK_WriteMemZonedEx',
'JLINK_DIALOG_Configure',
'JLINK_DIALOG_ConfigureEx',
'JLINK_EMU_GPIO_GetProps',
'JLINK_EMU_GPIO_GetState',
'JLINK_EMU_GPIO_SetState',
'JLINK_EMU_AddLicense',
'JLINK_EMU_EraseLicenses',
'JLINK_EMU_GetLicenses',
'JLINK_HSS_GetCaps',
'JLINK_HSS_Start',
'JLINK_HSS_Stop',
'JLINK_HSS_Read',
'JLINK_POWERTRACE_Control',
'JLINK_POWERTRACE_Read',
'JLINK_RTTERMINAL_Control',
'JLINK_RTTERMINAL_Read',
'JLINK_RTTERMINAL_Write',
'JLINK_STRACE_Config',
'JLINK_STRACE_Control',
'JLINK_STRACE_Read',
'JLINK_STRACE_Start',
'JLINK_STRACE_Stop',
'JLINK_SWD_GetData',
'JLINK_SWD_GetU8',
'JLINK_SWD_GetU16',
'JLINK_SWD_GetU32',
'JLINK_SWD_StoreGetRaw',
'JLINK_SWD_StoreRaw',
'JLINK_SWD_SyncBits',
'JLINK_SWD_SyncBytes',
'JLINK_SetFlashProgProgressCallback']
JLINK_SDK_NAME = 'libjlinkarm'
WINDOWS_32_JLINK_SDK_NAME = 'JLinkARM'
WINDOWS_64_JLINK_SDK_NAME = 'JLink_x64'
@classmethod
def get_appropriate_windows_sdk_name(cls):
"""Returns the appropriate JLink SDK library name on Windows depending
on 32bit or 64bit Python variant.
SEGGER delivers two variants of their dynamic library on Windows:
- ``JLinkARM.dll`` for 32-bit platform
- ``JLink_x64.dll`` for 64-bit platform
Args:
cls (Library): the ``Library`` class
Returns:
The name of the library depending on the platform this module is run on.
"""
if sys.maxsize == 9223372036854775807:
return Library.WINDOWS_64_JLINK_SDK_NAME
return Library.WINDOWS_32_JLINK_SDK_NAME
@classmethod
def find_library_windows(cls):
r"""Loads the SEGGER DLL from the windows installation directory.
On Windows, these are found either under:
- ``C:\Program Files\SEGGER\JLink``
- ``C:\Program Files (x86)\SEGGER\JLink``.
Args:
cls (Library): the ``Library`` class
Returns:
The paths to the J-Link library files in the order that they are
found.
"""
dll = cls.get_appropriate_windows_sdk_name() + '.dll'
root = 'C:\\'
for d in os.listdir(root):
dir_path = os.path.join(root, d)
if d.startswith('Program Files'):
if os.path.isdir(dir_path):
dir_path = os.path.join(dir_path, 'SEGGER')
if not os.path.isdir(dir_path):
continue
else:
ds = filter(lambda x: x.startswith('JLink')
, os.listdir(dir_path))
for jlink_dir in ds:
lib_path = os.path.join(dir_path, jlink_dir, dll)
if os.path.isfile(lib_path):
yield lib_path
@classmethod
def find_library_linux(cls):
"""Loads the SEGGER DLL from the root directory.
On Linux, the SEGGER tools are installed under the ``/opt/SEGGER``
directory with versioned directories having the suffix ``_VERSION``.
Args:
cls (Library): the ``Library`` class
Returns:
The paths to the J-Link library files in the order that they are
found.
"""
dll = Library.JLINK_SDK_NAME
root = os.path.join('/', 'opt', 'SEGGER')
for directory_name, subdirs, files in os.walk(root):
fnames = []
x86_found = False
for f in files:
path = os.path.join(directory_name, f)
if os.path.isfile(path):
if f.startswith(dll):
fnames.append(f)
if '_x86' in path:
x86_found = True
for fname in fnames:
fpath = os.path.join(directory_name, fname)
if util.is_os_64bit():
if '_x86' not in fname:
yield fpath
else:
if x86_found:
if '_x86' in fname:
yield fpath
else:
yield fpath
@classmethod
def find_library_darwin(cls):
r"""Loads the SEGGER DLL from the installed applications.
This method accounts for the all the different ways in which the DLL
may be installed depending on the version of the DLL. Always uses
the first directory found.
SEGGER's DLL is installed in one of three ways dependent on which
which version of the SEGGER tools are installed:
======== ============================================================
Versions Directory
======== ============================================================
< 5.0.0 ``/Applications/SEGGER/JLink\ NUMBER``
< 6.0.0 ``/Applications/SEGGER/JLink/libjlinkarm.major.minor.dylib``
>= 6.0.0 ``/Applications/SEGGER/JLink/libjlinkarm``
======== ============================================================
Args:
cls (Library): the ``Library`` class
Returns:
The path to the J-Link library files in the order they are found.
"""
dll = Library.JLINK_SDK_NAME
root = os.path.join('/', 'Applications', 'SEGGER')
if not os.path.isdir(root):
return
for d in os.listdir(root):
dir_path = os.path.join(root, d)
if os.path.isdir(dir_path):
if d.startswith('JLink'):
files = list((f for f in os.listdir(dir_path) if os.path.isfile(os.path.join(dir_path, f))))
if dll + '.dylib' in files:
yield os.path.join(dir_path, dll + '.dylib')
else:
for f in files:
if f.startswith(dll):
yield os.path.join(dir_path, f)
def __init__(self, dllpath=None):
"""Initializes an instance of a ``Library``.
Loads the default J-Link DLL if ``dllpath`` is ``None``, otherwise
loads the DLL specified by the given ``dllpath``.
Args:
self (Library): the ``Library`` instance
dllpath (str): the DLL to load into the library
Returns:
``None``
"""
self._lib = None
self._winlib = None
self._path = None
self._windows = sys.platform.startswith('win')
self._cygwin = sys.platform.startswith('cygwin')
self._temp = None
if self._windows or self._cygwin:
self._sdk = self.get_appropriate_windows_sdk_name()
else:
self._sdk = self.JLINK_SDK_NAME
if dllpath is not None:
self.load(dllpath)
else:
self.load_default()
def __del__(self):
"""Cleans up the temporary DLL file created when the lib was loaded.
Args:
self (Library): the ``Library`` instance
Returns:
``None``
"""
self.unload()
def load_default(self):
"""Loads the default J-Link SDK DLL.
The default J-Link SDK is determined by first checking if ``ctypes``
can find the DLL, then by searching the platform-specific paths.
Args:
self (Library): the ``Library`` instance
Returns:
``True`` if the DLL was loaded, otherwise ``False``.
"""
path = ctypes_util.find_library(self._sdk)
if not path is None or self._windows or self._cygwin:
path = next(self.find_library_windows(), None)
else:
if sys.platform.startswith('linux'):
path = next(self.find_library_linux(), None)
else:
if sys.platform.startswith('darwin'):
path = next(self.find_library_darwin(), None)
if path is not None:
return self.load(path)
return False
def load(self, path=None):
"""Loads the specified DLL, if any, otherwise re-loads the current DLL.
If ``path`` is specified, loads the DLL at the given ``path``,
otherwise re-loads the DLL currently specified by this library.
Note:
This creates a temporary DLL file to use for the instance. This is
necessary to work around a limitation of the J-Link DLL in which
multiple J-Links cannot be accessed from the same process.
Args:
self (Library): the ``Library`` instance
path (path): path to the DLL to load
Returns:
``True`` if library was loaded successfully.
Raises:
OSError: if there is no J-LINK SDK DLL present at the path.
See Also:
`J-Link Multi-session <http://forum.segger.com/index.php?page=Thread&threadID=669>`_.
"""
self.unload()
self._path = path or self._path
if self._windows or self._cygwin:
suffix = '.dll'
else:
if sys.platform.startswith('darwin'):
suffix = '.dylib'
else:
suffix = '.so'
tf = tempfile.NamedTemporaryFile(delete=False, suffix=suffix)
with open(tf.name, 'wb') as outputfile:
with open(self._path, 'rb') as inputfile:
outputfile.write(inputfile.read())
tf.close()
self._temp = tf
self._lib = ctypes.cdll.LoadLibrary(tf.name)
if self._windows:
self._winlib = ctypes.windll.LoadLibrary(tf.name)
for stdcall in self._standard_calls_:
if hasattr(self._winlib, stdcall):
setattr(self._lib, stdcall, getattr(self._winlib, stdcall))
return True
def unload(self):
"""Unloads the library's DLL if it has been loaded.
This additionally cleans up the temporary DLL file that was created
when the library was loaded.
Args:
self (Library): the ``Library`` instance
Returns:
``True`` if the DLL was unloaded, otherwise ``False``.
"""
unloaded = False
if self._lib is not None:
if self._winlib is not None:
ctypes.windll.kernel32.FreeLibrary.argtypes = (
ctypes.c_void_p,)
ctypes.windll.kernel32.FreeLibrary(self._lib._handle)
ctypes.windll.kernel32.FreeLibrary(self._winlib._handle)
self._lib = None
self._winlib = None
unloaded = True
else:
del self._lib
self._lib = None
unloaded = True
if self._temp is not None:
os.remove(self._temp.name)
self._temp = None
return unloaded
def dll(self):
"""Returns the DLL for the underlying shared library.
Args:
self (Library): the ``Library`` instance
Returns:
A ``ctypes`` DLL instance if one was loaded, otherwise ``None``.
"""
return self._lib
# okay decompiling ./pylink/library.pyc

206
pylink/registers.py Normal file
View File

@ -0,0 +1,206 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: pylink/registers.py
import ctypes
class IDCodeRegisterBits(ctypes.LittleEndianStructure):
__doc__ = 'This class holds the different bit masks for the IDCode register.\n\n Attributes:\n valid: validity bit, should always be ``0``.\n manufactuer: the JEDEC Manufacturer ID.\n part_no: the part number defined by the manufacturer.\n version_code: the version code.\n '
_fields_ = [
(
'valid', ctypes.c_uint32, 1),
(
'manufacturer', ctypes.c_uint32, 11),
(
'part_no', ctypes.c_uint32, 16),
(
'version_code', ctypes.c_uint32, 4)]
class IDCodeRegisterFlags(ctypes.Union):
__doc__ = 'Mask for the IDCode register bits.\n\n Attributes:\n value: the value stored in the mask.\n '
_anonymous_ = ('bit', )
_fields_ = [
(
'bit', IDCodeRegisterBits),
(
'value', ctypes.c_uint32)]
class AbortRegisterBits(ctypes.LittleEndianStructure):
__doc__ = 'This class holds the different bit mask for the Abort Register.\n\n Attributes:\n DAPABORT: write ``1`` to trigger a DAP abort.\n STKCMPCLR: write ``1`` to clear the ``STICKYCMP`` sticky compare flag\n (only supported on SW-DP).\n STKERRCLR: write ``1`` to clear the ``STICKYERR`` sticky error flag\n (only supported on SW-DP).\n WDERRCLR: write ``1`` to clear the ``WDATAERR`` write data error flag\n (only supported on SW-DP).\n ORUNERRCLR: write ``1`` to clear the ``STICKYORUN`` overrun error flag\n (only supported on SW-DP).\n '
_fields_ = [
(
'DAPABORT', ctypes.c_uint32, 1),
(
'STKCMPCLR', ctypes.c_uint32, 1),
(
'STKERRCLR', ctypes.c_uint32, 1),
(
'WDERRCLR', ctypes.c_uint32, 1),
(
'ORUNERRCLR', ctypes.c_uint32, 1),
(
'RESERVED', ctypes.c_uint32, 27)]
class AbortRegisterFlags(ctypes.Union):
__doc__ = 'Mask for the abort register bits.\n\n Attributes:\n value: the value stored in the mask.\n '
_anonymous_ = ('bit', )
_fields_ = [
(
'bit', AbortRegisterBits),
(
'value', ctypes.c_uint32)]
class ControlStatusRegisterBits(ctypes.LittleEndianStructure):
__doc__ = 'This class holds the different bit masks for the DP Control / Status\n Register bit assignments.\n\n Attributes:\n ORUNDETECT: if set, enables overrun detection.\n STICKYORUN: if overrun is enabled, is set when overrun occurs.\n TRNMODE: transfer mode for acess port operations.\n STICKYCMP: is set when a match occurs on a pushed compare or verify\n operation.\n STICKYERR: is set when an error is returned by an access port\n transaction.\n READOK: is set when the response to a previous access port or ``RDBUFF``\n was ``OK``.\n WDATAERR: set to ``1`` if a Write Data Error occurs.\n MASKLANE: bytes to be masked in pushed compare and verify operations.\n TRNCNT: transaction counter.\n RESERVED: reserved.\n CDBGRSTREQ: debug reset request.\n CDBGRSTACK: debug reset acknowledge.\n CDBGPWRUPREQ: debug power-up request.\n CDBGPWRUPACK: debug power-up acknowledge.\n CSYSPWRUPREQ: system power-up request\n CSYSPWRUPACK: system power-up acknowledge.\n\n See also:\n See the ARM documentation on the significance of these masks\n `here <http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ihi0031c/index.html>`_.\n '
_fields_ = [
(
'ORUNDETECT', ctypes.c_uint32, 1),
(
'STICKYORUN', ctypes.c_uint32, 1),
(
'TRNMODE', ctypes.c_uint32, 2),
(
'STICKYCMP', ctypes.c_uint32, 1),
(
'STICKYERR', ctypes.c_uint32, 1),
(
'READOK', ctypes.c_uint32, 1),
(
'WDATAERR', ctypes.c_uint32, 1),
(
'MASKLANE', ctypes.c_uint32, 4),
(
'TRNCNT', ctypes.c_uint32, 12),
(
'RESERVED', ctypes.c_uint32, 2),
(
'CDBGRSTREQ', ctypes.c_uint32, 1),
(
'CDBGRSTACK', ctypes.c_uint32, 1),
(
'CDBGPWRUPREQ', ctypes.c_uint32, 1),
(
'CDBGPWRUPACK', ctypes.c_uint32, 1),
(
'CSYSPWRUPREQ', ctypes.c_uint32, 1),
(
'CSYSPWRUPACK', ctypes.c_uint32, 1)]
class ControlStatusRegisterFlags(ctypes.Union):
__doc__ = 'Mask for the control/status register bits.\n\n Attributes:\n value: the value stored in the mask.\n '
_anonymous_ = ('bit', )
_fields_ = [
(
'bit', ControlStatusRegisterBits),
(
'value', ctypes.c_uint32)]
class SelectRegisterBits(ctypes.LittleEndianStructure):
__doc__ = 'This class holds the different bit masks for the AP Select Register.\n\n Attributes:\n CTRLSEL: SW-DP debug port address bank select.\n RESERVED_A: reserved.\n APBANKSEL: selects the active four-word register window on the current\n access port.\n RESERVED_B: reserved.\n APSEL: selects the current access port.\n '
_fields_ = [
(
'CTRLSEL', ctypes.c_uint32, 1),
(
'RESERVED_A', ctypes.c_uint32, 3),
(
'APBANKSEL', ctypes.c_uint32, 4),
(
'RESERVED_B', ctypes.c_uint32, 16),
(
'APSEL', ctypes.c_uint32, 8)]
class SelectRegisterFlags(ctypes.Union):
__doc__ = 'Mask for the select register bits.\n\n Attributes:\n value: the value stored in the mask.\n '
_anonymous_ = ('bit', )
_fields_ = [
(
'bit', SelectRegisterBits),
(
'value', ctypes.c_uint32)]
class MDMAPControlRegisterBits(ctypes.LittleEndianStructure):
__doc__ = 'This class holds the different bit masks for the MDM-AP Control\n Register.\n\n Attributes:\n flash_mass_erase: set to cause a mass erase, this is cleared\n automatically when a mass erase finishes.\n debug_disable: set to disable debug, clear to allow debug.\n debug_request: set to force the core to halt.\n sys_reset_request: set to force a system reset.\n core_hold_reset: set to suspend the core in reset at the end of reset\n sequencing.\n VLLDBGREQ: set to hold the system in reset after the next recovery from\n VLLSx (Very Low Leakage Stop).\n VLLDBGACK: set to release a system held in reset following a VLLSx\n (Very Low Leakage Stop) recovery.\n VLLSTATACK: set to acknowledge that the DAP LLS (Low Leakage Stop) and\n VLLS (Very Low Leakage Stop) status bits have read.\n '
_fields_ = [
(
'flash_mass_erase', ctypes.c_uint8, 1),
(
'debug_disable', ctypes.c_uint8, 1),
(
'debug_request', ctypes.c_uint8, 1),
(
'sys_reset_request', ctypes.c_uint8, 1),
(
'core_hold_reset', ctypes.c_uint8, 1),
(
'VLLDBGREQ', ctypes.c_uint8, 1),
(
'VLLDBGACK', ctypes.c_uint8, 1),
(
'VLLSTATACK', ctypes.c_uint8, 1)]
class MDMAPControlRegisterFlags(ctypes.Union):
__doc__ = 'Mask for the MDM-AP control register bits.\n\n Attributes:\n value: the value stored in the mask.\n '
_anonymous_ = ('bit', )
_fields_ = [
(
'bit', MDMAPControlRegisterBits),
(
'value', ctypes.c_uint8)]
class MDMAPStatusRegisterBits(ctypes.LittleEndianStructure):
__doc__ = 'Holds the bit masks for the MDM-AP Status Register.\n\n Attributes:\n flash_mass_erase_ack: cleared after a system reset, indicates that a\n flash mass erase was acknowledged.\n flash_ready: indicates that flash has been initialized and can be\n configured.\n system_security: if set, system is secure and debugger cannot access the\n memory or system bus.\n system_reset: ``1`` if system is in reset, otherwise ``0``.\n mass_erase_enabled: ``1`` if MCU can be mass erased, otherwise ``0``.\n low_power_enabled: ``1`` if low power stop mode is enabled, otherwise ``0``.\n very_low_power_mode: ``1`` if device is in very low power mode.\n LLSMODEEXIT: indicates an exit from LLS mode has occurred.\n VLLSxMODEEXIT: indicates an exit from VLLSx mode has occured.\n core_halted; indicates core has entered debug halt mode.\n core_deep_sleep: indicates core has entered a low power mode.\n core_sleeping: indicates the core has entered a low power mode.\n\n Note:\n if ``core_sleeping & !core_deep_sleep``, then the core is in VLPW (very\n low power wait) mode, otherwise if ``core_sleeping & core_deep_sleep``,\n then it is in VLPS (very low power stop) mode.\n '
_fields_ = [
(
'flash_mass_erase_ack', ctypes.c_uint32, 1),
(
'flash_ready', ctypes.c_uint32, 1),
(
'system_security', ctypes.c_uint32, 1),
(
'system_reset', ctypes.c_uint32, 1),
(
'RESERVED_A', ctypes.c_uint32, 1),
(
'mass_erase_enabled', ctypes.c_uint32, 1),
(
'backdoor_access_enabled', ctypes.c_uint32, 1),
(
'low_power_enabled', ctypes.c_uint32, 1),
(
'very_low_power_mode', ctypes.c_uint32, 1),
(
'LLSMODEEXIT', ctypes.c_uint32, 1),
(
'VLLSxMODEEXIT', ctypes.c_uint32, 1),
(
'RESERVED_B', ctypes.c_uint32, 5),
(
'core_halted', ctypes.c_uint32, 1),
(
'core_deep_sleep', ctypes.c_uint32, 1),
(
'core_sleeping', ctypes.c_uint32, 1),
(
'RESERVED_C', ctypes.c_uint32, 13)]
class MDMAPStatusRegisterFlags(ctypes.Union):
__doc__ = 'Mask for the MDM-AP status register bits.\n\n Attributes:\n value: the value stored in the mask.\n '
_anonymous_ = ('bit', )
_fields_ = [
(
'bit', MDMAPStatusRegisterBits),
(
'value', ctypes.c_uint32)]
# okay decompiling ./pylink/registers.pyc

907
pylink/structs.py Normal file
View File

@ -0,0 +1,907 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: pylink/structs.py
from . import enums
import ctypes
class JLinkConnectInfo(ctypes.Structure):
__doc__ = 'J-Link connection info structure.\n\n Attributes:\n SerialNumber: J-Link serial number.\n Connection: type of connection (e.g. ``enums.JLinkHost.USB``)\n USBAddr: USB address if connected via USB.\n aIPAddr: IP address if connected via IP.\n Time: Time period (ms) after which UDP discover answer was received.\n Time_us: Time period (uS) after which UDP discover answer was received.\n HWVersion: Hardware version of J-Link, if connected via IP.\n abMACAddr: MAC Address, if connected via IP.\n acProduct: Product name, if connected via IP.\n acNickname: Nickname, if connected via IP.\n acFWString: Firmware string, if connected via IP.\n IsDHCPAssignedIP: Is IP address reception via DHCP.\n IsDHCPAssignedIPIsValid: True if connected via IP.\n NumIPConnections: Number of IP connections currently established.\n NumIPConnectionsIsValid: True if connected via IP.\n aPadding: Bytes reserved for future use.\n '
_fields_ = [
(
'SerialNumber', ctypes.c_uint32),
(
'Connection', ctypes.c_ubyte),
(
'USBAddr', ctypes.c_uint32),
(
'aIPAddr', ctypes.c_uint8 * 16),
(
'Time', ctypes.c_int),
(
'Time_us', ctypes.c_uint64),
(
'HWVersion', ctypes.c_uint32),
(
'abMACAddr', ctypes.c_uint8 * 6),
(
'acProduct', ctypes.c_char * 32),
(
'acNickname', ctypes.c_char * 32),
(
'acFWString', ctypes.c_char * 112),
(
'IsDHCPAssignedIP', ctypes.c_char),
(
'IsDHCPAssignedIPIsValid', ctypes.c_char),
(
'NumIPConnections', ctypes.c_char),
(
'NumIPConnectionsIsValid', ctypes.c_char),
(
'aPadding', ctypes.c_uint8 * 34)]
def __repr__(self):
"""Returns a representation of this class.
Args:
self (JLinkConnectInfo): the ``JlinkConnectInfo`` instance
Returns:
String representation of the class.
"""
return 'JLinkConnectInfo(%s)' % self.__str__()
def __str__(self):
"""Returns a string representation of the connection info.
Args:
self (JLinkConnectInfo): the ``JLinkConnectInfo`` instance
Returns:
String specifying the product, its serial number, and the type of
connection that it has (one of USB or IP).
"""
conn = 'USB' if self.Connection == 1 else 'IP'
return '%s <Serial No. %s, Conn. %s>' % (self.acProduct.decode(), self.SerialNumber, conn)
class JLinkFlashArea(ctypes.Structure):
__doc__ = 'Definition for a region of Flash.\n\n Attributes:\n Addr: address where the flash area starts.\n Size: size of the flash area.\n '
_fields_ = [
(
'Addr', ctypes.c_uint32),
(
'Size', ctypes.c_uint32)]
def __repr__(self):
"""Returns a representation of the instance.
Args:
self (FlashArea): the ``FlashArea`` instance
Returns:
String representation of the Flash Area.
"""
return '%s(%s)' % (self.__class__.__name__, self.__str__())
def __str__(self):
"""Returns a string representation of the instance.
Args:
self (FlashArea): the ``FlashArea`` instance
Returns:
String specifying address of flash region, and its size.
"""
return 'Address = 0x%x, Size = %s' % (self.Addr, self.Size)
class JLinkRAMArea(JLinkFlashArea):
__doc__ = 'Definition for a region of RAM.\n\n Attributes:\n Addr: address where the flash area starts.\n Size: size of the flash area.\n '
class JLinkDeviceInfo(ctypes.Structure):
__doc__ = 'J-Link device information.\n\n This structure is used to represent a device that is supported by the\n J-Link.\n\n Attributes:\n SizeOfStruct: Size of the struct (DO NOT CHANGE).\n sName: name of the device.\n CoreId: core identifier of the device.\n FlashAddr: base address of the internal flash of the device.\n RAMAddr: base address of the internal RAM of the device.\n EndianMode: the endian mode of the device (0 -> only little endian,\n 1 -> only big endian, 2 -> both).\n FlashSize: total flash size in bytes.\n RAMSize: total RAM size in bytes.\n sManu: device manufacturer.\n aFlashArea: a list of ``JLinkFlashArea`` instances.\n aRamArea: a list of ``JLinkRAMArea`` instances.\n Core: CPU core.\n '
_fields_ = [
(
'SizeofStruct', ctypes.c_uint32),
(
'sName', ctypes.POINTER(ctypes.c_char)),
(
'CoreId', ctypes.c_uint32),
(
'FlashAddr', ctypes.c_uint32),
(
'RAMAddr', ctypes.c_uint32),
(
'EndianMode', ctypes.c_char),
(
'FlashSize', ctypes.c_uint32),
(
'RAMSize', ctypes.c_uint32),
(
'sManu', ctypes.POINTER(ctypes.c_char)),
(
'aFlashArea', JLinkFlashArea * 32),
(
'aRAMArea', JLinkRAMArea * 32),
(
'Core', ctypes.c_uint32)]
def __init__(self, *args, **kwargs):
(super(JLinkDeviceInfo, self).__init__)(*args, **kwargs)
self.SizeofStruct = ctypes.sizeof(self)
def __repr__(self):
"""Returns a representation of this instance.
Args:
self (JLinkDeviceInfo): the ``JLinkDeviceInfo`` instance
Returns:
Returns a string representation of the instance.
"""
return 'JLinkDeviceInfo(%s)' % self.__str__()
def __str__(self):
"""Returns a string representation of this instance.
Args:
self (JLinkDeviceInfo): the ``JLinkDeviceInfo`` instance
Returns:
Returns a string specifying the device name, core, and manufacturer.
"""
manu = self.manufacturer
return '%s <Core Id. %s, Manu. %s>' % (self.name, self.Core, manu)
@property
def name(self):
"""Returns the name of the device.
Args:
self (JLinkDeviceInfo): the ``JLinkDeviceInfo`` instance
Returns:
Device name.
"""
return ctypes.cast(self.sName, ctypes.c_char_p).value.decode()
@property
def manufacturer(self):
"""Returns the name of the manufacturer of the device.
Args:
self (JLinkDeviceInfo): the ``JLinkDeviceInfo`` instance
Returns:
Manufacturer name.
"""
buf = ctypes.cast(self.sManu, ctypes.c_char_p).value
if buf:
return buf.decode()
class JLinkHardwareStatus(ctypes.Structure):
__doc__ = 'Definition for the hardware status information for a J-Link.\n\n Attributes:\n VTarget: target supply voltage.\n tck: measured state of TCK pin.\n tdi: measured state of TDI pin.\n tdo: measured state of TDO pin.\n tms: measured state of TMS pin.\n tres: measured state of TRES pin.\n trst: measured state of TRST pin.\n '
_fields_ = [
(
'VTarget', ctypes.c_uint16),
(
'tck', ctypes.c_uint8),
(
'tdi', ctypes.c_uint8),
(
'tdo', ctypes.c_uint8),
(
'tms', ctypes.c_uint8),
(
'tres', ctypes.c_uint8),
(
'trst', ctypes.c_uint8)]
def __repr__(self):
"""Returns a string representation of the instance.
Args:
self (JLinkHardwareStatus): the ``JlinkHardwareStatus`` instance
Returns:
String representation of the instance.
"""
return '%s(VTarget=%dmV)' % (self.__class__.__name__, self.voltage)
@property
def voltage(self):
"""Returns the target supply voltage.
This is an alias for ``.VTarget``.
Args:
self (JLInkHardwareStatus): the ``JLinkHardwareStatus`` instance
Returns:
Target supply voltage as an integer.
"""
return self.VTarget
class JLinkGPIODescriptor(ctypes.Structure):
__doc__ = 'Definition for the structure that details the name and capabilities of a\n user-controllable GPIO.\n\n Attributes:\n acName: name of the GPIO.\n Caps: bitfield of capabilities.\n '
_fields_ = [
(
'acName', ctypes.c_char * 32),
(
'Caps', ctypes.c_uint32)]
def __repr__(self):
"""Returns a string representation of the instance.
Args:
self (JLinkGPIODescriptor): the ``JLinkGPIODescriptor`` instance
Returns:
String representation of the instance.
"""
return '%s(%s)' % (self.__class__.__name__, self.__str__())
def __str__(self):
"""Returns the GPIO name.
Args:
self (JLinkGPIODescriptor): the ``JLInkGPIODescriptor`` instance
Returns:
GPIO name.
"""
return self.acName.decode()
class JLinkMemoryZone(ctypes.Structure):
__doc__ = 'Represents a CPU memory zone.\n\n Attributes:\n sName: initials of the memory zone.\n sDesc: name of the memory zone.\n VirtAddr: start address of the virtual address space of the memory zone.\n abDummy: reserved for future use.\n '
_fields_ = [
(
'sName', ctypes.c_char_p),
(
'sDesc', ctypes.c_char_p),
(
'VirtAddr', ctypes.c_uint64),
(
'abDummy', ctypes.c_uint8 * 16)]
def __repr__(self):
"""Returns a string representation of the instance
Args:
self: the ``JLinkMemoryZone`` instance
Returns:
String representation of the instance.
"""
return '%s(%s)' % (self.__class__.__name__, self.__str__())
def __str__(self):
"""Returns a formatted string describing the memory zone.
Args:
self: the ``JLinkMemoryZone`` instance
Returns:
String representation of the memory zone.
"""
return '%s <Desc. %s, VirtAddr. 0x%x>' % (self.sName, self.sDesc, self.VirtAddr)
@property
def name(self):
"""Alias for the memory zone name.
Args:
self (JLinkMemoryZone): the ``JLinkMemoryZone`` instance
Returns:
The memory zone name.
"""
return self.sName
class JLinkSpeedInfo(ctypes.Structure):
__doc__ = "Represents information about an emulator's supported speeds.\n\n The emulator can support all target interface speeds calculated by dividing\n the base frequency by atleast ``MinDiv``.\n\n Attributes:\n SizeOfStruct: the size of this structure.\n BaseFreq: Base frequency (in HZ) used to calculate supported speeds.\n MinDiv: minimum divider allowed to divide the base frequency.\n SupportAdaptive: ``1`` if emulator supports adaptive clocking, otherwise\n ``0``.\n "
_fields_ = [
(
'SizeOfStruct', ctypes.c_uint32),
(
'BaseFreq', ctypes.c_uint32),
(
'MinDiv', ctypes.c_uint16),
(
'SupportAdaptive', ctypes.c_uint16)]
def __init__(self):
super(JLinkSpeedInfo, self).__init__()
self.SizeOfStruct = ctypes.sizeof(self)
def __repr__(self):
"""Returns a string representation of the instance.
Args:
self (JLinkSpeedInfo): the ``JLinkSpeedInfo`` instance
Returns:
String representation of the instance.
"""
return self.__str__()
def __str__(self):
"""Returns this instance formatted as a string.
Args:
self (JLinkSpeedInfo): the ``JLinkSpeedInfo`` instance
Returns:
String formatted instance.
"""
return '%s(Freq=%sHz)' % (self.__class__.__name__, self.BaseFreq)
class JLinkSWOStartInfo(ctypes.Structure):
__doc__ = 'Represents configuration information for collecting Serial Wire Output\n (SWO) information.\n\n Attributes:\n SizeofStruct: size of the structure.\n Interface: the interface type used for SWO.\n Speed: the frequency used for SWO communication in Hz.\n\n Note:\n You should *never* change ``.SizeofStruct`` or ``.Interface``.\n '
_fields_ = [
(
'SizeofStruct', ctypes.c_uint32),
(
'Interface', ctypes.c_uint32),
(
'Speed', ctypes.c_uint32)]
def __init__(self):
super(JLinkSWOStartInfo, self).__init__()
self.SizeofStruct = ctypes.sizeof(self)
self.Interface = enums.JLinkSWOInterfaces.UART
def __repr__(self):
"""Returns a representation of this instance.
Args:
self (JLinkSWOStartInfo): the ``JLinkSWOStartInfo`` instance
Returns:
The string representation of this instance.
"""
return self.__str__()
def __str__(self):
"""Returns a string representation of this instance.
Args:
self (JLinkSWOStartInfo): the ``JLinkSWOStartInfo`` instance
Returns:
The string representation of this instance.
"""
return '%s(Speed=%sHz)' % (self.__class__.__name__, self.Speed)
class JLinkSWOSpeedInfo(ctypes.Structure):
__doc__ = "Structure representing information about target's supported SWO speeds.\n\n To calculate the supported SWO speeds, the base frequency is taken and\n divide by a number in the range of ``[ MinDiv, MaxDiv ]``.\n\n Attributes:\n SizeofStruct: size of the structure.\n Interface: interface type for the speed information.\n BaseFreq: base frequency (Hz) used to calculate supported SWO speeds.\n MinDiv: minimum divider allowed to divide the base frequency.\n MaxDiv: maximum divider allowed to divide the base frequency.\n MinPrescale: minimum prescaler allowed to adjust the base frequency.\n MaxPrescale: maximum prescaler allowed to adjust the base frequency.\n\n Note:\n You should *never* change ``.SizeofStruct`` or ``.Interface``.\n "
_fields_ = [
(
'SizeofStruct', ctypes.c_uint32),
(
'Interface', ctypes.c_uint32),
(
'BaseFreq', ctypes.c_uint32),
(
'MinDiv', ctypes.c_uint32),
(
'MaxDiv', ctypes.c_uint32),
(
'MinPrescale', ctypes.c_uint32),
(
'MaxPrescale', ctypes.c_uint32)]
def __init__(self):
super(JLinkSWOSpeedInfo, self).__init__()
self.SizeofStruct = ctypes.sizeof(self)
self.Interface = enums.JLinkSWOInterfaces.UART
def __repr__(self):
"""Returns a representation of the instance.
Args:
self (JLinkSWOSpeedInfo): the ``JLinkSWOSpeedInfo`` instance
Returns:
``None``
"""
return self.__str__()
def __str__(self):
"""Returns a string representaton of the instance.
Args:
self (JLinkSWOSpeedInfo): the ``JLinkSWOSpeedInfo`` instance
Returns:
``None``
"""
return '%s(Interface=UART, Freq=%sHz)' % (self.__class__.__name__, self.BaseFreq)
class JLinkMOEInfo(ctypes.Structure):
__doc__ = 'Structure representing the Method of Debug Entry (MOE).\n\n The method of debug entry is a reason for which a CPU has stopped. At any\n given time, there may be multiple methods of debug entry.\n\n Attributes:\n HaltReason: reason why the CPU stopped.\n Index: if cause of CPU stop was a code/data breakpoint, this identifies\n the index of the code/data breakpoint unit which causes the CPU to\n stop, otherwise it is ``-1``.\n '
_fields_ = [
(
'HaltReason', ctypes.c_uint32),
(
'Index', ctypes.c_int)]
def __repr__(self):
"""Returns a string representation of the instance.
Args:
self (JLinkMOEInfo): the ``JLinkMOEInfo`` instance
Returns:
A string representation of the instance.
"""
return '%s(%s)' % (self.__class__.__name__, self.__str__())
def __str__(self):
"""Returns a string representation of the instance.
Args:
self (JLinkMOEInfo): the ``JLinkMOEInfo`` instance
Returns:
A string representation of the instance.
"""
d = enums.JLinkHaltReasons.__dict__
s = next((k for k, v in d.items() if v == self.HaltReason))
if self.dbgrq():
return s
return s.replace('_', ' ').title()
def dbgrq(self):
"""Returns whether this a DBGRQ.
Args:
self (JLinkMOEInfo): the ``JLinkMOEInfo`` instance
Returns:
``True`` if this is a DBGRQ, otherwise ``False``.
"""
return self.HaltReason == enums.JLinkHaltReasons.DBGRQ
def code_breakpoint(self):
"""Returns whether this a code breakpoint.
Args:
self (JLinkMOEInfo): the ``JLinkMOEInfo`` instance
Returns:
``True`` if this is a code breakpoint, otherwise ``False``.
"""
return self.HaltReason == enums.JLinkHaltReasons.CODE_BREAKPOINT
def data_breakpoint(self):
"""Returns whether this a data breakpoint.
Args:
self (JLinkMOEInfo): the ``JLinkMOEInfo`` instance
Returns:
``True`` if this is a data breakpoint, otherwise ``False``.
"""
return self.HaltReason == enums.JLinkHaltReasons.DATA_BREAKPOINT
def vector_catch(self):
"""Returns whether this a vector catch.
Args:
self (JLinkMOEInfo): the ``JLinkMOEInfo`` instance
Returns:
``True`` if this is a vector catch, otherwise ``False``.
"""
return self.HaltReason == enums.JLinkHaltReasons.VECTOR_CATCH
class JLinkBreakpointInfo(ctypes.Structure):
__doc__ = 'Class representing information about a breakpoint.\n\n Attributes:\n SizeOfStruct: the size of the structure (this should not be modified).\n Handle: breakpoint handle.\n Addr: address of where the breakpoint has been set.\n Type: type flags which were specified when the breakpoint was created.\n ImpFlags: describes the current state of the breakpoint.\n UseCnt: describes how often the breakpoint is set at the same address.\n '
_fields_ = [
(
'SizeOfStruct', ctypes.c_uint32),
(
'Handle', ctypes.c_uint32),
(
'Addr', ctypes.c_uint32),
(
'Type', ctypes.c_uint32),
(
'ImpFlags', ctypes.c_uint32),
(
'UseCnt', ctypes.c_uint32)]
def __init__(self):
super(JLinkBreakpointInfo, self).__init__()
self.SizeOfStruct = ctypes.sizeof(self)
def __repr__(self):
"""Returns a formatted string describing the breakpoint.
Args:
self (JLinkBreakpointInfo): the ``JLinkBreakpointInfo`` instance
Returns:
Stirng representation of the breakpoint.
"""
return self.__str__()
def __str__(self):
"""Returns a formatted string describing the breakpoint.
Args:
self (JLinkBreakpointInfo): the ``JLinkBreakpointInfo`` instance
Returns:
Stirng representation of the breakpoint.
"""
name = self.__class__.__name__
return '%s(Handle %d, Address %d)' % (name, self.Handle, self.Addr)
def software_breakpoint(self):
"""Returns whether this is a software breakpoint.
Args:
self (JLinkBreakpointInfo): the ``JLinkBreakpointInfo`` instance
Returns:
``True`` if the breakpoint is a software breakpoint, otherwise
``False``.
"""
software_types = [
enums.JLinkBreakpoint.SW_RAM,
enums.JLinkBreakpoint.SW_FLASH,
enums.JLinkBreakpoint.SW]
return any((self.Type & stype for stype in software_types))
def hardware_breakpoint(self):
"""Returns whether this is a hardware breakpoint.
Args:
self (JLinkBreakpointInfo): the ``JLinkBreakpointInfo`` instance
Returns:
``True`` if the breakpoint is a hardware breakpoint, otherwise
``False``.
"""
return self.Type & enums.JLinkBreakpoint.HW
def pending(self):
"""Returns if this breakpoint is pending.
Args:
self (JLinkBreakpointInfo): the ``JLinkBreakpointInfo`` instance
Returns:
``True`` if the breakpoint is still pending, otherwise ``False``.
"""
return self.ImpFlags & enums.JLinkBreakpointImplementation.PENDING
class JLinkDataEvent(ctypes.Structure):
__doc__ = 'Class representing a data event.\n\n A data may halt the CPU, trigger SWO output, or trigger trace output.\n\n Attributes:\n SizeOfStruct: the size of the structure (this should not be modified).\n Type: the type of the data event (this should not be modified).\n Addr: the address on which the watchpoint was set\n AddrMask: the address mask used for comparision.\n Data: the data on which the watchpoint has been set.\n DataMask: the data mask used for comparision.\n Access: the control data on which the event has been set.\n AccessMask: the control mask used for comparison.\n '
_fields_ = [
(
'SizeOfStruct', ctypes.c_int),
(
'Type', ctypes.c_int),
(
'Addr', ctypes.c_uint32),
(
'AddrMask', ctypes.c_uint32),
(
'Data', ctypes.c_uint32),
(
'DataMask', ctypes.c_uint32),
(
'Access', ctypes.c_uint8),
(
'AccessMask', ctypes.c_uint8)]
def __init__(self):
super(JLinkDataEvent, self).__init__()
self.SizeOfStruct = ctypes.sizeof(self)
self.Type = enums.JLinkEventTypes.BREAKPOINT
def __repr__(self):
"""Returns a string representation of the data event.
Args:
self (JLinkDataEvent): the ``JLinkDataEvent`` instance
Returns:
A string representation of the data event.
"""
return self.__str__()
def __str__(self):
"""Returns a string representation of the data event.
Args:
self (JLinkDataEvent): the ``JLinkDataEvent`` instance
Returns:
A string representation of the data event.
"""
name = self.__class__.__name__
return '%s(Type %d, Address %d)' % (name, self.Type, self.Addr)
class JLinkWatchpointInfo(ctypes.Structure):
__doc__ = 'Class representing information about a watchpoint.\n\n Attributes:\n SizeOfStruct: the size of the structure (this should not be modified).\n Handle: the watchpoint handle.\n Addr: the address the watchpoint was set at.\n AddrMask: the address mask used for comparison.\n Data: the data on which the watchpoint was set.\n DataMask: the data mask used for comparision.\n Ctrl: the control data on which the breakpoint was set.\n CtrlMask: the control mask used for comparison.\n WPUnit: the index of the watchpoint unit.\n '
_fields_ = [
(
'SizeOfStruct', ctypes.c_uint32),
(
'Handle', ctypes.c_uint32),
(
'Addr', ctypes.c_uint32),
(
'AddrMask', ctypes.c_uint32),
(
'Data', ctypes.c_uint32),
(
'DataMask', ctypes.c_uint32),
(
'Ctrl', ctypes.c_uint32),
(
'CtrlMask', ctypes.c_uint32),
(
'WPUnit', ctypes.c_uint8)]
def __init__(self):
super(JLinkWatchpointInfo, self).__init__()
self.SizeOfStruct = ctypes.sizeof(self)
def __repr__(self):
"""Returns a formatted string describing the watchpoint.
Args:
self (JLinkWatchpointInfo): the ``JLinkWatchpointInfo`` instance
Returns:
String representation of the watchpoint.
"""
return self.__str__()
def __str__(self):
"""Returns a formatted string describing the watchpoint.
Args:
self (JLinkWatchpointInfo): the ``JLinkWatchpointInfo`` instance
Returns:
String representation of the watchpoint.
"""
name = self.__class__.__name__
return '%s(Handle %d, Address %d)' % (name, self.Handle, self.Addr)
class JLinkStraceEventInfo(ctypes.Structure):
__doc__ = 'Class representing the STRACE event information.\n\n Attributes:\n SizeOfStruct: size of the structure.\n Type: type of event.\n Op: the STRACE operation to perform.\n AccessSize: access width for trace events.\n Reserved0: reserved.\n Addr: specifies the load/store address for data.\n Data: the data to be compared for the operation for data access events.\n DataMask: bitmask for bits of data to omit in comparision for data access\n events.\n AddrRangeSize: address range for range events.\n '
_fields_ = [
(
'SizeOfStruct', ctypes.c_uint32),
(
'Type', ctypes.c_uint8),
(
'Op', ctypes.c_uint8),
(
'AccessSize', ctypes.c_uint8),
(
'Reserved0', ctypes.c_uint8),
(
'Addr', ctypes.c_uint64),
(
'Data', ctypes.c_uint64),
(
'DataMask', ctypes.c_uint64),
(
'AddrRangeSize', ctypes.c_uint32)]
def __init__(self):
super(JLinkStraceEventInfo, self).__init__()
self.SizeOfStruct = ctypes.sizeof(self)
def __repr__(self):
"""Returns a formatted string describing the event info.
Args:
self (JLinkStraceEventInfo): the ``JLinkStraceEventInfo`` instance
Returns:
String representation of the event info.
"""
return self.__str__()
def __str__(self):
"""Returns a formatted string describing the event info.
Args:
self (JLinkStraceEventInfo): the ``JLinkStraceEventInfo`` instance
Returns:
String representation of the event information.
"""
name = self.__class__.__name__
return '%s(Type=%d, Op=%d)' % (name, self.Type, self.Op)
class JLinkTraceData(ctypes.Structure):
__doc__ = 'Structure representing trace data returned by the trace buffer.\n\n Attributes:\n PipeStat: type of trace data.\n Sync: sync point in buffer.\n Packet: trace data packet.\n '
_fields_ = [
(
'PipeStat', ctypes.c_uint8),
(
'Sync', ctypes.c_uint8),
(
'Packet', ctypes.c_uint16)]
def __repr__(self):
"""Returns a string representation of the trace data instance.
Args:
self (JLinkTraceData): the ``JLinkTraceData`` instance.
Returns:
A string representation of the instance.
"""
return self.__str__()
def __str__(self):
"""Returns a string representation of the trace data instance.
Args:
self (JLinkTraceData): the ``JLinkTraceData`` instance.
Returns:
A string representation of the instance.
"""
return '%s(%d)' % (self.__class__.__name__, self.Packet)
def instruction(self):
"""Returns whether the data corresponds to an executed instruction.
Args:
self (JLinkTraceData): the ``JLinkTraceData`` instance.
Returns:
``True`` if this is trace data for an executed instruction.
"""
return self.PipeStat == 0
def data_instruction(self):
"""Returns whether the data corresponds to an data instruction.
Args:
self (JLinkTraceData): the ``JLinkTraceData`` instance.
Returns:
``True`` if this is trace data for an data instruction.
"""
return self.PipeStat == 1
def non_instruction(self):
"""Returns whether the data corresponds to an un-executed instruction.
Args:
self (JLinkTraceData): the ``JLinkTraceData`` instance.
Returns:
``True`` if this is trace data for an un-executed instruction.
"""
return self.PipeStat == 2
def wait(self):
"""Returns whether the data corresponds to a wait.
Args:
self (JLinkTraceData): the ``JLinkTraceData`` instance.
Returns:
``True`` if this is trace data for a wait.
"""
return self.PipeStat == 3
def branch(self):
"""Returns whether the data corresponds to a branch execution.
Args:
self (JLinkTraceData): the ``JLinkTraceData`` instance.
Returns:
``True`` if this is trace data for a branch execution.
"""
return self.PipeStat == 4
def data_branch(self):
"""Returns whether the data corresponds to a branch with data.
Args:
self (JLinkTraceData): the ``JLinkTraceData`` instance.
Returns:
``True`` if this is trace data for a branch with data.
"""
return self.PipeStat == 5
def trigger(self):
"""Returns whether the data corresponds to a trigger event.
Args:
self (JLinkTraceData): the ``JLinkTraceData`` instance.
Returns:
``True`` if this is trace data for a trigger event.
"""
return self.PipeStat == 6
def trace_disabled(self):
"""Returns whether the data corresponds to trace being disabled.
Args:
self (JLinkTraceData): the ``JLinkTraceData`` instance.
Returns:
``True`` if this is trace data for the trace disabled event.
"""
return self.PipeStat == 7
class JLinkTraceRegion(ctypes.Structure):
__doc__ = 'Structure describing a trace region.\n\n Attributes:\n SizeOfStruct: size of the structure.\n RegionIndex: index of the region.\n NumSamples: number of samples in the region.\n Off: offset in the trace buffer.\n RegionCnt: number of trace regions.\n Dummy: unused.\n Timestamp: timestamp of last event written to buffer.\n '
_fields_ = [
(
'SizeOfStruct', ctypes.c_uint32),
(
'RegionIndex', ctypes.c_uint32),
(
'NumSamples', ctypes.c_uint32),
(
'Off', ctypes.c_uint32),
(
'RegionCnt', ctypes.c_uint32),
(
'Dummy', ctypes.c_uint32),
(
'Timestamp', ctypes.c_uint64)]
def __init__(self):
super(JLinkTraceRegion, self).__init__()
self.SizeOfStruct = ctypes.sizeof(self)
def __repr__(self):
"""Returns a string representation of the instance.
Args:
self (JLinkTraceRegion): the ``JLinkTraceRegion`` instance.
Returns:
String representation of the trace region.
"""
return self.__str__()
def __str__(self):
"""Returns a string representation of the instance.
Args:
self (JLinkTraceRegion): the ``JLinkTraceRegion`` instance.
Returns:
String representation of the trace region.
"""
return '%s(Index=%d)' % (self.__class__.__name__, self.RegionIndex)
# okay decompiling ./pylink/structs.pyc

45
pylink/threads.py Normal file
View File

@ -0,0 +1,45 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: pylink/threads.py
import threading
class ThreadReturn(threading.Thread):
__doc__ = 'Implementation of a thread with a return value.\n\n See also:\n `StackOverflow <http://stackoverflow.com/questions/6893968/>`__.\n '
def __init__(self, daemon=False, *args, **kwargs):
"""Initializes the thread.
Args:
self (ThreadReturn): the ``ThreadReturn`` instance
daemon (bool): if the thread should be spawned as a daemon
args: optional list of arguments
kwargs: optional key-word arguments
Returns:
``None``
"""
(super(ThreadReturn, self).__init__)(*args, **kwargs)
self.daemon = daemon
self._return = None
def run(self):
"""Runs the thread.
Args:
self (ThreadReturn): the ``ThreadReturn`` instance
Returns:
``None``
"""
target = getattr(self, '_Thread__target', getattr(self, '_target', None))
args = getattr(self, '_Thread__args', getattr(self, '_args', None))
kwargs = getattr(self, '_Thread__kwargs', getattr(self, '_kwargs', None))
if target is not None:
self._return = target(*args, **kwargs)
def join(self, *args, **kwargs):
(super(ThreadReturn, self).join)(*args, **kwargs)
return self._return
# okay decompiling ./pylink/threads.pyc

157
pylink/util.py Normal file
View File

@ -0,0 +1,157 @@
# decompyle3 version 3.9.0
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.7.16 (default, Mar 30 2023, 01:25:49)
# [GCC 12.2.1 20220924]
# Embedded file name: pylink/util.py
from . import enums
import platform, sys
def is_integer(val):
"""Returns whether the given value is an integer.
Args:
val (object): value to check
Returns:
``True`` if the given value is an integer, otherwise ``False``.
"""
try:
val += 1
except TypeError:
return False
else:
return True
def is_natural(val):
"""Returns whether the given value is a natrual number.
Args:
val (object): value to check
Returns:
``True`` if the given value is a natural number, otherwise ``False``.
"""
return is_integer(val) and val >= 0
def is_os_64bit():
"""Returns whether the current running platform is 64bit.
Returns:
``True`` if the platform is 64bit, otherwise ``False``.
"""
return platform.machine().endswith('64')
def noop(*args, **kwargs):
"""No-op. Does nothing.
Args:
args: list of arguments
kwargs: keyword arguments dictionary
Returns:
``None``
"""
pass
def unsecure_hook_dialog(title, msg, flags):
"""No-op that ignores the dialog.
Args:
title (str): title of the unsecure dialog
msg (str): text of the unsecure dialog
flags (int): flags specifying which values can be returned
Returns:
``enums.JLinkFlags.DLG_BUTTON_NO``
"""
return enums.JLinkFlags.DLG_BUTTON_NO
def progress_bar(iteration, total, prefix=None, suffix=None, decs=1, length=100):
"""Creates a console progress bar.
This should be called in a loop to create a progress bar.
See `StackOverflow <http://stackoverflow.com/questions/3173320/>`__.
Args:
iteration (int): current iteration
total (int): total iterations
prefix (str): prefix string
suffix (str): suffix string
decs (int): positive number of decimals in percent complete
length (int): character length of the bar
Returns:
``None``
Note:
This function assumes that nothing else is printed to the console in the
interim.
"""
if prefix is None:
prefix = ''
if suffix is None:
suffix = ''
format_str = '{0:.' + str(decs) + 'f}'
percents = format_str.format(100 * (iteration / float(total)))
filled_length = int(round(length * iteration / float(total)))
bar = '' * filled_length + '-' * (length - filled_length)
prefix, suffix = prefix.strip(), suffix.strip()
sys.stdout.write('\r%s |%s| %s%s %s' % (prefix, bar, percents, '%', suffix))
sys.stdout.flush()
if iteration == total:
sys.stdout.write('\n')
sys.stdout.flush()
def flash_progress_callback(action, progress_string, percentage):
"""Callback that can be used with ``JLink.flash()``.
This callback generates a progress bar in the console to show the progress
of each of the steps of the flash.
Args:
action (str): the current action being invoked
progress_string (str): the current step in the progress
percentage (int): the percent to which the current step has been done
Returns:
``None``
Note:
This function ignores the compare action.
"""
if action.lower() != 'compare':
return progress_bar((min(100, percentage)), 100, prefix=action)
def calculate_parity(n):
"""Calculates and returns the parity of a number.
The parity of a number is ``1`` if the number has an odd number of ones
in its binary representation, otherwise ``0``.
Args:
n (int): the number whose parity to calculate
Returns:
``1`` if the number has an odd number of ones, otherwise ``0``.
Raises:
ValueError: if ``n`` is less than ``0``.
"""
if not is_natural(n):
raise ValueError('Expected n to be a positive integer.')
y = 0
n = abs(n)
while n:
y += n & 1
n = n >> 1
return y & 1
# okay decompiling ./pylink/util.pyc

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
psutil==5.9.5