zephyr/boards/xtensa/intel_s1000_crb/support/download.py

134 lines
3.9 KiB
Python

#!/usr/bin/env python3
#
# Copyright (c) 2019 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
# Author: Sathish Kuttan <sathish.k.kuttan@intel.com>
# This script is the top level script that an user can invoke to
# download a Zephyr application binary from a Linux host connected
# over SPI to Intel Sue Creek S1000 target during development.
import os
import sys
import hashlib
import device
import messenger
sue_creek = device.Device()
msg = messenger.Message()
def check_arguments():
"""
Check whether file name is provided.
If not print usage instruction and exit.
"""
if len(sys.argv) != 2:
print('Usage: python3 %s <zephyr.bin>' % sys.argv[0])
sys.exit()
return sys.argv[1]
def calc_firmware_sha(file):
"""
Open firmware image file and calculate file size
Pad file size to a multiple of 64 bytes
Calculate SHA256 hash of the padded contents
"""
with open(file, 'rb') as firmware:
firmware.seek(0, 2)
size = firmware.tell()
# pad firmware to round upto 64 byte boundary
padding = (size % 64)
if padding != 0:
padding = (64 - padding)
size += padding
firmware.seek(0, 0)
sha256 = hashlib.sha256()
for block in iter(lambda: firmware.read(4096), b""):
sha256.update(block)
firmware.close()
if padding != 0:
sha256.update(b'\0' * padding)
print('Firmware (%s): %d bytes, will be padded to %d bytes.'
% (os.path.basename(file), size - padding, size))
else:
print('Firmware file size: %d bytes.' % size)
print('SHA: ' + sha256.hexdigest())
return (size, padding, sha256.digest())
def setup_device():
"""
Configure SPI master device
Reset target and send initialization commands
"""
sue_creek.configure_device(spi_mode=3, order='msb', bits=8)
sue_creek.reset_device()
command = msg.create_memwrite_cmd((0x71d14, 0, 0x71d24, 0,
0x304628, 0xd, 0x71fd0, 0x3))
response = sue_creek.send_receive(command)
msg.print_response(response)
def load_firmware(file, size, padding, sha):
"""
Send command to load firmware
Transfer binary file contents including padding
"""
command = msg.create_loadfw_cmd(size, sha)
response = sue_creek.send_receive(command)
msg.print_response(response)
with open(file, 'rb') as firmware:
firmware.seek(0, 0)
block_size = msg.get_bulk_message_size()
transferred = 0
for block in iter(lambda: firmware.read(block_size), b""):
if len(block) < block_size:
block += b'\0' * padding
bulk_msg = msg.create_bulk_message(block)
sue_creek.send_bulk(bulk_msg)
transferred += len(bulk_msg)
sys.stdout.write('\r%d of %d bytes transferred to %s.'
% (transferred, size, sue_creek.name))
print('')
firmware.close()
sue_creek.check_device_ready()
command = msg.create_null_cmd()
response = sue_creek.send_receive(command)
msg.print_response(response)
def execute_firmware():
"""
Send command to start execution
"""
command = msg.create_memwrite_cmd((0x71d10, 0, 0x71d20, 0))
response = sue_creek.send_receive(command)
msg.print_response(response)
command = msg.create_execfw_cmd()
response = sue_creek.send_receive(command, wait=False)
msg.print_response(response)
def main():
"""
Check arguments to ensure binary file is provided.
Calculate SHA of the binary image
Setup the SPI master device and GPIOs on the host
Download Firmware
"""
file = check_arguments()
(size, padding, sha) = calc_firmware_sha(file)
setup_device()
load_firmware(file, size, padding, sha)
execute_firmware()
sue_creek.close()
if __name__ == '__main__':
main()