| #!/bin/bash |
| # |
| # Copyright 2023 Google LLC |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # https://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| # Run a test on the nexus FPGA platform |
| set -ex |
| |
| BITSTREAM_PATH="$1" |
| BINARY_PATH="$2" |
| NEXUS_ID="${NEXUS_ID:-$3}" |
| DEFAULT_NEXUS_FLASH_PATH="${ROOTDIR}/internal/nexus_usage/nexus_flash.sh" |
| NEXUS_FLASH_PATH="${NEXUS_FLASH_PATH:-$DEFAULT_NEXUS_FLASH_PATH}" |
| export LOG_TIMEOUT="${LOG_TIMEOUT:-900}" |
| export LOG_CHECK_INTERVAL="${LOG_CHECK_INTERVAL:-30}" |
| |
| |
| function mcu_write() { |
| string=$1 |
| length=${#string} |
| for ((i = 0; i < length; i++)); do |
| char="${string:i:1}" |
| echo -n "$char" |
| sleep 0.5 |
| done > "/dev/Nexus-FTDI-${NEXUS_ID}-MCU-UART" |
| echo -e "\r" > "/dev/Nexus-FTDI-${NEXUS_ID}-MCU-UART" |
| } |
| |
| |
| if [ $# -lt 2 ] || [ $# -gt 3 ] ; then |
| cat << EOF |
| $0 <bitstream> <binary> [nexus index] |
| bitstream: The path to the nexus bitstream. |
| This will be copied and loaded to the fpga. |
| If the bitstream file doesn't exist the test will continue with |
| whatever bitstream is already loaded. |
| binary: The path to the test binary. |
| This will be loaded with the opentitantool utility using the |
| bootstrap subcommand |
| nexus index: The number assigned to the nexus board that will be used for |
| the test. Include zero padding for numbers less than 10. This |
| arg is optional and will fall back on the NEXUS_ID environment |
| variable. |
| EOF |
| exit 1 |
| fi |
| |
| # Verify no one else is using our UARTs |
| if fuser "/dev/Nexus-FTDI-${NEXUS_ID}-FPGA-UART" |
| then |
| echo "/dev/Nexus-FTDI-${NEXUS_ID}-FPGA-UART appears to be busy" |
| fi |
| if fuser "/dev/Nexus-CP210-FPGA-UART-${NEXUS_ID}" |
| then |
| echo "/dev/Nexus-CP210-FPGA-UART-${NEXUS_ID} appears to be busy" |
| fi |
| if fuser "/dev/Nexus-FTDI-${NEXUS_ID}-MCU-UART" |
| then |
| echo "/dev/Nexus-FTDI-${NEXUS_ID}-MCU-UART appears to be busy" |
| fi |
| |
| stty --file="/dev/Nexus-FTDI-${NEXUS_ID}-FPGA-UART" sane 115200 |
| stty --file="/dev/Nexus-CP210-FPGA-UART-${NEXUS_ID}" sane 115200 |
| stty --file="/dev/Nexus-FTDI-${NEXUS_ID}-MCU-UART" 115200 |
| |
| # Starting logging the UARTs |
| cat "/dev/Nexus-FTDI-${NEXUS_ID}-FPGA-UART" > uart.sc.log 2> uart.sc.err & |
| SC_UART_PID=$! |
| cat "/dev/Nexus-CP210-FPGA-UART-${NEXUS_ID}" > uart.smc.log 2> uart.smc.err & |
| SMC_UART_PID=$! |
| |
| # Logging cleanup for when the script exits |
| trap 'kill -INT ${SC_UART_PID} ; kill -INT ${SMC_UART_PID} ; \ |
| sleep 10 ; \ |
| kill -KILL ${SC_UART_PID} ; kill -KILL ${SMC_UART_PID}' 0 |
| |
| if [[ -f "${BITSTREAM_PATH}" ]]; then |
| # Issue a no-op command to flush the character buffer in case it isn't empty |
| mcu_write "help" |
| scp \ |
| "${BITSTREAM_PATH}" \ |
| "root@nexus${NEXUS_ID}:/mnt/mmcp1/" |
| mcu_write "camera_powerdown" |
| sleep 5 |
| # zturn exits with 1 even when working correctly. Mask with exit 0 |
| BITSTREAM_NAME=$(basename "${BITSTREAM_PATH}") |
| ssh \ |
| "root@nexus${NEXUS_ID}" \ |
| "/mnt/mmcp1/zturn -d a /mnt/mmcp1/${BITSTREAM_NAME} ; exit 0" |
| mcu_write "camera_powerup" |
| fi |
| |
| OT_TOOL_PATH=`command -v opentitantool` |
| NEXUS_JSON_DIR=`dirname "${OT_TOOL_PATH}"` |
| NEXUS_JSON_PATH="${NEXUS_JSON_DIR}/nexus.json" |
| |
| if [[ "${BINARY_PATH}" == *".bin" ]]; then |
| opentitantool \ |
| --conf "${NEXUS_JSON_PATH}" \ |
| --interface nexus \ |
| --usb-serial "Nexus-FTDI-${NEXUS_ID}" \ |
| bootstrap "${BINARY_PATH}" |
| elif [[ "${BINARY_PATH}" == *"extflash.tar" ]]; then |
| export NEXUS_BOARD="${NEXUS_ID}" |
| export OT_TOOL="${OT_TOOL_PATH}" |
| export NEXUS_JSON="${NEXUS_JSON_PATH}" |
| "${NEXUS_FLASH_PATH}" "${BINARY_PATH}" |
| fi |
| |
| timeout "${LOG_TIMEOUT}" bash -c ' |
| until grep -q -e PASS! -e FAIL! uart.sc.log uart.smc.log ; do |
| echo "Expected log is missing. Wait up to ${LOG_TIMEOUT}s." |
| sleep "${LOG_CHECK_INTERVAL}" |
| done' || echo "Time out waiting for PASS! or FAIL! log" |
| |
| cat -n uart.sc.log |
| cat -n uart.sc.err |
| cat -n uart.smc.log |
| cat -n uart.smc.err |
| |
| grep -q "PASS!" uart.sc.log uart.smc.log |
| exit $? |