134 lines
3.9 KiB
Python
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()
|