blob: 065aa2901946e5cee9436990e7a718f6bb0179c6 [file] [log] [blame]
#!/bin/bash
# Copyright 2020 NXP
# All rights reserved.
# SPDX-License-Identifier: BSD-3-Clause
###########################################################################################
# Bash script for loading CM4 ELF files to the remote iMX ARM-CM4 core via SSH and
# starting/stopping it using remoteproc. In order to use this script, make sure the remoteproc
# Linux kernel module is loaded and that the device is connected to your local network with an IP.
# The authentication is performed using SSH keys.
# Set up the SSH keys beforehand (https://www.ssh.com/ssh/keygen) and make sure you can login
# to the device without having to provide a password!
# Configure the Linux login Username and IP address (hostname) in the device.cfg file and test the
# connection using `load.sh state`.
# The script was tested with OpenSSH version 8.1 which is provided with the Windows Git Bash
############################################################################################
## Configuration file - contains the Username and Hostname of the remote
source ./remote.cfg
## Print Usage
function print_usage {
echo "Usage: load.sh <firmware.elf> [action]";
echo " flash - (default) download the ELF file to the remote and start the core";
echo " start - Start the remote core";
echo " stop - Stop the remote core";
echo " restart - Restart the remote core";
echo " state - Get the state of the remote core";
}
if [[ -z "$1" || "$1" == "-h" || "$1" == "--help" || "$1" == "-help" || "$1" == "help" ]]; then
print_usage;
exit 0;
fi
if [[ $# == 1 ]]; then
# We need a firmware file in order to flash
if [[ "$1" == "flash" ]]; then
echo "Please provide a ELF firmware file: load.sh <firmware.elf> flash";
exit 1;
fi
# These comands can be executed without firmware file
if [[ "$1" == "start" || "$1" == "stop" || "$1" == "restart" || "$1" == "state" ]]; then
ACTION=$1;
else
# The argument is probably a path, we are going to flash by default
ACTION='flash';
fi
elif [[ $# == 2 ]]; then
# When two arguments provided, first is the elf file path, the second is a command.
ACTION="$2";
else
echo "Invalid number of arguments";
print_usage;
exit 1;
fi
# TODO: Better way of converting paths (only valid for flash command)
ELFPATH=$(echo "$1" | sed -e 's/\\/\//g' -e 's/C:/\/c/'); # Convert Windows path to UNIX path
ELFNAME="$(basename $ELFPATH)";
### Commands to execute on the Remote
#------------------------------------
# 1. Check if the M4 core is in the running state, and if nescessary stop it
# 2. Set the firmware to the name of the new ELF file
# 3. Start the M4 core
REMOTEPROC_START="\
echo start > $REMOTEPROC/state;";
REMOTEPROC_STOP="\
[[ \$(< $REMOTEPROC/state) == 'running' ]] && echo stop > $REMOTEPROC/state; ";
REMOTEPROC_FLASH="\
$REMOTEPROC_STOP \
echo $ELFNAME.elf > $REMOTEPROC/firmware; \
$REMOTEPROC_START";
REMOTEPROC_RESTART="\
$REMOTEPROC_STOP \
$REMOTEPROC_START";
REMOTEPROC_GET_STATE="\
cat $REMOTEPROC/state;";
# Build the SSH Username and Hostname string
SSH_USER_HOST="$SSH_USER@$SSH_HOST";
# If specifying a jump proxy, set the
if [[ -n "$SSH_PROXY" ]]; then
SSH_PROXY="-J $SSH_PROXY";
fi
# If designating a different SSH port, set up the correct flags
if [[ -n "$SSH_PORT" ]]; then
SSH_PORT_SCP="-P $SSH_PORT";
SSH_PORT_SSH="-p $SSH_PORT";
else
SSH_PORT_SCP="";
SSH_PORT_SSH="";
fi
## get_core_state retrieves the state of the core from the remote and prints it to the console
function get_core_state {
result="$(echo $REMOTEPROC_GET_STATE | \
ssh $SSH_PROXY $SSH_PORT_SSH $SSH_USER_HOST 'bash -s')";
if [ $? != 0 ]; then
echo "Failed getting Core state";
exit 1;
fi
echo "M4 Core is $result!";
}
## Copy firmware ELF file to the remote /lib/firmware directory
function flash_firmware {
echo "==========================================";
echo "Copying $ELFNAME to remote $SSH_USER_HOST";
scp $SSH_PROXY $SSH_PORT_SCP $ELFPATH $SSH_USER_HOST:/lib/firmware/$ELFNAME.elf;
if [ $? != 0 ]; then
echo "Failed Transfering ELF file!";
get_core_state;
exit 1;
fi
}
## Send a given remoteproc bash script, passed as an argument, to the remote
function send_rproc_cmd {
echo $1 |
ssh $SSH_PROXY $SSH_PORT_SSH $SSH_USER_HOST "bash -s";
if [ $? != 0 ]; then
echo "Failed executing remoteproc command!";
get_core_state;
exit 1;
fi
}
case $ACTION in
"start")
echo "================";
echo "Starting M4 core";
send_rproc_cmd "$REMOTEPROC_START";
get_core_state;
;;
"stop")
echo "================";
echo "Stopping M4 core";
send_rproc_cmd "$REMOTEPROC_STOP";
get_core_state;
;;
"restart")
echo "==================";
echo "Restarting M4 core";
send_rproc_cmd "$REMOTEPROC_RESTART";
get_core_state;
;;
"flash")
flash_firmware;
echo "================";
echo "Starting M4 core";
send_rproc_cmd "$REMOTEPROC_FLASH";
get_core_state;
;;
"state")
get_core_state;
exit;
;;
*)
echo "Unknown command $ACTION";
exit 1;
;;
esac
exit;