diff options
author | Andrew Boie <andrew.p.boie@intel.com> | 2016-05-26 14:45:52 -0700 |
---|---|---|
committer | Anas Nashif <nashif@linux.intel.com> | 2016-06-10 15:22:40 +0000 |
commit | 9280e71ea407062df4be946e758a3009cbd27b15 (patch) | |
tree | d4954f81499b8b37608700d7a8e5c3f05163f50f /scripts/support | |
parent | fe6f178a3bb514e5698c2c97d1e1d861d0012f51 (diff) |
nios2: add flashing/debug scripts
For the moment, NIOS2_CPU_SOF must be set with the path to the
CPU configuration. We are checking with Altera on whether we
can directly check in the binary to the source tree.
These scripts depend on tools provided by the Altera Quartus
Prime Lite Edition. This is available for free but requires
registration on Altera's website to obtain.
Change-Id: Ia6cb6c9e43c3e141807a887cb25c47b370a7d8e9
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
Diffstat (limited to 'scripts/support')
-rwxr-xr-x | scripts/support/nios2.sh | 53 | ||||
-rwxr-xr-x | scripts/support/quartus-flash.py | 140 |
2 files changed, 193 insertions, 0 deletions
diff --git a/scripts/support/nios2.sh b/scripts/support/nios2.sh new file mode 100755 index 000000000..1b96ab16b --- /dev/null +++ b/scripts/support/nios2.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +set -e + +HEX_NAME=${O}/${KERNEL_HEX_NAME} +ELF_NAME=${O}/${KERNEL_ELF_NAME} + +GDB_TCP_PORT=1234 + +REQUIRED_PROGRAMS="quartus_cpf quartus_pgm nios2-gdb-server" + + +for pgm in ${REQUIRED_PROGRAMS}; do + type -P $pgm > /dev/null 2>&1 || { echo >&2 "$pgm not found in PATH"; exit 1; } +done + +do_flash() { + if [ -z "${NIOS2_CPU_SOF}" ]; then + echo "Please set NIOS2_CPU_SOF variable to location of CPU .sof data" + exit 1 + fi + + ${ZEPHYR_BASE}/scripts/support/quartus-flash.py \ + --sof ${NIOS2_CPU_SOF} \ + --kernel ${HEX_NAME} +} + +do_debug() { + do_debugserver & + + # connect to the GDB server + ${GDB} ${TUI} -ex "target remote :${GDB_TCP_PORT}" ${ELF_NAME} +} + +do_debugserver() { + nios2-gdb-server --tcpport ${GDB_TCP_PORT} +} + + +CMD="$1" +shift + +case "${CMD}" in + flash) + do_flash "$@" + ;; + debugserver) + do_debugserver "$@" + ;; + debug) + do_debug "$@" + ;; +esac diff --git a/scripts/support/quartus-flash.py b/scripts/support/quartus-flash.py new file mode 100755 index 000000000..9429f769b --- /dev/null +++ b/scripts/support/quartus-flash.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python3 + +import subprocess +import tempfile +import argparse +import os +import string +import sys +import shutil + +quartus_cpf_template = """<?xml version="1.0" encoding="US-ASCII" standalone="yes"?> +<cof> + <output_filename>${OUTPUT_FILENAME}</output_filename> + <n_pages>1</n_pages> + <width>1</width> + <mode>14</mode> + <sof_data> + <user_name>Page_0</user_name> + <page_flags>1</page_flags> + <bit0> + <sof_filename>${SOF_FILENAME}<compress_bitstream>1</compress_bitstream></sof_filename> + </bit0> + </sof_data> + <version>10</version> + <create_cvp_file>0</create_cvp_file> + <create_hps_iocsr>0</create_hps_iocsr> + <auto_create_rpd>0</auto_create_rpd> + <rpd_little_endian>1</rpd_little_endian> + <options> + <map_file>1</map_file> + </options> + <MAX10_device_options> + <por>0</por> + <io_pullup>1</io_pullup> + <config_from_cfm0_only>0</config_from_cfm0_only> + <isp_source>0</isp_source> + <verify_protect>0</verify_protect> + <epof>0</epof> + <ufm_source>2</ufm_source> + <ufm_filepath>${KERNEL_FILENAME}</ufm_filepath> + </MAX10_device_options> + <advanced_options> + <ignore_epcs_id_check>2</ignore_epcs_id_check> + <ignore_condone_check>2</ignore_condone_check> + <plc_adjustment>0</plc_adjustment> + <post_chain_bitstream_pad_bytes>-1</post_chain_bitstream_pad_bytes> + <post_device_bitstream_pad_bytes>-1</post_device_bitstream_pad_bytes> + <bitslice_pre_padding>1</bitslice_pre_padding> + </advanced_options> +</cof> +""" + +# XXX Do we care about FileRevision, DefaultMfr, PartName? Do they need +# to be parameters? So far seems to work across 2 different boards, leave +# this alone for now. +quartus_pgm_template = """/* Quartus Prime Version 16.0.0 Build 211 04/27/2016 SJ Lite Edition */ +JedecChain; + FileRevision(JESD32A); + DefaultMfr(6E); + + P ActionCode(Cfg) + Device PartName(10M50DAF484ES) Path("${POF_DIR}/") File("${POF_FILE}") MfrSpec(OpMask(1)); + +ChainEnd; + +AlteraBegin; + ChainType(JTAG); +AlteraEnd;""" + + +def create_pof(input_sof, kernel_hex): + """given an input CPU .sof file and a kernel binary, return a file-like + object containing .pof data suitable for flashing onto the device""" + + t = string.Template(quartus_cpf_template) + output_pof = tempfile.NamedTemporaryFile(suffix=".pof") + + input_sof = os.path.abspath(input_sof) + kernel_hex = os.path.abspath(kernel_hex) + + # These tools are very stupid and freak out if the desired filename + # extensions are used. The kernel image must have extension .hex + + with tempfile.NamedTemporaryFile(suffix=".cof") as temp_xml: + + xml = t.substitute(SOF_FILENAME=input_sof, + OUTPUT_FILENAME=output_pof.name, + KERNEL_FILENAME=kernel_hex) + + temp_xml.write(bytes(xml, 'UTF-8')) + temp_xml.flush() + + cmd = ["quartus_cpf", "-c", temp_xml.name] + try: + subprocess.check_output(cmd) + except subprocess.CalledProcessError as cpe: + print(cpe.output.decode("UTF-8")) + print("Failed to create POF file") + sys.exit(1) + + return output_pof + + +def flash_kernel(device_id, input_sof, kernel_hex): + pof_file = create_pof(input_sof, kernel_hex) + + with tempfile.NamedTemporaryFile(suffix=".cdf") as temp_cdf: + dname, fname = os.path.split(pof_file.name) + t = string.Template(quartus_pgm_template) + cdf = t.substitute(POF_DIR=dname, POF_FILE=fname) + temp_cdf.write(bytes(cdf, 'UTF-8')) + temp_cdf.flush() + cmd = ["quartus_pgm", "-c", device_id, temp_cdf.name] + try: + subprocess.check_output(cmd) + except subprocess.CalledProcessError as cpe: + print(cpe.output.decode("UTF-8")) + print("Failed to flash image") + sys.exit(1) + pof_file.close() + +def main(): + parser = argparse.ArgumentParser(description="Flash zephyr onto Altera boards") + parser.add_argument("-s", "--sof", + help=".sof file with Nios II CPU configuration") + parser.add_argument("-k", "--kernel", + help="Zephyr kernel image to place into UFM in Intel HEX format") + parser.add_argument("-d", "--device", + help="Remote device identifier / cable name. Default is " + "USB-BlasterII. Run jtagconfig -n if unsure.", + default="USB-BlasterII") + + args = parser.parse_args() + + flash_kernel(args.device, args.sof, args.kernel) + + +if __name__ == "__main__": + main() + |