Files
Linux_Drivers/build/tools/cv183x/usb_dl/cv1835_usb_download.py
sam.xiang a4f213ceb0 [build] add cvitek build scripts
Change-Id: If63ce4a669e5d4d72b8e3b9253336dd99bf74c30
2023-03-10 20:35:59 +08:00

274 lines
8.5 KiB
Python

#!/usr/bin/python3
from cv_usb_util.cv_usb import cv_usb
import argparse
import logging
import os
import sys
import time
import cv_usb_util.cv_usb_pkt as pkt
from glob import glob
from array import array
from XmlParser import XmlParser
from zipfile import ZipFile
from tempfile import mkdtemp
from singleton import SingleInstance
FORMAT = '%(levelname)s: %(message)s'
logging.basicConfig(level=logging.INFO, format=FORMAT)
parser = argparse.ArgumentParser(description='Create CVITEK device image')
header_size = 64
max_chunk_size = 100 * 1024 * 1024
uboot_vidpid = ""
uboot_cvi_vidpid = ""
def parse_Args():
cur_dir = os.path.abspath(os.getcwd())
parser.add_argument(
'--image_dir',
metavar='path',
type=str,
default=cur_dir,
help='the folder path to dir inclued fip,rootfs kernel and xml')
parser.add_argument(
'--location',
metavar='',
type=str)
parser.add_argument(
'--pid',
metavar='1001',
default='1001',
type=str)
parser.add_argument("--zipfile",
metavar="path to upgrade.zip",
type=str,
help="the path of upgrade.zip")
parser.add_argument("-v",
"--verbose",
help="increase output verbosity",
action="store_true")
group = parser.add_mutually_exclusive_group()
group.add_argument('--serial', action='store_true', default=False)
group.add_argument('--libusb', action='store_true', default=False)
parser.add_argument("--mac",
metavar="mac address",
type=str,
help="set mac address")
args = parser.parse_args()
if args.zipfile:
args.image_dir = mkdtemp()
with ZipFile(args.zipfile, 'r') as zipObj:
zipObj.extractall(args.image_dir)
if args.verbose:
logging.debug("Enable more verbose output")
logging.getLogger().setLevel(level=logging.DEBUG)
return args
def usage():
parser.print_usage()
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.dirname(os.path.realpath(__file__))
return os.path.join(base_path, relative_path)
def changeOffset(fd, offset):
last_pos = fd.tell()
"""
Since we cannot send cmd to device due to security issue. We can
only modify the header information for changing the offset we
want to program.
"""
# Get Chunk header
chunk_header = array('I')
chunk_header.fromfile(fd, 64)
chunk_header[2] = offset
# Modify header according to the partition.xml
fd.seek(last_pos)
fd.write(chunk_header)
fd.seek(last_pos)
def set_macaddress(usb, libusb, mac):
global uboot_vidpid
global uboot_cvi_vidpid
if not libusb:
usb.restart()
logging.info("set macaddress... ")
usb.query([uboot_vidpid, uboot_cvi_vidpid])
time.sleep(0.2)
# Send setenv
cmd = array('B', [ord(c) for c in "setenv ethaddr "])
for c in [ord(ch) for ch in mac]:
cmd.append(c)
usb.send_req_data(pkt.CV_USB_PRG_CMD, 0, len(cmd) + 8, cmd)
# Send savenv
cmd = array('B', [ord(c) for c in "saveenv"])
usb.send_req_data(pkt.CV_USB_PRG_CMD, 0, len(cmd) + 8, cmd)
# Break command
# usb.send_req_data(pkt.CV_USB_BREAK, 0x04003000, 0, None)
def reboot_device(usb, libusb):
global uboot_vidpid
global uboot_cvi_vidpid
# if not libusb:
# usb.restart()
# usb.query([uboot_vidpid,uboot_cvi_vidpid])
# time.sleep(0.2)
usb.send_req_data(pkt.CVI_USB_REBOOT, 0x04003000, 0, None)
logging.info("reboot device done")
def main():
args = parse_Args()
image_dir = args.image_dir
location = args.location
pid = args.pid
# location != None is usb_mult_dl
if(location is None):
try:
me = SingleInstance()
except Exception:
print("%d" % me)
exit(-1)
xml = glob(os.path.join(image_dir, "partition*.xml"))
if len(xml) != 1:
logging.error("Cannot get correct partition xml in %s", image_dir)
usage()
return
xmlParser = XmlParser(xml[0])
parts = xmlParser.parse(image_dir)
fip_path = os.path.join(image_dir, "fip.bin")
if not os.path.isfile(fip_path):
logging.error("Cannot find fip.bin in %s", image_dir)
cv_dl_magic = open(resource_path('cv_dl_magic.bin'), 'rb')
cv_dl_magic_size = os.path.getsize(resource_path('cv_dl_magic.bin'))
logging.info("CV1835 USB download start... ")
if (not args.serial and not args.libusb) or args.serial:
driver = "pyserial"
else:
driver = "libusb"
logging.info("Using %s" % driver)
usb = cv_usb(driver)
logging.info("Connecting to ROM code... ")
usb.query([pkt.rom_vidpid, pkt.rom_cvi_vidpid])
usb.send_chunk(cv_dl_magic, cv_dl_magic_size, 0x4003000, 0, Type="magic")
logging.info("done")
logging.info("Send fip.bin...")
usb.send_file(fip_path, 0x0C040000, 0)
logging.info("done")
# Set SRAM flag
logging.info("Send magic number for USB boot... ")
flag = array('B', [ord(c) for c in "1NGM"])
usb.send_req_data(pkt.CV_USB_NONE, 0x0E00FC00, 12, flag)
logging.info("done")
logging.info("Send magic number for USB download... ")
flag = array('B')
flag = array('B', [ord(c) for c in "3NGM"])
usb.send_req_data(pkt.CV_USB_NONE, 0x0E00FC08, 12, flag)
logging.info("done")
flag = array('B')
flag = array('B', [int(c) for c in pid])
usb.send_req_data(pkt.CV_USB_NONE, 0x0E00FFFC, 12, flag)
logging.info("set uboot pid")
usb.send_req_data(pkt.CV_USB_BREAK, 0x04003000, 0, None)
files = []
prog_parts = []
if xmlParser.getStorage() == "emmc":
files.append(fip_path)
prog_parts.append({}) # Add empty dict for fip
uboot_vidpid = "VID:PID=30B1:" + pid
uboot_cvi_vidpid = "VID:PID=3346:" + pid
usb.query([uboot_vidpid, uboot_cvi_vidpid])
for p in parts:
if p['file_size'] != 0:
files.append(p['file_path'])
prog_parts.append(p)
for i, f in enumerate(files):
if(location is not None):
# For UI Tool
print("SEND FILE %s " % files[i] + "LOCATION=" + location + "\r\n")
else:
logging.info("Send %s " % files[i])
if i == 0:
usb.send_file(f, 0x100090000, 0)
usb.send_req_data(pkt.CV_USB_BREAK, 0x04003000, 0, None)
usb.query([uboot_vidpid, uboot_cvi_vidpid])
time.sleep(0.02)
else:
if (driver == "pyserial"):
usb.restart()
logging.info("Connecting to u-boot... ")
usb.query([uboot_vidpid, uboot_cvi_vidpid])
time.sleep(1)
fd = open(f, 'r+b')
usb.send_chunk(fd, header_size, 0x100080000, 0)
fd.seek(0)
header = array('I')
header.fromfile(fd, int(header_size / 4))
chunk_header_sz = header[2]
cnt = header[3]
file_size = header[4]
remain_file_size = file_size
offset = prog_parts[i]["offset"]
for j in range(cnt):
if (j > 0 and driver == "pyserial"):
usb.restart()
logging.info("Connecting to u-boot... ")
usb.query([pkt.uboot_vidpid, pkt.uboot_cvi_vidpid])
time.sleep(0.02)
send_size = min(remain_file_size, max_chunk_size + chunk_header_sz)
# location != None is usb_mult_dl
if(location is None):
changeOffset(fd, offset)
usb.send_chunk(
fd,
send_size,
0x100090000,
0,
)
logging.info("CVI_USB_PROGRAME")
usb.send_req_data(pkt.CVI_USB_PROGRAME, 0x04003000, 0, None)
remain_file_size -= send_size
offset += max_chunk_size
if file_size == fd.tell():
break
fd.close()
logging.info("Image download finished, waiting for reboot!")
if args.mac:
set_macaddress(usb, driver == "libusb", args.mac)
reboot_device(usb, driver == "libusb")
if __name__ == '__main__':
main()