Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions tools/flaskIfc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
This tool provides you an interface to Tsavorite FPGA via a serial console

The tool consists of following files

.
├── flaskCommon.py << Common code but currently not used
├── flaskIfc.py << Browser based console interface to TSI device
├── flaskXterm.py << Browser based terminal emulation
├── README.md << Readme file
└── serial_script.py << File with serial interface to console


The command to run to run the service on FPGA machine is
```
flask -A flaskIfc.py --debug run --port 5000
```

This command runs a webserver at port number 500

The curl command to connect to this server and communicate is as follows as
an example

```
curl "http://localhost:5000/serial?command=cd+%20/usr/bin/tsi/v0.1.1.tsv31_06_06_2025/bin/;./run_platform_test.sh"
```

In the above command the command being run is

```
cd /usr/bin/tsi/v0.1.1.tsv31_06_06_2025/bin
./run_platform_test.sh
```

You can also get full fledged Terminal within a browser by running following

```
flask -A flaskXterm.py --debug run --port 5000
```

You can connect to this flaskTerm by doing as follows

```
http://127.0.0.1:5000/terminal
```


85 changes: 85 additions & 0 deletions tools/flaskIfc/flaskCommon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@

from flask import Flask
from flask_terminal import terminal_blueprint, configure_logger
from flask import Flask, render_template, request
import serial


app = Flask(__name__)
app.logger = configure_logger('flask_terminal')

app.config['SECRET_KEY'] = 'your_secret_key_here'


@app.route('/ping')
def ping():
app.logger.info("Accessed /ping route")
try:
app.logger.info("Successfully returned 'pong'")
return 'pong', 200
except Exception as e:
app.logger.error(f"Error in ping route: {e}", exc_info=True)
return "An error occurred", 500

####
## IMPLEMENT SOME SORT OF SECURITY
## Around your application, below is an example
###
def is_authenticated():
"""Check if the user is authenticated based on a token stored in the session."""
# Example logic for checking if a user is authenticated
return 'user_token' in session and session['user_token'] == 'your_secure_token'

#@terminal_blueprint.before_request
#def before_request_func():
# if not is_authenticated():
# Redirect to login page or return an error
# current_app.logger.info("User not authenticated, redirecting to login.")
# return redirect('/login') # Adjusted to use a direct path


# Register the terminal blueprint
#app.register_blueprint(terminal_blueprint, url_prefix='/terminal')

#if __name__ == '__main__':
# app.run(port=8080)



try:
ser = serial.Serial('/dev/ttyUSB3', 921600) # Replace /dev/ttyUSB3 with your port and baud rate
except serial.SerialException as e:
print(f"Error opening serial port: {e}")
ser = None # Handle case where serial port cannot be opened

@app.route('/send', methods=['POST'])
def send_data():
if ser is None:
return "Serial port not available", 500
data = request.form['data'] # Get data from the form
try:
ser.write(data.encode()) # Convert to bytes and send
return 'Data sent successfully'
except serial.SerialException as e:
return f"Error writing to serial port: {e}", 500


@app.route('/receive')
def receive_data():
if ser is None:
return "Serial port not available", 500
try:
if ser.in_waiting > 0:
data = ser.readline().decode().strip() # Read and decode
return data
else:
return "No data available"
except serial.SerialException as e:
return f"Error reading from serial port: {e}", 500

# Register the terminal blueprint
#app.register_blueprint(terminal_blueprint, url_prefix='/terminal')

if __name__ == '__main__':
app.run(port=8080)

32 changes: 32 additions & 0 deletions tools/flaskIfc/flaskIfc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from flask import Flask, request
import subprocess

app = Flask(__name__)

@app.route('/serial', methods=['GET'])
def serial_command():
# Currently the port is hard coded to /dev/ttyUSB3 but can be parameterized
port = '/dev/ttyUSB3'
#port = request.args.get('port')

# Currently the baudrate is hard coded to 921600 but can be parameterized
#baudrate = request.args.get('baudrate')
baudrate = '921600'


# Parse the command and send it to serial.py
command = request.args.get('command')

#if not all([port, baudrate, command]):
if not all([command]):
return "Missing parameters", 400

try:
result = subprocess.run(['python3', 'serial_script.py', port, baudrate, command], capture_output=True, text=True, check=True)
return result.stdout.strip(), 200
except subprocess.CalledProcessError as e:
return f"Error executing script: {e.stderr}", 500


if __name__ == '__main__':
app.run(debug=True, port=5000)
43 changes: 43 additions & 0 deletions tools/flaskIfc/flaskXterm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

from flask import Flask
from flask_terminal import terminal_blueprint, configure_logger


app = Flask(__name__)
app.logger = configure_logger('flask_terminal')

app.config['SECRET_KEY'] = 'your_secret_key_here'


@app.route('/ping')
def ping():
app.logger.info("Accessed /ping route")
try:
app.logger.info("Successfully returned 'pong'")
return 'pong', 200
except Exception as e:
app.logger.error(f"Error in ping route: {e}", exc_info=True)
return "An error occurred", 500

####
## IMPLEMENT SOME SORT OF SECURITY
## Around your application, below is an example
###
def is_authenticated():
"""Check if the user is authenticated based on a token stored in the session."""
# Example logic for checking if a user is authenticated
return 'user_token' in session and session['user_token'] == 'your_secure_token'

#@terminal_blueprint.before_request
#def before_request_func():
# if not is_authenticated():
# Redirect to login page or return an error
# current_app.logger.info("User not authenticated, redirecting to login.")
# return redirect('/login') # Adjusted to use a direct path


# Register the terminal blueprint
app.register_blueprint(terminal_blueprint, url_prefix='/terminal')

if __name__ == '__main__':
app.run(port=8080)
44 changes: 44 additions & 0 deletions tools/flaskIfc/serial_script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import serial
import sys

def send_serial_command(port, baudrate, command):
try:
# Open the serial port with 1 second timeout
ser = serial.Serial(port, baudrate, timeout=1)

ser.write(command.encode()) # Encode command to bytes
ser.write('\n'.encode()) # Encode command to bytes

# Wait to read the serial port
data = '\0'
while True:
try:
line = ser.readline()
if line: # Check if line is not empty
data += (line.decode('utf-8').strip()) # Decode and strip to remove extra chars
else:
break # Exit loop if no data is received
except serial.SerialException as e:
ser.close()
return (f"Error reading from serial port: {e}")
except KeyboardInterrupt:
ser.close()
return ("Program interrupted by user")
ser.close()
return data

except serial.SerialException as e:
ser.close()
return f"Error: {e}"

# This script can be run in standalone as well
if __name__ == "__main__":
if len(sys.argv) < 4:
print("Usage: python script.py <port> <baudrate> <command>")
sys.exit(1)

port = sys.argv[1]
baudrate = int(sys.argv[2])
command = sys.argv[3]
response = send_serial_command(port, baudrate, command)
print(response)