Skip to content

Commit

Permalink
Ner build fixups (#180)
Browse files Browse the repository at this point in the history
* wsl flash, serial work with confluence docs

* working debug

* fixup

* works on linux

* works again on windows

* flash and debug ftdi works on windows
  • Loading branch information
jr1221 authored Oct 15, 2024
1 parent ea57165 commit 357727f
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 42 deletions.
12 changes: 6 additions & 6 deletions ftdi_flash.cfg
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
adapter driver ftdi
ftdi vid_pid 0x0403 0x6010
ftdi_vid_pid 0x0403 0x6010

# Initial state: Assuming 0x0008 doesn't interfere with your setup
# and 0x000b sets the required initial states for your other signals.
ftdi layout_init 0x0008 0x000b
ftdi_layout_init 0x0008 0x000b

ftdi layout_signal LED_Tx -data 0x00F0 -oe 0x00F0
ftdi layout_signal LED_Rx -data 0x00F0 -oe 0x00F0
ftdi_layout_signal LED_Tx -data 0x00F0 -oe 0x00F0
ftdi_layout_signal LED_Rx -data 0x00F0 -oe 0x00F0

# Configure GPIOL0 (ADBUS4) as nSRST, assuming active low reset
# Setting `-data` for active low, `-oe` to enable output.
# If tri-state isn't supported, this configures the pin as push-pull.
ftdi layout_signal nSRST -data 0x0010 -oe 0x0010
ftdi_layout_signal nSRST -data 0x0010 -oe 0x0010

transport select jtag
transport select jtag
104 changes: 85 additions & 19 deletions ner_environment/build_system/build_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@
# To see a list of available commands and additional configuration options, run `ner --help`
# ==============================================================================
import argparse
import platform
import subprocess
import sys
import os
import glob
import time

# custom modules for functinality that is too large to be included in this script directly
from .miniterm import main as miniterm
Expand All @@ -31,7 +34,7 @@ def build(args):
command = ["docker", "compose", "run", "--rm", "ner-gcc-arm", "make", "clean"]
else:
command = ["docker", "compose", "run", "--rm", "ner-gcc-arm", "make", f"-j{os.cpu_count()}"]
run_command(command)
run_command(command, stream_output=True)

# ==============================================================================
# Clang command
Expand All @@ -55,7 +58,53 @@ def clang(args):
# ==============================================================================

def debug(args):
pass

command = []
#if args.docker:
# print("Dockerized openocd unsupported for gdb")
# sys.exit(1)

command = command + ["openocd"]

current_directory = os.getcwd()
if args.ftdi:
ftdi_path = os.path.join(current_directory, "Drivers", "Embedded-Base", "ftdi_flash.cfg")
command = command + ["-f", ftdi_path]
else:
command = command + ["-f", "interface/cmsis-dap.cfg"]

build_directory = os.path.join("build", "*.elf")
elf_files = glob.glob(build_directory)
if not elf_files:
print("Error: No ELF file found in ./build/")
sys.exit(1)

elf_file = os.path.basename(os.path.normpath(elf_files[0])) # Take the first ELF file found
print(f"Found ELF file: {elf_file}")

halt_command = command + ["-f", "flash.cfg", "-f", os.path.join(current_directory, "Drivers", "Embedded-Base", "openocd.cfg"),
"-c", "init", "-c", "reset halt"]
ocd = subprocess.Popen(halt_command)
time.sleep(1)

# for some reason the host docker internal thing is broken on linux despite compose being set correctly, hence this hack
gdb_uri = "host.docker.internal"
if platform.system() == "Linux" and is_wsl() == 0:
gdb_uri = "localhost"

send_command = ["docker", "compose", "run", "--rm", "ner-gcc-arm", "arm-none-eabi-gdb", f"/home/app/build/{elf_file}", "-ex", f"target extended-remote {gdb_uri}:3333"]

subprocess.run(send_command)

# make terminal clearer
time.sleep(4)
print("\nKilling openocd...")
ocd.terminate()
time.sleep(1)





# ==============================================================================
# Flash command
Expand All @@ -64,6 +113,10 @@ def debug(args):
def flash(args):

command = []
if args.docker and args.ftdi:
print("Cannot flash ftdi from docker")
sys.exit(1)

if args.docker:
command = ["docker", "compose", "run", "--rm", "ner-gcc-arm"]

Expand All @@ -75,8 +128,18 @@ def flash(args):
command = command + ["-f", ftdi_path]
else:
command = command + ["-f", "interface/cmsis-dap.cfg"]

command = command + ["-f", "flash.cfg"]


build_directory = os.path.join("build", "*.elf")
elf_files = glob.glob(build_directory)
if not elf_files:
print("Error: No ELF file found in ./build/")
sys.exit(1)

elf_file = elf_files[0] # Take the first ELF file found
print(f"Found ELF file: {elf_file}")

command = command + ["-f", "flash.cfg", "-c", f"program {elf_file} verify reset exit"]

run_command(command, stream_output=True)

Expand Down Expand Up @@ -206,6 +269,11 @@ def main():
# ==============================================================================

parser_debug = subparsers.add_parser('debug', help="Start a debug session")
parser_debug.add_argument(
'--ftdi',
action="store_true",
help="Set this flag if the device uses an FTDI chip",
)
parser_debug.set_defaults(func=debug)

# ==============================================================================
Expand Down Expand Up @@ -257,21 +325,7 @@ def run_command(command, stream_output=False, exit_on_fail=True):

if stream_output:

process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

# Stream the output in real-time
while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break
if output:
print(output.strip())

# Capture any remaining output
stderr_output = process.stderr.read()
if stderr_output:
print(stderr_output, file=sys.stderr)

process = subprocess.Popen(command, text=True)

returncode = process.wait()
if returncode != 0:
Expand All @@ -294,6 +348,18 @@ def disconnect_usbip():
command = ["sudo", "usbip", "detach", "-p", "0"]
run_command(command, exit_on_fail=False)

def is_wsl(v: str = platform.uname().release) -> int:
"""
detects if Python is running in WSL
"""

if v.endswith("-Microsoft"):
return 1
elif v.endswith("microsoft-standard-WSL2"):
return 2

return 0


if __name__ == "__main__":
main()
Expand Down
40 changes: 23 additions & 17 deletions ner_environment/ner_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@
except ImportError:
distro = None

def is_wsl(v: str = platform.uname().release) -> int:
"""
detects if Python is running in WSL
"""

if v.endswith("-Microsoft"):
return 1
elif v.endswith("microsoft-standard-WSL2"):
return 2

return 0

def run_command(command, check=True, shell=False):
try:
result = subprocess.run(command, check=check, shell=shell, text=True, capture_output=True)
Expand All @@ -19,22 +31,20 @@ def run_command(command, check=True, shell=False):
print(f"Command failed: {e.cmd}\nReturn code: {e.returncode}\nOutput: {e.output}\nError: {e.stderr}", file=sys.stderr)
sys.exit(1)

def check_docker_and_rust():
print("This script requires Docker and Rust to be installed.")
answer = input("Do you have Docker and Rust installed? (yes/no): ").strip().lower()
def check_docker():
print("This script requires Docker to be installed.")
answer = input("Do you have Docker installed? (yes/no): ").strip().lower()
if 'y' not in answer:
sys.exit(1)

os_type = platform.system()
if os_type == 'Windows':
print("Windows OS detected. If on windows, you must be using bash (included with git), instead of cmd or powershell")
answer = input("Are you using bash? (yes/no): ").strip().lower()
if 'y' not in answer:
sys.exit(1)
print("Windows OS detected. If on windows, you must be using WSL. Revist the docs and reinstall. Sorry")
sys.exit(1)

def docker_pull(image_url):
os_type = platform.system()
if os_type=='Windows' or os_type == 'Darwin':
if is_wsl() or os_type == 'Darwin':
print("Please open the Docker Desktop application before proceeding")
answer =input("Is the Docker Desktop app running? (yes/no)")
print("Pulling Docker image...")
Expand Down Expand Up @@ -70,11 +80,7 @@ def install_precommit(venv_python):
def install_openocd():
os_type = platform.system()
try:
if os_type == "Windows":
print("Please install OpenOCD manually on Windows. You can download it from https://gnutoolchains.com/arm-eabi/openocd/")
print("You will need to unzip the downloaded file and run the exe file.")
return
elif os_type == "Darwin":
if os_type == "Darwin":
run_command(["brew", "install", "openocd"])

elif os_type == "Linux":
Expand Down Expand Up @@ -113,8 +119,8 @@ def main():
print("Everyone's system is different, and if you already have something installed, or know exactly")
print("what you are doing, feel free to manually go about this as needed.")

# Step 0: Check for Docker and Rust
check_docker_and_rust()
# Step 0: Check for Docker
check_docker()

# Step 1: pull image
answer = input("Would you like to pull the docker image? (yes/no)")
Expand All @@ -137,7 +143,7 @@ def main():
answer = input("Would you like to install all python packages in the venv? (yes/no)")
if 'y' in answer:
# Use the venv's Python
venv_python = os.path.join(venv_path, 'Scripts', 'python') if os_type == "Windows" else os.path.join(venv_path, 'bin', 'python')
venv_python = os.path.join(venv_path, 'bin', 'python')

# Step 4: run setup.py (installs requirements and entry points)
run_setup(venv_python)
Expand All @@ -151,7 +157,7 @@ def main():
install_openocd()

# Step 6: Install usbip if on Linux
if os_type == "Linux":
if os_type == "Linux" and is_wsl() == 0:
answer = input("Would you like to install usbip? (yes/no)")
if 'y' in answer:
install_usbip()
Expand Down
7 changes: 7 additions & 0 deletions openocd.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
$_TARGETNAME configure -event gdb-detach {
reset run
shutdown
}

init
reset halt

0 comments on commit 357727f

Please sign in to comment.