blflashcommand/libs/base/bflb_base_eflash_loader.py

2208 lines
100 KiB
Python
Raw Normal View History

2023-04-20 21:04:18 +00:00
# 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/base/bflb_base_eflash_loader.py
__doc__ = '\nCreated on 20220908\n\n@author: Dillon\n'
import os, lzma, ecdsa, config as gol
from libs.bflb_utils import *
from libs.bflb_configobj import BFConfigParser
from libs import bflb_ecdh
from libs import bflb_interface_jlink
from libs import bflb_interface_cklink
from libs import bflb_interface_openocd
from libs.base import bflb_img_loader
from libs.base import bflb_flash_select
from libs.base import bflb_efuse_boothd_create
from libs.base import bflb_img_create as img_create
from pickle import NONE
FLASH_LOAD_SHAKE_HAND = 'Flash load shake hand'
FLASH_ERASE_SHAKE_HAND = 'Flash erase shake hand'
class BaseEflashLoader(object):
__doc__ = '\n Load the flash base execution file.\n '
def __init__(self, chip_type, args, config, callback, macaddr_callback, create_simple_callback, create_img_callback, task_num):
self.chip_type = chip_type
self.chip_name = ''
self.args = args
self.config = config
self.callback = callback
self.macaddr_callback = macaddr_callback
self.create_simple_callback = create_simple_callback
self.create_img_callback = create_img_callback
self.temp_task_num = task_num
self.task_num = None
self.device = ''
self.speed = 0
self.boot_speed = 0
self.bflb_serial_object = None
self.start = ''
self.end = ''
self.file = ''
self.address = ''
self.macaddr = ''
self.bootinfo = None
self.flash_set = 0
self.read_flash_id = 0
self.id_valid_flag = '80'
self.read_flash2_id = 0
self.id2_valid_flag = '80'
self.do_reset = True
self.reset_hold_time = 100
self.shake_hand_delay = 100
self.reset_revert = True
self.cutoff_time = 0
self.shake_hand_retry = 2
self.flash_burn_retry = 1
self.ram_load = False
self.load_function = 1
self.macaddr_check = False
self.NUM_ERR = 5
self.cfg = ''
self.eflash_loader_file = ''
self.cpu_reset = False
self.retry_delay_after_cpu_reset = 0
self.input_macaddr = ''
self.isp_mode_sign = False
self.create_cfg = None
self._skip_addr = []
self._skip_len = []
self.address_list = []
self.flash_file_list = []
self.encrypt_key = None
self.encrypt_iv = None
self.public_key = None
self.private_key = None
self.load_file = ''
self._mac_addr = bytearray(0)
self._need_shake_hand = True
self._isp_shakehand_timeout = 0
self._macaddr_check = bytearray(0)
self._default_time_out = 2.0
self._flash2_en = False
self._flash1_size = 0
self._flash2_size = 0
self._flash2_select = False
self._efuse_bootheader_file = ''
self._img_create_file = ''
self._com_cmds = {'change_rate':{'cmd_id':'20',
'data_len':'0008',
'callback':None},
'reset':{'cmd_id':'21',
'data_len':'0000',
'callback':None},
'clk_set':{'cmd_id':'22',
'data_len':'0000',
'callback':None},
'opt_finish':{'cmd_id':'23',
'data_len':'0000',
'callback':None},
'flash_erase':{'cmd_id':'30',
'data_len':'0000',
'callback':None},
'flash_write':{'cmd_id':'31',
'data_len':'0100',
'callback':None},
'flash_read':{'cmd_id':'32',
'data_len':'0100',
'callback':None},
'flash_boot':{'cmd_id':'33',
'data_len':'0000',
'callback':None},
'flash_xip_read':{'cmd_id':'34',
'data_len':'0100',
'callback':None},
'flash_switch_bank':{'cmd_id':'35',
'data_len':'0100',
'callback':None},
'flash_read_jid':{'cmd_id':'36',
'data_len':'0000',
'callback':None},
'flash_read_status_reg':{'cmd_id':'37',
'data_len':'0000',
'callback':None},
'flash_write_status_reg':{'cmd_id':'38',
'data_len':'0000',
'callback':None},
'flash_write_check':{'cmd_id':'3a',
'data_len':'0000',
'callback':None},
'flash_set_para':{'cmd_id':'3b',
'data_len':'0000',
'callback':None},
'flash_chiperase':{'cmd_id':'3c',
'data_len':'0000',
'callback':None},
'flash_readSha':{'cmd_id':'3d',
'data_len':'0100',
'callback':None},
'flash_xip_readSha':{'cmd_id':'3e',
'data_len':'0100',
'callback':None},
'flash_decompress_write':{'cmd_id':'3f',
'data_len':'0100',
'callback':None},
'efuse_write':{'cmd_id':'40',
'data_len':'0080',
'callback':None},
'efuse_read':{'cmd_id':'41',
'data_len':'0000',
'callback':None},
'efuse_read_mac':{'cmd_id':'42',
'data_len':'0000',
'callback':None},
'efuse_write_mac':{'cmd_id':'43',
'data_len':'0006',
'callback':None},
'flash_xip_read_start':{'cmd_id':'60',
'data_len':'0080',
'callback':None},
'flash_xip_read_finish':{'cmd_id':'61',
'data_len':'0000',
'callback':None},
'log_read':{'cmd_id':'71',
'data_len':'0000',
'callback':None},
'efuse_security_write':{'cmd_id':'80',
'data_len':'0080',
'callback':None},
'efuse_security_read':{'cmd_id':'81',
'data_len':'0000',
'callback':None},
'ecdh_get_pk':{'cmd_id':'90',
'data_len':'0000',
'callback':None},
'ecdh_chanllenge':{'cmd_id':'91',
'data_len':'0000',
'callback':None}}
self._resp_cmds = [
'flash_read','flash_xip_read','efuse_read','efuse_read_mac','flash_readSha','flash_xip_readSha','flash_read_jid',
'flash_read_status_reg','log_read','ecdh_get_pk','ecdh_chanllenge','efuse_security_read']
def first_run_step_load_parameter(self):
"""
First step: init.
"""
if self.temp_task_num == None:
local_log_enable(True)
if self.temp_task_num != None:
if self.temp_task_num > 256:
self.task_num = self.temp_task_num - 256
else:
self.task_num = self.temp_task_num
else:
self.task_num = None
printf('========= eflash loader cmd arguments =========')
self.interface = self.config['param']['interface_type'].lower()
self.chip_name = self.config['param']['chip_name']
self.config_file = os.path.join(app_path, 'chips', self.chip_name.lower(), 'eflash_loader', 'eflash_loader_cfg.ini')
if not os.path.exists(self.config_file):
conf_file = self.config_file.replace('.ini', '.conf')
if os.path.exists(conf_file):
shutil.copy(conf_file, self.config_file)
if os.path.exists(self.config_file):
self.cfg = BFConfigParser()
self.cfg.read(self.config_file)
else:
printf('Config file "' + self.config_file + '" not found')
2023-04-20 21:04:18 +00:00
self.error_code_print('000B')
return (False, 0)
if self.interface == 'openocd':
self.device = self.cfg.get('LOAD_CFG', 'openocd_config')
self._bflb_sn_device = self.config['param']['comport_uart']
else:
if self.interface == 'cklink':
self.device = self.cfg.get('LOAD_CFG', 'cklink_vidpid')
self._bflb_sn_device = self.cfg.get('LOAD_CFG', 'cklink_type') + ' ' + self.config['param']['comport_uart']
else:
self.device = self.config['param']['comport_uart']
if 'aes_key' in self.config['param']:
if self.config['check_box']['encrypt']:
self.encrypt_key = self.config['param']['aes_key']
if 'aes_iv' in self.config['param']:
if self.config['check_box']['sign']:
self.encrypt_iv = self.config['param']['aes_iv']
if 'input_path' in self.config:
if 'publickey' in self.config['input_path']['publickey']:
self.public_key = self.config['input_path']['publickey']
if 'input_path' in self.config:
if 'privatekey' in self.config['input_path']['privatekey']:
self.private_key = self.config['input_path']['privatekey']
xtal_type = self.config['param']['chip_xtal']
if self.interface == 'uart':
temp_speed = int(self.config['param']['speed_uart'])
else:
temp_speed = int(self.config['param']['speed_jlink'])
printf('serial port is ', self.device)
printf('chiptype: ', self.chip_type)
try:
if self.args.start:
self.start = self.args.start
if self.args.end:
self.end = self.args.end
if self.args.file:
self.file = self.args.file
if self.args.addr:
self.address = self.args.addr
if self.args.mac:
self.macaddr = self.args.mac
if self.args.createcfg:
self.create_cfg = self.args.createcfg
if self.args.loadfile:
self.load_file = self.args.loadfile
if self.args.usage:
printf('-e --start=00000000 --end=0000FFFF -c config.ini')
printf('-w --flash -c config.ini')
printf('-w --flash --file=1.bin,2.bin --addr=00000000,00001000 -c config.ini')
printf('-r --flash --start=00000000 --end=0000FFFF --file=flash.bin -c config.ini')
except Exception as e:
try:
printf(e)
self.error_code_print('0002')
return (False, 0)
finally:
e = None
del e
if self.cfg.has_option('LOAD_CFG', 'verify'):
if self.cfg.get('LOAD_CFG', 'verify') == '1':
self.verify = 1
else:
self.verify = 0
else:
self.verify = 0
try:
self.erase = int(self.config['param']['erase'])
except:
self.erase = 1
try:
boot2_isp_mode = int(self.config['param']['boot2_isp_mode'])
if int(boot2_isp_mode) == 1:
self.isp_mode_sign = True
except:
pass
if not 'skip_mode' in self.config['param'] or self.config['param']['skip_mode']:
skip_para = self.config['param']['skip_mode'].replace(' ', '')
if skip_para[-1] == ';':
skip_para = skip_para[:-1]
skip_para_list = skip_para.split(';')
for temp_value in skip_para_list:
temp_list = temp_value.split(',')
if temp_list[0][0:2] == '0x':
self._skip_addr.append(int(temp_list[0][2:], 16))
else:
self._skip_addr.append(int(temp_list[0], 10))
if temp_list[1][0:2] == '0x':
self._skip_len.append(int(temp_list[1][2:], 16))
else:
self._skip_len.append(int(temp_list[1], 10))
if len(self._skip_len) > 1 or len(self._skip_len) == 1 and self._skip_len[0] > 0:
if self.erase == 2:
printf('Error: skip mode can not set flash chiperase!')
self.error_code_print('0044')
return (False, 0)
if self.cfg.has_option('LOAD_CFG', 'local_log'):
if self.cfg.get('LOAD_CFG', 'local_log') == 'true':
printf('local log enable')
local_log_enable(True)
self.input_macaddr = self.macaddr
else:
local_log_enable(False)
self.input_macaddr = ''
if self.interface == 'cklink':
self._bflb_com_tx_size = 14344
else:
self._bflb_com_tx_size = int(self.cfg.get('LOAD_CFG', 'tx_size'))
if self.cfg.has_option('LOAD_CFG', 'erase_time_out'):
self._erase_time_out = int(self.cfg.get('LOAD_CFG', 'erase_time_out'))
if self.cfg.has_option('LOAD_CFG', 'shake_hand_retry'):
self.shake_hand_retry = int(self.cfg.get('LOAD_CFG', 'shake_hand_retry'))
if self.cfg.has_option('LOAD_CFG', 'flash_burn_retry'):
self.flash_burn_retry = int(self.cfg.get('LOAD_CFG', 'flash_burn_retry'))
if self.cfg.has_option('LOAD_CFG', 'checksum_err_retry'):
self._checksum_err_retry_limit = int(self.cfg.get('LOAD_CFG', 'checksum_err_retry'))
if self.cfg.has_option('LOAD_CFG', 'cpu_reset_after_load'):
self.cpu_reset = self.cfg.get('LOAD_CFG', 'cpu_reset_after_load') == 'true'
if self.cfg.has_option('LOAD_CFG', 'retry_delay_after_cpu_reset'):
self.retry_delay_after_cpu_reset = int(self.cfg.get('LOAD_CFG', 'retry_delay_after_cpu_reset'))
printf('retry delay: ', self.retry_delay_after_cpu_reset)
if self.cfg.has_option('LOAD_CFG', 'eflash_loader_file'):
if self.eflash_loader_file is None:
self.eflash_loader_file = self.cfg.get('LOAD_CFG', 'eflash_loader_file')
printf('cpu_reset=', self.cpu_reset)
if xtal_type != '':
self.eflash_loader_file = 'chips/' + self.chip_name.lower() + '/eflash_loader/eflash_loader_' + xtal_type.replace('.', 'p').lower() + '.bin'
if self.load_file and not self.eflash_loader_file:
self.eflash_loader_file = self.load_file
else:
if self.eflash_loader_file is not None:
self.eflash_loader_file = os.path.join(app_path, self.eflash_loader_file)
self.load_function = 1
if self.cfg.has_option('LOAD_CFG', 'isp_shakehand_timeout'):
self._isp_shakehand_timeout = int(self.cfg.get('LOAD_CFG', 'isp_shakehand_timeout'))
result, address, flash_file = self.get_flash_file_and_address()
if not result:
return (False, self.flash_burn_retry)
temp_file_list = []
for one in flash_file:
if os.path.join(chip_path, self.chip_name) in one:
temp_file_list.append(one.replace(app_path, '')[1:])
else:
temp_file_list.append(os.path.join('chips', self.chip_name, 'img_create', os.path.basename(one)))
if 'erase' in self.config['param']:
if self.config['param']['erase']:
update_cfg(self.cfg, 'LOAD_CFG', 'erase', str(self.erase))
if 'skip_mode' in self.config['param']:
if self.config['param']['skip_mode']:
update_cfg(self.cfg, 'LOAD_CFG', 'skip_mode', self.config['param']['skip_mode'])
if 'boot2_isp_mode' in self.config['param']:
if self.config['param']['boot2_isp_mode']:
update_cfg(self.cfg, 'LOAD_CFG', 'boot2_isp_mode', self.config['param']['boot2_isp_mode'])
update_cfg(self.cfg, 'FLASH_CFG', 'file', ' '.join(temp_file_list))
update_cfg(self.cfg, 'FLASH_CFG', 'address', ' '.join(address))
self.cfg.write(self.config_file, 'w+')
with open((self.config_file), 'r', encoding='utf-8') as cf_file:
cf_context = cf_file.read().replace('"', '')
with open((self.config_file), 'w', encoding='utf-8') as cf_file:
cf_file.write(cf_context)
self.bl_write_flash_img(address, flash_file)
self.address_list = address[:]
self.flash_file_list = flash_file[:]
if self.args.efuse:
try:
if self.config['input_path']['efuse']:
if self.config['check_box']['efuse']:
efusefile = self.config['input_path']['efuse']
except:
efusefile = ''
if efusefile:
efuse_file = efusefile
mask_file = efuse_file.replace('.bin', '_mask.bin')
relpath_efuse_file = os.path.relpath(os.path.join('chips', self.chip_name, 'img_create', os.path.basename(efuse_file)))
relpath_mask_file = os.path.relpath(os.path.join('chips', self.chip_name, 'img_create', os.path.basename(mask_file)))
if self.cfg.has_option('EFUSE_CFG', 'file'):
update_cfg(self.cfg, 'EFUSE_CFG', 'file', relpath_efuse_file)
update_cfg(self.cfg, 'EFUSE_CFG', 'maskfile', relpath_mask_file)
self.cfg.write(self.config_file, 'w+')
with open((self.config_file), 'r', encoding='utf-8') as cf_file:
cf_context = cf_file.read().replace('"', '')
with open((self.config_file), 'w', encoding='utf-8') as cf_file:
cf_file.write(cf_context)
else:
efuse_file = self.cfg.get('EFUSE_CFG', 'file')
mask_file = self.cfg.get('EFUSE_CFG', 'maskfile')
if self.temp_task_num != None:
efuse_file = 'task' + str(self.temp_task_num) + '/' + efuse_file
ret = img_create.compress_dir(self.chip_name, 'img_create', self.args.efuse, address, flash_file, efuse_file, mask_file)
if ret is not True:
return errorcode_msg()
else:
ret = img_create.compress_dir(self.chip_name, 'img_create', False, address, flash_file)
if ret is not True:
return errorcode_msg()
if self.interface == 'uart' or self.interface == 'sdio':
if temp_speed:
self.speed = temp_speed
self.boot_speed = int(self.cfg.get('LOAD_CFG', 'speed_uart_boot'))
self.set_boot_speed()
if self.cfg.has_option('LOAD_CFG', 'reset_hold_time'):
self.reset_hold_time = int(self.cfg.get('LOAD_CFG', 'reset_hold_time'))
if self.cfg.has_option('LOAD_CFG', 'shake_hand_delay'):
self.shake_hand_delay = int(self.cfg.get('LOAD_CFG', 'shake_hand_delay'))
if self.cfg.has_option('LOAD_CFG', 'do_reset'):
self.do_reset = self.cfg.get('LOAD_CFG', 'do_reset') == 'true'
if self.cfg.has_option('LOAD_CFG', 'reset_revert'):
self.reset_revert = self.cfg.get('LOAD_CFG', 'reset_revert') == 'true'
if self.cfg.has_option('LOAD_CFG', 'cutoff_time'):
self.cutoff_time = int(self.cfg.get('LOAD_CFG', 'cutoff_time'))
printf('========= Interface is %s =========' % self.interface)
self._bflb_com_img_loader = bflb_img_loader.BflbImgLoader(self.device, self.speed, self.boot_speed, self.interface, self.chip_type, self.chip_name, self.eflash_loader_file, '', self.callback, self.do_reset, self.reset_hold_time, self.shake_hand_delay, self.reset_revert, self.cutoff_time, self.shake_hand_retry, self.isp_mode_sign, self._isp_shakehand_timeout, self.encrypt_key, self.encrypt_iv, self.public_key, self.private_key)
self.bflb_serial_object = self._bflb_com_img_loader.bflb_serial_object
if not self.cfg.has_option('LOAD_CFG', 'isp_mode_speed') or self.isp_mode_sign is True:
isp_mode_speed = int(self.cfg.get('LOAD_CFG', 'isp_mode_speed'))
self._bflb_com_img_loader.set_isp_baudrate(isp_mode_speed)
else:
if self.interface == 'jlink':
printf('========= Interface is JLink =========')
self.bflb_serial_object = bflb_interface_jlink.BflbJLinkPort()
if temp_speed:
self.speed = temp_speed
printf('com speed: %dk' % self.speed)
else:
self.speed = int(self.cfg.get('LOAD_CFG', 'speed_jlink'))
self.boot_speed = self.speed
else:
if self.interface == 'openocd':
printf('========= Interface is Openocd =========')
self.bflb_serial_object = bflb_interface_openocd.BflbOpenocdPort()
if temp_speed:
self.speed = temp_speed
printf('com speed: %dk' % self.speed)
else:
self.speed = int(self.cfg.get('LOAD_CFG', 'speed_jlink'))
self.boot_speed = self.speed
else:
if self.interface == 'cklink':
printf('========= Interface is CKLink =========')
self.bflb_serial_object = bflb_interface_cklink.BflbCKLinkPort()
if temp_speed:
self.speed = temp_speed
printf('com speed: %dk' % self.speed)
else:
self.speed = int(self.cfg.get('LOAD_CFG', 'speed_jlink'))
self.boot_speed = self.speed
else:
printf(self.interface + ' is not supported ')
return (
False, self.flash_burn_retry)
if self.args.chipid:
ret, self.bootinfo, res = self.get_boot_info()
if ret is False:
self.error_code_print('0003')
return (
False, self.flash_burn_retry)
return (
True, self.flash_burn_retry)
if self.cfg.has_option('LOAD_CFG', 'load_function'):
self.load_function = int(self.cfg.get('LOAD_CFG', 'load_function'))
if self.isp_mode_sign is True:
if self._isp_shakehand_timeout == 0:
self._isp_shakehand_timeout = 5
self.set_load_function()
return (True, 'continue')
def second_run_step_shake_hand(self):
"""
Second step: shake hand and load eflash_loader.bin.
"""
try:
if self.load_function == 0:
printf('No need load eflash_loader.bin')
else:
if self.load_function == 1:
load_bin_pass = False
printf('Eflash load bin file: ', self.eflash_loader_file)
ret, self.bootinfo, res = self.load_eflash_loader_bin()
if res == 'shake hand fail':
self.error_code_print('0050')
if res.startswith('repeat_burn') is True:
return ('repeat_burn', self.flash_burn_retry)
if res.startswith('error_shakehand') is True:
if self.cpu_reset is True:
self.error_code_print('0003')
return (
False, self.flash_burn_retry)
load_bin_pass = True
time.sleep(4.5)
if ret is False:
if load_bin_pass == False:
self.error_code_print('0003')
return (
False, self.flash_burn_retry)
if self.ram_load:
return (True, self.flash_burn_retry)
else:
if self.load_function == 2:
load_bin_pass = False
printf('Bootrom load')
ret, self.bootinfo, res = self.get_boot_info()
if res == 'shake hand fail':
self.error_code_print('0050')
if res.startswith('repeat_burn') is True:
self.error_code_print('000A')
return (
'repeat_burn', self.flash_burn_retry)
if res.startswith('error_shakehand') is True:
if self.cpu_reset is True:
self.error_code_print('0003')
return (
False, self.flash_burn_retry)
load_bin_pass = True
time.sleep(4.5)
if ret is False:
if load_bin_pass == False:
self.error_code_print('0050')
return (
False, self.flash_burn_retry)
self._need_shake_hand = False
clock_para = bytearray(0)
if self.cfg.has_option('LOAD_CFG', 'clock_para'):
clock_para_str = self.cfg.get('LOAD_CFG', 'clock_para')
if clock_para_str != '':
clock_para_file = os.path.join(app_path, clock_para_str)
printf('clock para file: ', clock_para_file)
clock_para = self.clock_para_update(clock_para_file)
printf('change bdrate: ', self.speed)
ret = self.clock_pll_set(self._need_shake_hand, True, clock_para)
if ret is False:
printf('pll set fail!!')
return (
False, self.flash_burn_retry)
return (True, 'continue')
except Exception as e:
try:
printf(e)
self.error_code_print('0003')
return (
False, self.flash_burn_retry)
finally:
e = None
del e
def third_run_step_read_mac_address(self):
"""
Third step: read mac address.
"""
time.sleep(0.1)
if self.isp_mode_sign is True:
if self.cpu_reset is True:
self.set_clear_boot_status(self._need_shake_hand)
if self.cfg.has_option('LOAD_CFG', 'check_mac'):
self.macaddr_check = self.cfg.get('LOAD_CFG', 'check_mac') == 'true'
if self.macaddr_check:
if self.isp_mode_sign is False:
ret, self._mac_addr = self.efuse_read_mac_addr_process()
if ret is False:
printf('read mac addr fail!!')
return (
False, self.flash_burn_retry)
if self._mac_addr == self._macaddr_check:
self.error_code_print('000A')
return (
False, self.flash_burn_retry)
self._need_shake_hand = False
self._macaddr_check_status = True
if self.macaddr_callback is not None:
ret, self._efuse_data, self._efuse_mask_data, macaddr = self.macaddr_callback(binascii.hexlify(self._mac_addr).decode('utf-8'))
if ret is False:
return (False, self.flash_burn_retry)
if self._efuse_data != bytearray(0) and self._efuse_mask_data != bytearray(0) or macaddr != '':
self.args.efuse = True
if self.callback:
self.callback(0, 100, 'running', 'blue')
return (True, 'continue')
def fourth_run_step_interact_chip(self):
"""
Fourth step: Interact with chip, read chip ID and update flash parameter.
"""
if self.args.flash:
flash_pin = 0
flash_clock_cfg = 0
flash_io_mode = 0
flash_clk_delay = 0
if self.cfg.has_option('FLASH_CFG', 'decompress_write'):
self.decompress_write = self.cfg.get('FLASH_CFG', 'decompress_write') == 'true'
self.set_decompress_write()
printf('flash set para')
if self.cfg.get('FLASH_CFG', 'flash_pin'):
flash_pin_cfg = self.cfg.get('FLASH_CFG', 'flash_pin')
if flash_pin_cfg.startswith('0x'):
flash_pin = int(flash_pin_cfg, 16)
else:
flash_pin = int(flash_pin_cfg, 10)
if flash_pin == 128:
flash_pin = self.get_flash_pin_from_bootinfo(self.chip_type, self.bootinfo)
printf('get flash pin cfg from bootinfo: 0x%02X' % flash_pin)
else:
flash_pin = self.get_flash_pin()
if self.cfg.has_option('FLASH_CFG', 'flash_clock_cfg'):
clock_div_cfg = self.cfg.get('FLASH_CFG', 'flash_clock_cfg')
if clock_div_cfg.startswith('0x'):
flash_clock_cfg = int(clock_div_cfg, 16)
else:
flash_clock_cfg = int(clock_div_cfg, 10)
if self.cfg.has_option('FLASH_CFG', 'flash_io_mode'):
io_mode_cfg = self.cfg.get('FLASH_CFG', 'flash_io_mode')
if io_mode_cfg.startswith('0x'):
flash_io_mode = int(io_mode_cfg, 16)
else:
flash_io_mode = int(io_mode_cfg, 10)
if self.cfg.has_option('FLASH_CFG', 'flash_clock_delay'):
clk_delay_cfg = self.cfg.get('FLASH_CFG', 'flash_clock_delay')
if clk_delay_cfg.startswith('0x'):
flash_clk_delay = int(clk_delay_cfg, 16)
else:
flash_clk_delay = int(clk_delay_cfg, 10)
self.flash_set = (flash_pin << 0) + (flash_clock_cfg << 8) + (flash_io_mode << 16) + (flash_clk_delay << 24)
if self.flash_set != 66047 or self.load_function == 2:
printf('set flash cfg: %X' % self.flash_set)
ret = self.flash_set_para_main_process(self.flash_set, bytearray(0))
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.id_valid_flag = data[6:]
read_id = data[0:6]
self.read_flash_id = read_id
if self.cfg.has_option('FLASH_CFG', 'flash_para'):
flash_para_file = os.path.join(app_path, self.cfg.get('FLASH_CFG', 'flash_para'))
self.flash_para_update(flash_para_file, read_id)
if self.id_valid_flag != '80':
if not self.show_identify_fail():
return (False, self.flash_burn_retry)
if self.is_conf_exist(self.read_flash_id) is False:
self.error_code_print('003D')
return (
False, self.flash_burn_retry)
else:
self.error_code_print('0030')
return (
False, self.flash_burn_retry)
result, content = self.run_flash2()
return (
result, content)
return (True, 'continue')
def fifth_run_step_write_flash_and_check(self):
"""
Fifth step: write flash and check.
"""
if self.args.none:
return (True, self.flash_burn_retry)
if self.args.write:
if not self.args.flash:
if not self.args.efuse:
printf('No target select')
return (
False, self.flash_burn_retry)
printf('Program operation')
if self.args.flash:
flash_para_file = ''
flash2_para_file = ''
if self.cfg.has_option('FLASH_CFG', 'flash_para'):
flash_para_file = os.path.join(app_path, self.cfg.get('FLASH_CFG', 'flash_para'))
if self.cfg.has_option('FLASH2_CFG', 'flash2_para'):
flash2_para_file = os.path.join(app_path, self.cfg.get('FLASH2_CFG', 'flash2_para'))
address = self.address_list
flash_file = self.flash_file_list
if self.erase == 2:
ret = self.flash_chiperase_main_process()
if ret is False:
return (False, self.flash_burn_retry)
self._need_shake_hand = False
self.erase = 0
if len(flash_file) > 0:
size_before = 0
size_all = 0
i = 0
for item in flash_file:
if self.temp_task_num != None:
size_all += os.path.getsize(os.path.join(app_path, convert_path('task' + str(self.temp_task_num) + '/' + item)))
else:
size_all += os.path.getsize(os.path.join(app_path, convert_path(item)))
try:
ret = False
while i < len(flash_file):
if self.temp_task_num != None:
flash_file[i] = 'task' + str(self.temp_task_num) + '/' + flash_file[i]
size_current = os.path.getsize(os.path.join(app_path, convert_path(flash_file[i])))
else:
size_current = os.path.getsize(os.path.join(app_path, convert_path(flash_file[i])))
if self.callback:
self.callback(size_before, size_all, 'program1')
else:
if self.callback:
self.callback(size_current, size_all, 'program2')
printf('Dealing Index ', i)
if self.isp_mode_sign is True:
printf('========= programming ', convert_path(flash_file[i]))
else:
printf('========= programming ', convert_path(flash_file[i]), ' to 0x', address[i])
flash1_bin = ''
flash1_bin_len = 0
flash2_bin = ''
flash2_bin_len = 0
flash1_bin, flash1_bin_len, flash2_bin, flash2_bin_len = self.get_flash1_and_flash2(flash_file, address, size_current, i)
if flash1_bin != '' and flash2_bin != '':
ret = self.flash_cfg_option(self.read_flash_id, flash_para_file, self.flash_set, self.id_valid_flag, flash1_bin, self.config_file, self.cfg, self.create_img_callback, self.create_simple_callback)
if ret is False:
return (False, self.flash_burn_retry)
printf('========= programming ', convert_path(flash1_bin), ' to 0x', address[i])
ret = self.flash_load_specified(convert_path(flash1_bin), int(address[i], 16), self.callback)
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 = self.flash_cfg_option(self.read_flash2_id, flash2_para_file, self.flash2_set, self.id2_valid_flag, flash_file[i], self.config_file, self.cfg, self.create_img_callback, self.create_simple_callback)
if ret is False:
return (False, self.flash_burn_retry)
printf('========= programming ', convert_path(flash2_bin), ' to 0x%08X' % (int(address[i], 16) + flash1_bin_len))
ret = self.flash_load_specified(convert_path(flash2_bin), int(address[i], 16) + flash1_bin_len, self.callback)
if ret is False:
return (False, self.flash_burn_retry)
else:
if not (self._flash2_en is False or self._flash2_select) is False or int(address[i], 16) < self._flash1_size:
ret = self.flash_cfg_option(self.read_flash_id, flash_para_file, self.flash_set, self.id_valid_flag, flash_file[i], self.config_file, self.cfg, self.create_img_callback, self.create_simple_callback)
if ret is False:
return (False, self.flash_burn_retry)
else:
if self._flash2_select is False:
if int(address[i], 16) >= self._flash1_size:
ret = self.flash_switch_bank_process(1)
self._need_shake_hand = False
if ret is False:
return (False, self.flash_burn_retry)
ret = self.flash_cfg_option(self.read_flash2_id, flash2_para_file, self.flash2_set, self.id2_valid_flag, flash_file[i], self.config_file, self.cfg, self.create_img_callback, self.create_simple_callback)
if ret is False:
return (False, self.flash_burn_retry)
if 'eflash_loader_cfg.ini' in flash_file[i]:
print('11111')
ret = self.flash_load_specified(convert_path(flash_file[i]), int(address[i], 16), self.callback)
if ret is False:
return (False, self.flash_burn_retry)
size_before += os.path.getsize(os.path.join(app_path, convert_path(flash_file[i])))
i += 1
if self.callback:
self.callback(i, len(flash_file), 'program')
self._need_shake_hand = False
if self._flash2_select is True:
ret = self.flash_switch_bank_process(0)
self._need_shake_hand = False
if ret is False:
return (False, self.flash_burn_retry)
printf('Program Finished')
except Exception as e:
try:
printf(e)
traceback.print_exc(limit=(self.NUM_ERR), file=(sys.stdout))
return (
False, self.flash_burn_retry)
finally:
e = None
del e
else:
printf('Warning: No input file to program to flash')
return (True, 'continue')
def sixth_run_step_write_efuse(self):
"""
Sixth step: write efuse.
"""
if self.args.efuse:
try:
if self.config['input_path']['efuse']:
efusefile = self.config['input_path']['efuse']
except:
efusefile = ''
if efusefile:
efuse_file = efusefile
mask_file = efuse_file.replace('.bin', '_mask.bin')
else:
efuse_file = self.cfg.get('EFUSE_CFG', 'file')
mask_file = self.cfg.get('EFUSE_CFG', 'maskfile')
if self.temp_task_num != None:
efuse_file = 'task' + str(self.temp_task_num) + '/' + efuse_file
efuse_load = True
efuse_verify = 0
if self.cfg.has_option('EFUSE_CFG', 'burn_en'):
efuse_load = self.cfg.get('EFUSE_CFG', 'burn_en') == 'true'
if self.cfg.has_option('EFUSE_CFG', 'factory_mode'):
if self.cfg.get('EFUSE_CFG', 'factory_mode') == 'true':
efuse_verify = 1
security_write = self.cfg.get('EFUSE_CFG', 'security_write') == 'true'
if efuse_load and self.isp_mode_sign is False:
ret = self.efuse_load_specified(efuse_file, mask_file, bytearray(0), bytearray(0), efuse_verify, security_write)
if self.callback:
self.callback(1, 1, 'APP_WR')
if ret is False:
return (False, self.flash_burn_retry)
else:
printf('efuse load disalbe')
self._need_shake_hand = False
return (True, 'continue')
def seventh_run_step_erase(self):
"""
Seventh step: erase.
"""
if self.args.erase:
printf('Erase flash operation')
if self.end == '0':
ret = self.flash_chiperase_main_process()
if ret is False:
return (False, self.flash_burn_retry)
else:
ret = self.flash_erase_main_process(int(self.start, 16), int(self.end, 16), self._need_shake_hand)
if ret is False:
return (False, self.flash_burn_retry)
printf('Erase flash OK')
return (True, 'continue')
def eighth_run_step_read(self):
"""
Eighth step: read.
"""
if self.args.read:
printf('Read operation')
if not self.args.flash:
if not self.args.efuse:
printf('No target select')
return (
False, self.flash_burn_retry)
if not (self.args.flash and self.start and self.end):
self.flash_read_jedec_id_process(self.callback)
else:
start_addr = int(self.start, 16)
end_addr = int(self.end, 16)
ret, readdata = self.flash_read_main_process(start_addr, end_addr - start_addr + 1, self._need_shake_hand, self.file, self.callback)
if ret is False:
return (False, self.flash_burn_retry)
if self.args.efuse:
start_addr = int(self.start, 16)
end_addr = int(self.end, 16)
if self.efuse_read_main_process(start_addr, end_addr - start_addr + 1, self._need_shake_hand, self.file) is False:
return (False, self.flash_burn_retry)
return (True, 'continue')
def ninth_run_step_end(self):
"""
Ninth step: run end.
"""
self.run_reset_cpu()
if self.macaddr_check is True:
self._bootinfo = self.bootinfo
self._macaddr_check = self._mac_addr
self._macaddr_check_status = False
return (
True, self.flash_burn_retry)
def set_clear_boot_status(self, shakehand=0):
pass
def set_boot_speed(self):
pass
def set_load_function(self):
self.load_function = 2
def set_decompress_write(self):
pass
def get_flash_pin(self):
return 0
def show_identify_fail(self):
return True
def run_flash2(self):
return (True, 'continue')
def get_flash1_and_flash2(self, flash_file, address, size_current, i):
return ('', 0, '', 0)
def run_reset_cpu(self):
pass
def get_mac_len(self):
return 6
def get_isp_sh_time(self):
return 0
def write_flash_data(self, file, start_addr, callback):
pass
def clear_boot_status(self, shakehand=0):
printf('Clear boot status at hbn rsvd register')
if shakehand != 0:
printf(FLASH_ERASE_SHAKE_HAND)
if self.img_load_shake_hand() is False:
return False
data = bytearray(12)
data[0] = 80
data[1] = 0
data[2] = 8
data[3] = 0
data[4] = 8
data[5] = 241
data[6] = 0
data[7] = 32
data[8] = 0
data[9] = 0
data[10] = 0
data[11] = 0
self.bflb_serial_object.write(data)
self.bflb_serial_object.deal_ack(dmy_data=False)
return True
def set_config_file(self, bootheaderFile, imgCreateFile):
self._efuse_bootheader_file = bootheaderFile
self._img_create_file = imgCreateFile
def load_eflash_loader_bin(self):
"""
This function is used to load eflash loader bin file.
"""
printf('========= load eflash_loader.bin =========')
bootinfo = None
if self.interface == 'jlink':
printf('Load eflash_loader.bin via jlink')
self.bflb_serial_object.if_init(self.device, self.speed, self.chip_type, self.chip_name)
self.bflb_serial_object.reset_cpu()
imge_fp = open_file(self.eflash_loader_file, 'rb')
fw_data = bytearray(imge_fp.read())[192:] + bytearray(0)
imge_fp.close()
sub_module = __import__(('libs.base.' + self.chip_type), fromlist=[self.chip_type])
load_addr = sub_module.jlink_load_cfg.jlink_load_addr
self.bflb_serial_object.if_raw_write(load_addr, fw_data)
pc = fw_data[4:8]
pc = bytes([pc[3], pc[2], pc[1], pc[0]])
msp = fw_data[0:4]
msp = bytes([msp[3], msp[2], msp[1], msp[0]])
self.bflb_serial_object.set_pc_msp(binascii.hexlify(pc), binascii.hexlify(msp).decode('utf-8'))
time.sleep(0.01)
self.bflb_serial_object.if_close()
return (
True, bootinfo, '')
if self.interface == 'openocd':
printf('Load eflash_loader.bin via openocd')
self.bflb_serial_object.if_init(self.device, self._bflb_sn_device, self.speed, self.chip_type, self.chip_name)
self.bflb_serial_object.halt_cpu()
imge_fp = open_file(self.eflash_loader_file, 'rb')
fw_data = bytearray(imge_fp.read())[192:] + bytearray(0)
imge_fp.close()
sub_module = __import__(('libs.base.' + self.chip_type), fromlist=[self.chip_type])
load_addr = sub_module.openocd_load_cfg.openocd_load_addr
self.bflb_serial_object.if_raw_write(load_addr, fw_data)
pc = fw_data[4:8]
pc = bytes([pc[3], pc[2], pc[1], pc[0]])
msp = fw_data[0:4]
msp = bytes([msp[3], msp[2], msp[1], msp[0]])
self.bflb_serial_object.set_pc_msp(binascii.hexlify(pc), binascii.hexlify(msp).decode('utf-8'))
return (
True, bootinfo, '')
if self.interface == 'cklink':
printf('Load eflash_loader.bin via cklink')
self.bflb_serial_object.if_init(self.device, self._bflb_sn_device, self.speed, self.chip_type, self.chip_name)
self.bflb_serial_object.halt_cpu()
imge_fp = open_file(self.eflash_loader_file, 'rb')
fw_data = bytearray(imge_fp.read())[192:] + bytearray(0)
imge_fp.close()
sub_module = __import__(('libs.base.' + self.chip_type), fromlist=[self.chip_type])
load_addr = sub_module.openocd_load_cfg.openocd_load_addr
self.bflb_serial_object.if_raw_write(load_addr, fw_data)
pc = fw_data[4:8]
pc = bytes([pc[3], pc[2], pc[1], pc[0]])
msp = fw_data[0:4]
msp = bytes([msp[3], msp[2], msp[1], msp[0]])
self.bflb_serial_object.set_pc_msp(binascii.hexlify(pc), binascii.hexlify(msp).decode('utf-8'))
self.bflb_serial_object.resume_cpu()
return (
True, bootinfo, '')
if self.interface.lower() == 'uart' or self.interface == 'sdio':
ret = True
printf('Load eflash_loader.bin via %s' % self.interface)
start_time = time.time() * 1000
ret, bootinfo, res = self._bflb_com_img_loader.img_load_process(self.boot_speed, self.boot_speed, None, self.do_reset, self.reset_hold_time, self.shake_hand_delay, self.reset_revert, self.cutoff_time, self.shake_hand_retry, self.isp_mode_sign, self._isp_shakehand_timeout, True, bootinfo)
printf('Load helper bin time cost(ms): ', time.time() * 1000 - start_time)
return (
ret, bootinfo, res)
def set_temp_timeout(self):
self.bflb_serial_object.set_timeout(self._erase_time_out / 1000)
def get_new_bh_data(self, section, bh_data, fp):
return b''
def get_chip_id(self, bootinfo):
chip_id = bootinfo[34:36] + bootinfo[32:34] + bootinfo[30:32] + bootinfo[28:30] + bootinfo[26:28] + bootinfo[24:26]
return chip_id
def get_flash_file_and_address(self):
result = True
temp_files = []
temp_addrs = []
temp_dict = {}
temp_set_addrs = []
for key, value_dict in self.config.items():
if isinstance(value_dict, dict):
if 'addr' in value_dict:
if value_dict['addr'] in temp_set_addrs:
printf('Error: %s has duplicate addresse %s!' % (key, value_dict['addr']))
return (
False, temp_addrs, temp_files)
else:
temp_dict[value_dict['addr']] = value_dict['path']
temp_set_addrs.append(value_dict['addr'])
if temp_dict:
temp_list = sorted((temp_dict.items()), key=(lambda x: int(x[0], 16)
), reverse=False)
for i in range(len(temp_list)):
temp_addrs.append(temp_list[i][0].replace('0x', ''))
temp_files.append(temp_list[i][1])
if i != 0:
temp_length = int(temp_list[i][0], 16) - int(temp_list[i - 1][0], 16)
file_length = os.path.getsize(temp_list[i - 1][1])
if temp_length < file_length:
result = False
printf('Error: path: %s size: %s range: %s' % (temp_list[i - 1][1], str(file_length), str(temp_length)))
printf('Error: The file size exceeds the address space size!')
return (
result, temp_addrs, temp_files)
def get_boot_info(self):
"""
This function is used to get boot information from chips. At the same time, it can get chip ID.
"""
printf('========= get_boot_info =========')
bootinfo = None
if self.interface == 'uart':
ret = True
start_time = time.time() * 1000
ret, bootinfo = self._bflb_com_img_loader.img_get_bootinfo(self.boot_speed, self.boot_speed, None, self.do_reset, self.reset_hold_time, self.shake_hand_delay, self.reset_revert, self.cutoff_time, self.shake_hand_retry, self.isp_mode_sign, self._isp_shakehand_timeout)
bootinfo = bootinfo.decode('utf-8')
chipid = ''
chipid = self.get_chip_id(bootinfo)
printf('========= ChipID: ', chipid, ' =========')
printf('Get bootinfo time cost(ms): ', time.time() * 1000 - start_time)
return (
ret, bootinfo, 'OK')
printf('interface not fit')
return (
False, bootinfo, '')
def error_code_print(self, code):
set_error_code(code, self.task_num)
printf('{"ErrorCode": "' + code + '","ErrorMsg":"' + eflash_loader_error_code[code] + '"}')
def clock_para_update(self, file):
if os.path.isfile(file) is False:
efuse_bootheader_path = os.path.join(chip_path, self.chip_name, 'efuse_bootheader')
efuse_bh_cfg = efuse_bootheader_path + '/efuse_bootheader_cfg.conf'
sub_module = __import__(('libs.base.' + self.chip_type), fromlist=[self.chip_type])
section = 'BOOTHEADER_GROUP0_CFG'
fp = open(efuse_bh_cfg, 'r')
data = fp.read()
fp.close()
if 'BOOTHEADER_CFG' in data:
section = 'BOOTHEADER_CFG'
else:
if 'BOOTHEADER_CPU0_CFG' in data:
section = 'BOOTHEADER_CPU0_CFG'
else:
if 'BOOTHEADER_GROUP0_CFG' in data:
section = 'BOOTHEADER_GROUP0_CFG'
bh_data, tmp = bflb_efuse_boothd_create.update_data_from_cfg(sub_module.bootheader_cfg_keys.bootheader_cfg_keys, efuse_bh_cfg, section)
bh_data = bflb_efuse_boothd_create.bootheader_update_flash_pll_crc(bh_data, self.chip_type)
fp = open(file, 'wb+')
self.get_new_bh_data(section, bh_data, fp)
fp.close()
fp = open_file(file, 'rb')
clock_para = bytearray(fp.read())
fp.close()
return clock_para
def clock_pll_set(self, shakehand, irq_en, clk_para):
printf('Clock PLL set')
if shakehand != 0:
printf('clock set shake hand')
if self.img_load_shake_hand() is False:
return False
start_time = time.time() * 1000
cmd_id = hexstr_to_bytearray(self._com_cmds.get('clk_set')['cmd_id'])
irq_enable = bytearray(4)
load_speed = bytearray(4)
if irq_en:
irq_enable = b'\x01\x00\x00\x00'
load_speed = int_to_4bytearray_l(int(self.speed))
data_send = irq_enable + load_speed + clk_para
try_cnt = 0
while True:
ret, dmy = self.com_process_one_cmd('clk_set', cmd_id, data_send)
if ret.startswith('OK'):
break
if try_cnt < self._checksum_err_retry_limit:
printf('Retry')
try_cnt += 1
else:
self.error_code_print('000C')
return False
printf('Set clock time cost(ms): ', time.time() * 1000 - start_time)
self.bflb_serial_object.repeat_init(self.device, self.speed, self.chip_type, self.chip_name)
self.bflb_serial_object.clear_buf()
time.sleep(0.01)
return True
def efuse_read_mac_addr_process(self, callback=None):
readdata = bytearray(0)
macLen = self.get_mac_len()
if self._need_shake_hand != 0:
printf(FLASH_LOAD_SHAKE_HAND)
if self.img_load_shake_hand() is False:
return (False, None)
cmd_id = hexstr_to_bytearray(self._com_cmds.get('efuse_read_mac')['cmd_id'])
printf('Read mac addr ')
ret, data_read = self.com_process_one_cmd('efuse_read_mac', cmd_id, bytearray(0))
if ret.startswith('OK') is False:
self.error_code_print('0023')
return (False, None)
readdata += data_read
crcarray = get_crc32_bytearray(readdata[:macLen])
if crcarray != readdata[macLen:macLen + 4]:
printf(binascii.hexlify(crcarray))
printf(binascii.hexlify(readdata[macLen:macLen + 4]))
self.error_code_print('0025')
return (False, None)
return (True, readdata[:macLen])
def flash_set_para_main_process(self, flash_pin, flash_para):
printf('Set flash config ')
if flash_para != bytearray(0):
if flash_para[13:14] == b'\xff':
printf('Skip set flash para due to flash id is 0xFF')
return True
if self._need_shake_hand != 0:
printf('Flash set para shake hand')
if self.img_load_shake_hand() is False:
return False
start_time = time.time() * 1000
cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_set_para')['cmd_id'])
data_send = int_to_4bytearray_l(flash_pin) + flash_para
try_cnt = 0
while True:
ret, dmy = self.com_process_one_cmd('flash_set_para', cmd_id, data_send)
if ret.startswith('OK'):
break
if try_cnt < self._checksum_err_retry_limit:
printf('Retry')
try_cnt += 1
else:
self.error_code_print('003B')
return False
printf('Set para time cost(ms): ', time.time() * 1000 - start_time)
return True
def flash_read_jedec_id_process(self, callback=None):
printf('========= flash read jedec ID =========')
readdata = bytearray(0)
if self._need_shake_hand is not False:
printf(FLASH_LOAD_SHAKE_HAND)
if self.img_load_shake_hand() is False:
return (False, None)
cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_read_jid')['cmd_id'])
ret, data_read = self.com_process_one_cmd('flash_read_jid', cmd_id, bytearray(0))
printf('Read flash jedec ID ')
if ret.startswith('OK') is False:
self.error_code_print('0030')
return (False, None)
readdata += data_read
printf('readdata: ')
printf(binascii.hexlify(readdata))
printf('Finished')
return (
True, readdata[:4])
def flash_para_update(self, file, jedec_id):
flash_para = bytearray(0)
if self.is_conf_exist(jedec_id) is True:
sub_module = __import__(('libs.base.' + self.chip_type), fromlist=[self.chip_type])
cfg_dir = app_path + '/utils/flash/' + self.chip_type + '/'
conf_name = sub_module.flash_select_do.get_suitable_file_name(cfg_dir, jedec_id)
offset, flashCfgLen, flash_para, flashCrcOffset, crcOffset = bflb_flash_select.update_flash_para_from_cfg(sub_module.bootheader_cfg_keys.bootheader_cfg_keys, cfg_dir + conf_name)
fp = open(os.path.join(app_path, file), 'wb+')
fp.write(flash_para)
fp.close()
return flash_para
def is_conf_exist(self, flash_id):
cfg_dir = app_path + '/utils/flash/' + self.chip_type + '/'
conf_name = self.get_suitable_conf_name(cfg_dir, flash_id)
if os.path.isfile(cfg_dir + conf_name) is False:
printf('ERROR: Could not find flash configuration for chip')
printf('File must be at: %s' % cfg_dir + conf_name)
2023-04-20 21:04:18 +00:00
return False
return True
def flash_chiperase_main_process(self):
printf('Flash Chip Erase All')
if self._need_shake_hand != 0:
printf(FLASH_ERASE_SHAKE_HAND)
if self.img_load_shake_hand() is False:
printf('Shake hand fail')
return False
start_time = time.time() * 1000
self.set_temp_timeout()
cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_chiperase')['cmd_id'])
try_cnt = 0
while True:
ret, dmy = self.com_process_one_cmd('flash_chiperase', cmd_id, bytearray(0))
if ret.startswith('OK'):
break
else:
if ret.startswith('PD'):
printf('erase pending')
while True:
ret = self.bflb_serial_object.deal_ack()
if ret.startswith('PD'):
printf('erase pending')
else:
self.bflb_serial_object.set_timeout(0.02)
self.bflb_serial_object.read(1000)
break
if time.time() * 1000 - start_time > self._erase_time_out:
printf('erase timeout')
break
if ret.startswith('OK'):
break
if try_cnt < self._checksum_err_retry_limit:
printf('Retry')
try_cnt += 1
else:
printf('Erase Fail')
self.bflb_serial_object.set_timeout(self._default_time_out)
self.error_code_print('0033')
return False
printf('Chip erase time cost(ms): ', time.time() * 1000 - start_time)
self.bflb_serial_object.set_timeout(self._default_time_out)
return True
def flash_cfg_option(self, read_flash_id, flash_para_file, flash_set, id_valid_flag, binfile, cfgfile, cfg, create_img_callback=None, create_simple_callback=None):
ret = bflb_flash_select.flash_bootheader_config_check(self.chip_type, read_flash_id, convert_path(binfile), flash_para_file)
if ret is False:
printf('flashcfg not match first')
if self.is_conf_exist(read_flash_id) is True:
update_cfg(cfg, 'FLASH_CFG', 'flash_id', read_flash_id)
if isinstance(cfgfile, BFConfigParser) == False:
cfg.write(cfgfile, 'w+')
if create_img_callback is not None:
create_img_callback()
else:
if create_simple_callback is not None:
create_simple_callback()
else:
self.error_code_print('003D')
return False
ret = bflb_flash_select.flash_bootheader_config_check(self.chip_name, read_flash_id, convert_path(binfile), flash_para_file)
if ret is False:
printf('flashcfg not match again')
self.error_code_print('0040')
return False
if flash_para_file:
if id_valid_flag != '80':
printf('flash para file: ', flash_para_file)
fp = open_file(flash_para_file, 'rb')
flash_para = bytearray(fp.read())
fp.close()
ret = self.flash_set_para_main_process(flash_set, flash_para)
self._need_shake_hand = False
if ret is False:
return False
def flash_switch_bank_process(self, bank):
"""When the chip has two flashes, switch the flashes according to bank."""
printf('Flash Switch Bank')
if self._need_shake_hand != 0:
printf('Flash switch bank shake hand')
if self.img_load_shake_hand() is False:
printf('Shake hand fail')
return False
start_time = time.time() * 1000
self.bflb_serial_object.set_timeout(self._erase_time_out / 1000)
cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_switch_bank')['cmd_id'])
data_send = int_to_4bytearray_l(bank)
ret, dmy = self.com_process_one_cmd('flash_switch_bank', cmd_id, data_send)
if ret.startswith('OK') is False:
printf('Switch Fail')
self.bflb_serial_object.set_timeout(self._default_time_out)
self.error_code_print('0042')
return False
printf('Switch bank time cost(ms): ', time.time() * 1000 - start_time)
self.bflb_serial_object.set_timeout(self._default_time_out)
if bank == 0:
self._flash2_select = False
else:
self._flash2_select = True
return True
def flash_load_opt(self, file, start_addr, callback=None):
printf('========= flash load =========')
if self._need_shake_hand != 0:
printf(FLASH_LOAD_SHAKE_HAND)
if self.img_load_shake_hand() is False:
return False
if self._flash2_select is True:
start_addr -= self._flash1_size
self.write_flash_data(file, start_addr, callback)
ret = self.flash_load_main_process(file, start_addr, callback)
if ret is False:
printf('Flash load fail')
return ret
fw_sha256 = ''
fp = open_file(file, 'rb')
flash_data = fp.read()
fp.close()
flash_data_len = len(flash_data)
if flash_data_len > 2097152:
self.bflb_serial_object.set_timeout(2.0 * (flash_data_len / 2097152 + 1))
sh = hashlib.sha256()
sh.update(flash_data)
fw_sha256 = sh.hexdigest()
fw_sha256 = hexstr_to_bytearray(fw_sha256)
printf('Sha caled by host: ', binascii.hexlify(fw_sha256).decode('utf-8'))
del sh
printf('xip mode Verify')
ret, read_data = self.flash_xip_read_sha_main_process(start_addr, flash_data_len, 0, None, callback)
try:
printf('Sha caled by dev: ', binascii.hexlify(read_data).decode('utf-8'))
except:
printf('Sha caled by dev: ', binascii.hexlify(read_data))
if ret is True and read_data == fw_sha256:
printf('Verify success')
else:
printf('Verify fail')
self.flash_load_tips()
self.error_code_print('003E')
ret = False
if self.verify > 0:
fp = open_file(file, 'rb')
flash_data = bytearray(fp.read())
fp.close()
flash_data_len = len(flash_data)
ret, read_data = self.flash_read_main_process(start_addr, flash_data_len, 0, None, callback)
if ret is True and read_data == flash_data:
printf('Verify success')
else:
printf('Verify fail')
self.flash_load_tips()
self.error_code_print('003E')
ret = False
printf('sbus mode Verify')
ret, read_data = self.flash_read_sha_main_process(start_addr, flash_data_len, 0, None, callback)
printf('Sha caled by dev: ', binascii.hexlify(read_data).decode('utf-8'))
if ret is True and read_data == fw_sha256:
printf('Verify success')
else:
printf('Verify fail')
self.flash_load_tips()
self.error_code_print('003E')
ret = False
self.bflb_serial_object.set_timeout(self._default_time_out)
return ret
def flash_load_specified(self, file, start_addr, callback=None):
ret = False
run_state = 0
temp_start_addr = start_addr
if len(self._skip_len) > 0 and self._skip_len[0] > 0:
fp = open_file(file, 'rb')
flash_data = fp.read()
fp.close()
flash_data_len = len(flash_data)
if self._skip_addr[0] > temp_start_addr + flash_data_len or self._skip_addr[-1] + self._skip_len[-1] < temp_start_addr:
ret = self.flash_load_opt(file, start_addr, callback)
return ret
for i in range(len(self._skip_addr)):
if self._skip_addr[i] <= start_addr:
if self._skip_addr[i] + self._skip_len[i] > start_addr and self._skip_addr[i] + self._skip_len[i] < temp_start_addr + flash_data_len:
addr = self._skip_addr[i] + self._skip_len[i]
start_addr = self._skip_addr[i] + self._skip_len[i]
else:
if self._skip_addr[i] > start_addr and self._skip_addr[i] + self._skip_len[i] < temp_start_addr + flash_data_len:
printf('skip flash file, skip addr 0x%08X, skip len 0x%08X' % (
self._skip_addr[i], self._skip_len[i]))
addr = start_addr
data = flash_data[start_addr - temp_start_addr:self._skip_addr[i] - temp_start_addr]
filename, ext = os.path.splitext(file)
file_temp = os.path.join(app_path, filename + '_skip' + str(i) + ext)
fp = open(file_temp, 'wb')
fp.write(data)
fp.close()
ret = self.flash_load_opt(file_temp, addr, callback)
start_addr = self._skip_addr[i] + self._skip_len[i]
else:
if self._skip_addr[i] > start_addr:
if self._skip_addr[i] < temp_start_addr + flash_data_len and self._skip_addr[i] + self._skip_len[i] >= temp_start_addr + flash_data_len:
printf('skip flash file, skip addr 0x%08X, skip len 0x%08X' % (
self._skip_addr[i], self._skip_len[i]))
addr = start_addr
data = flash_data[start_addr - temp_start_addr:self._skip_addr[i] - temp_start_addr]
filename, ext = os.path.splitext(file)
file_temp = os.path.join(app_path, filename + '_skip' + str(i) + ext)
fp = open(file_temp, 'wb')
fp.write(data)
fp.close()
ret = self.flash_load_opt(file_temp, addr, callback)
start_addr = temp_start_addr + flash_data_len
else:
if self._skip_addr[i] <= start_addr:
if self._skip_addr[i] + self._skip_len[i] >= temp_start_addr + flash_data_len:
printf('skip flash file, skip addr 0x%08X, skip len 0x%08X' % (
self._skip_addr[i], self._skip_len[i]))
start_addr = temp_start_addr + flash_data_len
return True
if start_addr < temp_start_addr + flash_data_len:
addr = start_addr
data = flash_data[start_addr - temp_start_addr:]
filename, ext = os.path.splitext(file)
file_temp = os.path.join(app_path, filename + '_skip' + str(i + 1) + ext)
fp = open(file_temp, 'wb')
fp.write(data)
fp.close()
ret = self.flash_load_opt(file_temp, addr, callback)
else:
ret = self.flash_load_opt(file, start_addr, callback)
return ret
def flash_load_main_process(self, file, start_addr, callback=None):
fp = open_file(file, 'rb')
flash_data = bytearray(fp.read())
fp.close()
flash_data_len = len(flash_data)
i = 0
cur_len = 0
if self.erase == 1:
ret = self.flash_erase_main_process(start_addr, start_addr + flash_data_len - 1)
if ret is False:
return False
start_time = time.time() * 1000
log = ''
if self.decompress_write and flash_data_len > 4096:
self.bflb_serial_object.set_timeout(30.0)
start_addr |= 2147483648
cmd_name = 'flash_decompress_write'
ret, flash_data, flash_data_len = self.flash_load_xz_compress(file)
if ret is False:
printf('Flash write data xz fail')
self.bflb_serial_object.set_timeout(self._default_time_out)
return False
if time.time() * 1000 - start_time > 2200:
printf(FLASH_LOAD_SHAKE_HAND)
if self.img_load_shake_hand() is False:
return False
else:
if time.time() * 1000 - start_time > 1800:
time.sleep(0.5)
printf(FLASH_LOAD_SHAKE_HAND)
if self.img_load_shake_hand() is False:
return False
printf('decompress flash load ', flash_data_len)
else:
cmd_name = 'flash_write'
while i < flash_data_len:
cur_len = flash_data_len - i
if cur_len > self._bflb_com_tx_size - 8:
cur_len = self._bflb_com_tx_size - 8
cmd_id = hexstr_to_bytearray(self._com_cmds.get(cmd_name)['cmd_id'])
data_send = int_to_4bytearray_l(i + start_addr) + flash_data[i:i + cur_len]
start_addr &= 2147483647
try_cnt = 0
while True:
ret, dmy = self.com_process_one_cmd(cmd_name, cmd_id, data_send)
if ret.startswith('OK'):
break
if try_cnt < self._checksum_err_retry_limit:
printf('Retry')
try_cnt += 1
else:
self.error_code_print('0036')
self.bflb_serial_object.set_timeout(self._default_time_out)
return False
i += cur_len
log = 'Load ' + str(i) + '/' + str(flash_data_len) + ' {"progress":' + str(i * 100 // flash_data_len) + '}'
printf(log)
if callback is not None:
if flash_data_len > 200:
callback(i, flash_data_len, 'APP_WR')
printf(log)
if self.flash_write_check_main_process() is False:
printf('Flash write check fail')
self.bflb_serial_object.set_timeout(self._default_time_out)
return False
self.bflb_serial_object.set_timeout(self._default_time_out)
printf('Flash load time cost(ms): ', time.time() * 1000 - start_time)
printf('Finished')
return True
def flash_xip_read_sha_main_process(self, start_addr, flash_data_len, shakehand=0, file=None, callback=None):
readdata = bytearray(0)
if shakehand != 0:
printf(FLASH_LOAD_SHAKE_HAND)
if self.img_load_shake_hand() is False:
return (False, None)
cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_xip_read_start')['cmd_id'])
ret, dmy = self.com_process_one_cmd('flash_xip_read_start', cmd_id, bytearray(0))
if ret.startswith('OK') is False:
self.error_code_print('0039')
return (False, None)
start_time = time.time() * 1000
log = ''
cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_xip_readSha')['cmd_id'])
data_send = int_to_4bytearray_l(start_addr) + int_to_4bytearray_l(flash_data_len)
try_cnt = 0
while True:
ret, data_read = self.com_process_one_cmd('flash_xip_readSha', cmd_id, data_send)
if ret.startswith('OK'):
break
if try_cnt < self._checksum_err_retry_limit:
printf('Retry')
try_cnt += 1
else:
printf('Read Fail')
cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_xip_read_finish')['cmd_id'])
ret, dmy = self.com_process_one_cmd('flash_xip_read_finish', cmd_id, bytearray(0))
if ret.startswith('OK') is False:
self.error_code_print('0039')
return (False, None)
return (False, None)
log += 'Read Sha256/' + str(flash_data_len)
if callback is not None:
callback(flash_data_len, flash_data_len, 'APP_VR')
readdata += data_read
printf(log)
printf('Flash xip readsha time cost(ms): ', time.time() * 1000 - start_time)
printf('Finished')
if file is not None:
fp = open_file(file, 'wb+')
fp.write(readdata)
fp.close()
cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_xip_read_finish')['cmd_id'])
ret, dmy = self.com_process_one_cmd('flash_xip_read_finish', cmd_id, bytearray(0))
if ret.startswith('OK') is False:
self.error_code_print('0039')
return (False, None)
return (True, readdata)
def flash_read_sha_main_process(self, start_addr, flash_data_len, shakehand=0, file=None, callback=None):
readdata = bytearray(0)
if shakehand != 0:
printf(FLASH_LOAD_SHAKE_HAND)
if self.img_load_shake_hand() is False:
return (False, None)
start_time = time.time() * 1000
log = ''
cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_readSha')['cmd_id'])
data_send = int_to_4bytearray_l(start_addr) + int_to_4bytearray_l(flash_data_len)
try_cnt = 0
while True:
ret, data_read = self.com_process_one_cmd('flash_readSha', cmd_id, data_send)
if ret.startswith('OK'):
break
if try_cnt < self._checksum_err_retry_limit:
printf('Retry')
try_cnt += 1
else:
self.error_code_print('0038')
return (False, None)
log += 'Read Sha256/' + str(flash_data_len)
if callback is not None:
callback(flash_data_len, flash_data_len, 'APP_VR')
readdata += data_read
printf(log)
printf('Flash readsha time cost(ms): ', time.time() * 1000 - start_time)
printf('Finished')
if file is not None:
fp = open_file(file, 'wb+')
fp.write(readdata)
fp.close()
return (True, readdata)
def flash_load_xz_compress(self, file):
try:
xz_filters = [
{'id':lzma.FILTER_LZMA2,
'dict_size':32768}]
fp = open_file(file, 'rb')
data = bytearray(fp.read())
fp.close()
flash_data = lzma.compress(data, check=(lzma.CHECK_CRC32), filters=xz_filters)
flash_data_len = len(flash_data)
except Exception as e:
try:
printf(e)
return (False, None, None)
finally:
e = None
del e
return (
True, flash_data, flash_data_len)
def flash_load_tips(self):
printf('########################################################################')
printf('请按照以下描述排查问题:')
printf('是否降低烧录波特率到500K测试过')
printf('烧写文件的大小是否超过Flash所能存储的最大空间')
printf('Flash是否被写保护')
printf('########################################################################')
def flash_erase_main_process(self, start_addr, end_addr, shakehand=0):
printf('========= flash erase =========')
printf('Erase flash from ', hex(start_addr), ' to ', hex(end_addr))
if shakehand != 0:
printf(FLASH_ERASE_SHAKE_HAND)
if self.img_load_shake_hand() is False:
printf('Shake hand fail')
return False
start_time = time.time() * 1000
self.set_temp_timeout()
cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_erase')['cmd_id'])
data_send = int_to_4bytearray_l(start_addr) + int_to_4bytearray_l(end_addr)
try_cnt = 0
while True:
ret, dmy = self.com_process_one_cmd('flash_erase', cmd_id, data_send)
if ret.startswith('OK'):
break
else:
if ret.startswith('PD'):
printf('erase pending')
while True:
ret = self.bflb_serial_object.deal_ack()
if ret.startswith('PD'):
printf('erase pending')
else:
self.bflb_serial_object.set_timeout(0.02)
self.bflb_serial_object.read(1000)
break
if time.time() * 1000 - start_time > self._erase_time_out:
printf('erase timeout')
break
if ret.startswith('OK'):
break
if try_cnt < self._checksum_err_retry_limit:
printf('Retry')
try_cnt += 1
else:
printf('Erase Fail')
self.bflb_serial_object.set_timeout(self._default_time_out)
self.error_code_print('0034')
return False
printf('Erase time cost(ms): ', time.time() * 1000 - start_time)
self.bflb_serial_object.set_timeout(self._default_time_out)
return True
def flash_read_main_process(self, start_addr, flash_data_len, shakehand=0, file=None, callback=None):
printf('========= flash read =========')
i = 0
cur_len = 0
readdata = bytearray(0)
if shakehand != 0:
printf(FLASH_LOAD_SHAKE_HAND)
if self.img_load_shake_hand() is False:
return (False, None)
start_time = time.time() * 1000
log = ''
while i < flash_data_len:
cur_len = flash_data_len - i
if cur_len > self._bflb_com_tx_size - 8:
cur_len = self._bflb_com_tx_size - 8
else:
cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_read')['cmd_id'])
data_send = int_to_4bytearray_l(i + start_addr) + int_to_4bytearray_l(cur_len)
try_cnt = 0
while True:
ret, data_read = self.com_process_one_cmd('flash_read', cmd_id, data_send)
if ret.startswith('OK'):
break
if try_cnt < self._checksum_err_retry_limit:
printf('Retry')
try_cnt += 1
else:
self.error_code_print('0035')
return (False, None)
i += cur_len
log += 'Read ' + str(i) + '/' + str(flash_data_len)
if len(log) > 50:
printf(log)
log = ''
else:
log += '\n'
if callback is not None:
callback(i, flash_data_len, 'APP_VR')
readdata += data_read
printf(log)
printf('Flash read time cost(ms): ', time.time() * 1000 - start_time)
printf('Finished')
if file is not None:
fp = open_file(file, 'wb+')
fp.write(readdata)
fp.close()
return (True, readdata)
def flash_write_check_main_process(self, shakehand=0):
printf('Write check')
if shakehand != 0:
printf(FLASH_LOAD_SHAKE_HAND)
if self.img_load_shake_hand() is False:
return False
cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_write_check')['cmd_id'])
try_cnt = 0
while True:
retry = 0
if self.decompress_write:
retry = 10
ret, dmy = self.com_process_one_cmd('flash_write_check', cmd_id, bytearray(0))
if ret.startswith('OK'):
break
if try_cnt < self._checksum_err_retry_limit + retry:
printf('Retry')
try_cnt += 1
else:
self.error_code_print('0037')
return False
return True
def efuse_load_specified(self, file, maskfile, efusedata, efusedatamask, verify=0, security_write=False):
printf('========= efuse load =========')
if self._need_shake_hand != 0:
printf('Efuse load shake hand')
ret = self.img_load_shake_hand()
if ret is False:
return False
ret = self.efuse_load_main_process(file, maskfile, efusedata, efusedatamask, verify, security_write)
return ret
def efuse_load_main_process(self, file, maskfile, efusedata, efusedatamask, verify=0, security_write=False):
if efusedata != bytearray(0):
printf('Load data')
efuse_data = efusedata
mask_data = efusedatamask
else:
if file is not None:
printf('Load file: ', file)
fp = open_file(file, 'rb')
efuse_data = bytearray(fp.read()) + bytearray(0)
fp.close()
if verify:
fp = open_file(maskfile, 'rb')
mask_data = bytearray(fp.read()) + bytearray(0)
fp.close()
else:
mask_data = bytearray(0)
if len(efuse_data) > 4096:
printf('Decrypt efuse data')
efuse_data = efuse_data[4096:]
security_key, security_iv = get_security_key()
efuse_data = aes_decrypt_data(efuse_data, security_key, security_iv, 0)
else:
efuse_data = self._efuse_data
if verify:
mask_data = self._efuse_mask_data
else:
mask_data = bytearray(0)
if security_write:
if self.get_ecdh_shared_key() is not True:
return False
printf('Load efuse 0')
if security_write:
cmd_name = 'efuse_security_write'
else:
cmd_name = 'efuse_write'
cmd_id = hexstr_to_bytearray(self._com_cmds.get(cmd_name)['cmd_id'])
data_send = efuse_data[0:124] + bytearray(4)
if security_write:
data_send = self.ecdh_encrypt_data(data_send)
data_send = int_to_4bytearray_l(0) + data_send
ret, dmy = self.com_process_one_cmd(cmd_name, cmd_id, data_send)
if ret.startswith('OK') is False:
printf('Write Fail')
self.error_code_print('0021')
return False
if verify >= 1:
ret, read_data = self.efuse_read_main_process(0, 128, shakehand=0, file=None, security_read=security_write)
if ret is True and self.efuse_compare(read_data, mask_data[0:124] + bytearray(4), efuse_data[0:124] + bytearray(4)):
printf('Verify success')
else:
printf('Read: ')
printf(binascii.hexlify(read_data[0:124]).decode('utf-8'))
printf('Expected: ')
printf(binascii.hexlify(efuse_data[0:124]).decode('utf-8'))
printf('Verify fail')
self.error_code_print('0022')
return False
data_send = bytearray(12) + efuse_data[124:128]
if security_write:
data_send = self.ecdh_encrypt_data(data_send)
data_send = int_to_4bytearray_l(112) + data_send
ret, dmy = self.com_process_one_cmd(cmd_name, cmd_id, data_send)
if ret.startswith('OK') is False:
printf('Write Fail')
self.error_code_print('0021')
return False
if verify >= 1:
ret, read_data = self.efuse_read_main_process(112, 16, shakehand=0, file=None, security_read=security_write)
if ret is True and self.efuse_compare(read_data, bytearray(12) + mask_data[124:128], bytearray(12) + efuse_data[124:128]):
printf('Verify success')
else:
printf('Read: ')
printf(binascii.hexlify(read_data[12:16]))
printf('Expected: ')
printf(binascii.hexlify(efuse_data[124:128]))
printf('Verify fail')
self.error_code_print('0022')
return False
if len(efuse_data) > 128:
printf('Load efuse 1')
if security_write:
cmd_name = 'efuse_security_write'
else:
cmd_name = 'efuse_write'
cmd_id = hexstr_to_bytearray(self._com_cmds.get(cmd_name)['cmd_id'])
data_send = efuse_data[128:252] + bytearray(4)
if security_write:
data_send = self.ecdh_encrypt_data(data_send)
data_send = int_to_4bytearray_l(128) + data_send
ret, dmy = self.com_process_one_cmd(cmd_name, cmd_id, data_send)
if ret.startswith('OK') is False:
printf('Write Fail')
self.error_code_print('0021')
return False
if verify >= 1:
ret, read_data = self.efuse_read_main_process(128, 128, shakehand=0, file=None, security_read=security_write)
if ret is True and self.efuse_compare(read_data, mask_data[128:252] + bytearray(4), efuse_data[128:252] + bytearray(4)):
printf('Verify success')
else:
printf('Verify fail')
self.error_code_print('0022')
return False
data_send = bytearray(12) + efuse_data[252:256]
if security_write:
data_send = self.ecdh_encrypt_data(data_send)
data_send = int_to_4bytearray_l(240) + data_send
ret, dmy = self.com_process_one_cmd(cmd_name, cmd_id, data_send)
if ret.startswith('OK') is False:
printf('Write Fail')
self.error_code_print('0021')
return False
if verify >= 1:
ret, read_data = self.efuse_read_main_process(240, 16, shakehand=0, file=None, security_read=security_write)
if ret is True and self.efuse_compare(read_data, bytearray(12) + mask_data[252:256], bytearray(12) + efuse_data[252:256]):
printf('Verify success')
else:
printf('Verify fail')
self.error_code_print('0022')
printf('Finished')
return True
def efuse_read_main_process(self, start_addr, data_len, shakehand=0, file=None, security_read=False):
readdata = bytearray(0)
if shakehand != 0:
printf(FLASH_LOAD_SHAKE_HAND)
if self.img_load_shake_hand() is False:
return (False, None)
if security_read:
cmd_name = 'efuse_security_read'
else:
cmd_name = 'efuse_read'
cmd_id = hexstr_to_bytearray(self._com_cmds.get(cmd_name)['cmd_id'])
data_send = int_to_4bytearray_l(start_addr) + int_to_4bytearray_l(data_len)
ret, data_read = self.com_process_one_cmd(cmd_name, cmd_id, data_send)
printf('Read efuse ')
if ret.startswith('OK') is False:
self.error_code_print('0020')
return (False, None)
readdata += data_read
if security_read:
readdata = self.ecdh_decrypt_data(readdata)
printf('Finished')
if file is not None:
fp = open_file(file, 'wb+')
fp.write(readdata)
fp.close()
return (True, readdata)
def efuse_compare(self, read_data, maskdata, write_data):
i = 0
for i in range(len(read_data)):
compare_data = read_data[i] & maskdata[i]
if compare_data & write_data[i] != write_data[i]:
printf('compare fail: ', i)
printf(read_data[i], write_data[i])
return False
return True
def img_load_shake_hand(self):
isp_sh_time = self.get_isp_sh_time()
if self.interface.lower() == 'uart':
self.bflb_serial_object.repeat_init(self.device, self.speed, self.chip_type, self.chip_name)
if self._bflb_com_img_loader.toggle_boot_or_shake_hand(2, do_reset=False,
reset_hold_time=100,
shake_hand_delay=100,
reset_revert=True,
cutoff_time=0,
isp_mode_sign=(self.isp_mode_sign),
isp_timeout=isp_sh_time,
boot_load=False,
shake_hand_retry=2) != 'OK':
self.error_code_print('0001')
return False
else:
self.bflb_serial_object.if_init(self.device, self.speed, self.chip_type, self.chip_name)
if self.bflb_serial_object.if_shakehand(do_reset=False, reset_hold_time=100,
shake_hand_delay=100,
reset_revert=True,
cutoff_time=0,
shake_hand_retry=2,
isp_timeout=isp_sh_time,
boot_load=False) != 'OK':
self.error_code_print('0001')
return False
self._need_shake_hand = False
return True
def com_process_one_cmd(self, section, cmd_id, data_send):
data_read = bytearray(0)
data_len = int_to_2bytearray_l(len(data_send))
checksum = 0
checksum += bytearray_to_int(data_len[0:1]) + bytearray_to_int(data_len[1:2])
for char in data_send:
checksum += char
data = cmd_id + int_to_2bytearray_l(checksum & 255)[0:1] + data_len + data_send
if self.interface.lower() == 'uart':
self.bflb_serial_object.write(data)
if section in self._resp_cmds:
res, data_read = self.bflb_serial_object.deal_response()
else:
res = self.bflb_serial_object.deal_ack()
else:
self.bflb_serial_object.if_write(data)
if section in self._resp_cmds:
res, data_read = self.bflb_serial_object.if_deal_response()
else:
res = self.bflb_serial_object.if_deal_ack()
return (
res, data_read)
def get_suitable_conf_name(self, cfg_dir, flash_id):
conf_files = []
for home, dirs, files in os.walk(cfg_dir):
for filename in files:
if filename.split('_')[-1] == flash_id + '.conf':
conf_files.append(filename)
if len(conf_files) > 1:
printf('Flash id duplicate and alternative is:')
for i in range(len(conf_files)):
tmp = conf_files[i].split('.')[0]
printf('%d:%s' % (i + 1, tmp))
return conf_files[i]
if len(conf_files) == 1:
return conf_files[0]
return ''
def get_ecdh_shared_key(self, shakehand=0):
printf('========= get ecdh shared key =========')
publickey_file = 'utils/pem/publickey_uecc.pem'
if shakehand != 0:
printf('Shake hand')
ret = self.img_load_shake_hand()
if ret is False:
return
tmp_ecdh = bflb_ecdh.BflbEcdh()
self._ecdh_public_key = tmp_ecdh.create_public_key()
self._ecdh_private_key = binascii.hexlify(tmp_ecdh.ecdh.private_key.to_string()).decode('utf-8')
printf('ecdh public key')
printf(self._ecdh_public_key)
printf('ecdh private key')
printf(self._ecdh_private_key)
cmd_id = hexstr_to_bytearray(self._com_cmds.get('ecdh_get_pk')['cmd_id'])
data_send = bytearray.fromhex(self._ecdh_public_key)
ret, data_read = self.com_process_one_cmd('ecdh_get_pk', cmd_id, data_send)
if ret.startswith('OK') is True:
self._ecdh_peer_public_key = binascii.hexlify(data_read).decode('utf-8')
printf('ecdh peer key')
printf(self._ecdh_peer_public_key)
self._ecdh_shared_key = tmp_ecdh.create_shared_key(self._ecdh_peer_public_key[0:128])
printf('ecdh shared key')
printf(self._ecdh_shared_key)
cmd_id = hexstr_to_bytearray(self._com_cmds.get('ecdh_chanllenge')['cmd_id'])
data_send = bytearray(0)
ret, data_read = self.com_process_one_cmd('ecdh_chanllenge', cmd_id, data_send)
if ret.startswith('OK') is True:
printf('challenge data')
printf(binascii.hexlify(data_read).decode('utf-8'))
encrypted_data = data_read[0:32]
signature = data_read[32:96]
signature_r = data_read[32:64]
signature_s = data_read[64:96]
vk = ecdsa.VerifyingKey.from_pem(open_file('utils\\pem\\room_root_publickey_ecc.pem').read())
try:
ret = vk.verify(signature, (self.ecdh_decrypt_data(encrypted_data)),
hashfunc=(hashlib.sha256),
sigdecode=(ecdsa.util.sigdecode_string))
except Exception as err:
try:
printf(err)
finally:
err = None
del err
if ret is True:
return True
printf('Challenge verify fail')
return False
else:
printf('Challenge ack fail')
return False
else:
printf('Get shared key fail')
return False
def ecdh_encrypt_data(self, data):
cryptor = AES.new(bytearray.fromhex(self._ecdh_shared_key[0:32]), AES.MODE_CBC, bytearray(16))
ciphertext = cryptor.encrypt(data)
return ciphertext
def ecdh_decrypt_data(self, data):
cryptor = AES.new(bytearray.fromhex(self._ecdh_shared_key[0:32]), AES.MODE_CBC, bytearray(16))
plaintext = cryptor.decrypt(data)
return plaintext
def close_serial(self):
if self.bflb_serial_object:
try:
self.bflb_serial_object.close()
except Exception as e:
try:
printf(e)
finally:
e = None
del e
def clear_all_data(self):
if self.bflb_serial_object:
try:
self.bflb_serial_object.clear_buf()
except Exception as e:
try:
printf(e)
finally:
e = None
del e
def base_reset_cpu(self):
if self.bflb_serial_object:
self.bflb_serial_object.reset_cpu()
def object_status_clear(self):
self.bootinfo = None
self._macaddr_check = bytearray(0)
self._macaddr_check_status = False
def flash_read_status_reg_process(self, cmd, len, callback=None):
printf('========= flash read status register =========')
readdata = bytearray(0)
if self._need_shake_hand is not False:
printf(FLASH_LOAD_SHAKE_HAND)
if self.img_load_shake_hand() is False:
return (False, None)
cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_read_status_reg')['cmd_id'])
data_send = int_to_4bytearray_l(int(cmd, 16)) + int_to_4bytearray_l(len)
ret, data_read = self.com_process_one_cmd('flash_read_status_reg', cmd_id, data_send)
printf('Read flash status register ')
if ret.startswith('OK') is False:
self.error_code_print('0031')
return (False, None)
readdata += data_read
printf('readdata: ')
printf(binascii.hexlify(readdata))
printf('Finished')
return (
True, readdata)
def flash_write_status_reg_process(self, cmd, len, write_data, callback=None):
printf('========= flash write status register =========')
if self._need_shake_hand is not False:
printf(FLASH_LOAD_SHAKE_HAND)
if self.img_load_shake_hand() is False:
return (False, 'Flash load shake hand fail')
printf('write_data ', write_data)
cmd_id = hexstr_to_bytearray(self._com_cmds.get('flash_write_status_reg')['cmd_id'])
data_send = int_to_4bytearray_l(int(cmd, 16)) + int_to_4bytearray_l(len) + int_to_4bytearray_l(int(write_data, 16))
ret, data_read = self.com_process_one_cmd('flash_write_status_reg', cmd_id, data_send)
printf('Write flash status register ')
if ret.startswith('OK') is False:
self.error_code_print('0032')
return (False, 'Write fail')
printf('Finished')
return (True, None)
def bl_get_largest_addr(self, addrs, files):
maxlen = 0
datalen = 0
for i in range(len(addrs)):
if int(addrs[i], 16) > maxlen:
maxlen = int(addrs[i], 16)
if os.path.exists(files[i]):
datalen = os.path.getsize(files[i])
else:
datalen = os.path.getsize(os.path.join(app_path, files[i]))
return maxlen + datalen
def bl_get_file_data(self, files):
datas = []
for file in files:
if os.path.exists(file):
temp_path = file
else:
temp_path = os.path.join(app_path, file)
with open(temp_path, 'rb') as fp:
data = fp.read()
datas.append(data)
return datas
def bl_create_flash_default_data(self, length):
datas = bytearray(length)
for i in range(length):
datas[i] = 255
return datas
def bl_write_flash_img(self, d_addrs, d_files, flash_size='1M'):
whole_img_len = self.bl_get_largest_addr(d_addrs, d_files)
whole_img_data = self.bl_create_flash_default_data(whole_img_len)
whole_img_file = os.path.join(chip_path, self.chip_name, 'img_create', 'whole_flash_data.bin')
if os.path.exists(whole_img_file):
os.remove(whole_img_file)
filedatas = self.bl_get_file_data(d_files)
for i in range(len(d_addrs)):
start_addr = int(d_addrs[i], 16)
whole_img_data[start_addr:start_addr + len(filedatas[i])] = filedatas[i]
if not os.path.exists(os.path.dirname(whole_img_file)):
os.makedirs(os.path.dirname(whole_img_file))
fp = open(whole_img_file, 'wb+')
fp.write(whole_img_data)
fp.close()
def get_flash_pin_from_bootinfo(self, chiptype, bootinfo):
return 128
# okay decompiling ./libs/base/bflb_base_eflash_loader.pyc