discovery icon indicating copy to clipboard operation
discovery copied to clipboard

3,4 Can't Verify Install - Failed Attaching To Target

Open datsimps opened this issue 2 years ago • 5 comments

I have tried verifying the install a couple dozen times, in hopes it was some witch craft preventing me from attaching to target. I am using WSL which you need to bind the usb device to the WSL, check Make sure the usb has the correct permissions inside the WSL, check. Make sure the probes can be found. check. I come across this error to no avail: Embed Error The toml is the correct chip version but I have a sneaking suspicion something about the file isn't correct. Embed toml

I would appreciate any and all help on the matter. Thank you.

datsimps avatar Jan 03 '24 14:01 datsimps

TLDR SOLUTION : unset RUSTFLAGS to completely remove it from your environmental variables. unset RUSTFLAGS

OR assign RUSTFLAGS manually instead of config.toml
RUSTFLAGS="-C link-arg=-Tlink.x" cargo embed

Hi I had the same issue on linux and I found out the problem after 2 days of debugging. I came to report it but I saw your open issue.

This is not a problem connecting to the USB device. The issue boils down to the elf file not being correct and probe-rs not finding anything to load onto the microcontroller. This is a BUG the actual linker is not using rustflags defined in the config.toml file in LINUX only (it is working fine in windows with same code and rustc version). I ran the same project in linux and windows and displayed the linker arguments using cargo rustc -- --print=link-args my config.toml inside project's .cargo folder contains the following.

[target.'cfg(all(target_arch = "arm", target_os = "none"))']
rustflags = ["-C", "link-arg=-Tlink.x"]

[build]
target = "thumbv7em-none-eabihf"

In windows I got the following linker args at the end of the linker command ... target\\thumbv7em-none-eabihf\\debug\\deps\\i2c-4754388f49bb4437" "--gc-sections" "-Tlink.x"

In linux this is what I get at the end of my linker args

... target/thumbv7em-none-eabihf/debug/deps/i2c-ce1445d509cca9ef" "--gc-sections"

I checked the output in linux

readelf -l ../../target/thumbv7em-none-eabihf/debug/i2c

Elf file type is EXEC (Executable file)
Entry point 0x0
There are 3 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x00010034 0x00010034 0x00060 0x00060 R   0x4
  LOAD           0x000000 0x00010000 0x00010000 0x00094 0x00094 R   0x10000
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0

 Section to Segment mapping:
  Segment Sections...
   00     
   01     
   02     

and In windows

readelf.exe -l ..\..\target\thumbv7em-none-eabihf\debug\i2c    

Elf file type is EXEC (Executable file)
Entry point 0x101
There are 5 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x010000 0x00000000 0x00000000 0x00100 0x00100 R   0x10000
  LOAD           0x010100 0x00000100 0x00000100 0x0aedc 0x0aedc R E 0x10000
  LOAD           0x01afdc 0x0000afdc 0x0000afdc 0x03054 0x03054 R   0x10000
  LOAD           0x020000 0x20000000 0x20000000 0x00000 0x00444 RW  0x10000
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0

 Section to Segment mapping:
  Segment Sections...
   00     .vector_table
   01     .text
   02     .rodata
   03     .bss
   04

WORKAROUND: Manually assign RUSTFLAGS before running the build command RUSTFLAGS="-C link-arg=-Tlink.x" cargo rustc -- --print=link-args

This displayed the correct linker arguments in linux and probe-rs worked great. ......target/thumbv7em-none-eabihf/debug/deps/i2c-9061183c020b57e6" "--gc-sections" "-Tlink.x"

rustup -V
rustup 1.27.1 
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active `rustc` version is `rustc 1.87.0 (17067e9ac 2025-05-09)`


cargo embed -V
cargo embed 0.29.0

[UPDATE] my environmental variables had RUSTFLAGS set to empty and that was overriding my config.toml file. I needed to remove it for everything to work as expected. unset RUSTFLAGS

ajundi avatar May 25 '25 17:05 ajundi

Much appreciated information! I wish I could post this to the README.md, for everyone else. Very informative and thorough, keep spreading the word lol

datsimps avatar May 25 '25 18:05 datsimps

Seems the main problem is that my RUSTFLAGS env variable is Set as empty. This seems to be overriding rust flag in config file.

Needed to run unset RUSTFLAGS to completely remove it.

ajundi avatar May 26 '25 10:05 ajundi

How is RUSTFLAGS getting set in the first place? That is super-weird, and should not be happening.

BartMassey avatar May 29 '25 15:05 BartMassey

How is RUSTFLAGS getting set in the first place? That is super-weird, and should not be happening.

My bad I was creating a nix shell file and i was combining configurations of others that had "RUST_FLAGS" defined and I didn't notice it. I also didn't know which one takes priority. I commented the section out and unset it in the shell hook to be sure. If anyone else is using Nix then I would appriciate if they can test out the nix file below.

{pkgs ? import <nixpkgs> {}}: let
  libPath = with pkgs;
    lib.makeLibraryPath [
    ];
in
  pkgs.mkShell rec {
    libraries = with pkgs; [
    ];

    buildInputs = with pkgs; [
      rustup
      pkg-config
      systemd # give us access to libudev.pc for cargo install --locked probe-rs-tools
      openocd
      gcc-arm-embedded-13 # This is needed for arm gdb debugger. Not needed for compiling 
      vscodium
      jq
      nixd
      bashInteractive
    ];
    OPENOCDPATH="${pkgs.openocd}";
    RUST_BACKTRACE = "full";
    RUSTC_CHANNEL = "stable"; #"stable", "nightly" , "beta" , version
    LD_LIBRARY_PATH = libPath; 
    # RUST_SRC_PATH = "${pkgs.rust.packages.${RUSTC_CHANNEL}.rustPlatform.rustLibSrc}"; # since I am not using a pure nix method I shouldn't set this manually and let the defaults using RUSTUP_HOME take over this one. 
    RUST_ANALYZER_PATH = "${pkgs.rust-analyzer-unwrapped}/bin/rust-analyzer";
    
    # export LD_LIBRARY_PATH=${pkgs.lib.makeLibraryPath libraries}:$LD_LIBRARY_PATH
    # https://github.com/rust-lang/rust-bindgen#environment-variables
    shellHook = ''
      # rustup-initialization
      rustup default $RUSTC_CHANNEL # First set a default channel
      rustup component add rust-src --toolchain $RUSTC_CHANNEL-x86_64-unknown-linux-gnu
      rustup target add thumbv7em-none-eabihf
      rustup component add llvm-tools
      rustup component add rust-analyzer
      cargo install cargo-binutils
      cargo size --version
      cargo install --locked probe-rs-tools
      cargo embed --version
      # Create the directory if it doesn't exist
      mkdir -p ~/.local/share/bash-completion/completions

      # Generate the completion script only if the file doesn't exist
      if [ ! -f ~/.local/share/bash-completion/completions/rustup ]; then
        rustup completions bash > ~/.local/share/bash-completion/completions/rustup
      fi
      # Generate the completion script only if the file doesn't exist
      if [ ! -f ~/.local/share/bash-completion/completions/cargo ]; then
        rustup completions bash cargo > ~/.local/share/bash-completion/completions/cargo
      fi

      # Path to the settings.json file
      SETTINGS_FILE="$HOME/.config/VSCodium/User/settings.json"
      SETTINGS_FOLDER="$HOME/.config/VSCodium/User"
      # Ensure the .vscode directory exists
      if [ ! -d "$SETTINGS_FOLDER" ]; then
        echo "The $SETTINGS_FOLDER directory does not exist. Creating it..."
        mkdir -p $SETTINGS_FOLDER
      fi

      # Ensure the settings.json file exists
      if [ ! -f "$SETTINGS_FILE" ]; then
        echo "The "$SETTINGS_FILE" file does not exist. Creating it..."
        echo "{}" > "$SETTINGS_FILE"
      fi

      # The new value for rust-analyzer.server.path
      NEW_PATH="rust-analyzer"

      # Check if rust-analyzer.server.path exists and replace it
      if grep -q '"rust-analyzer.server.path"' "$SETTINGS_FILE"; then
        # Use sed to replace the existing line with the new path
        sed -i''' -e "s#\"rust-analyzer.server.path\": \".*\"#\"rust-analyzer.server.path\": \"$NEW_PATH\"#" "$SETTINGS_FILE"
        echo "Replaced rust-analyzer.server.path with $NEW_PATH"
      else
        sed -i''' '/^[[:space:]]*$/d' "$SETTINGS_FILE"
        echo "Removed empty lines from $SETTINGS_FILE"
        # If the key doesn't exist, add it at the end of the JSON file
        # We use jq to safely insert it into the JSON file
        #sed -i''' -e "\$s/{}/{\n  \"rust-analyzer.server.path\": \"$NEW_PATH\"\n}/" "$SETTINGS_FILE"
        sed -i''' -e '$s/}$/\n  "rust-analyzer.server.path": "'"$NEW_PATH"'",\n}/' "$SETTINGS_FILE"
        echo "Added rust-analyzer.server.path with value $NEW_PATH to $SETTINGS_FILE"
      fi

      sed -i''' '/^[[:space:]]*$/d' "$SETTINGS_FILE"
      echo "Removed empty lines from $SETTINGS_FILE"
      export CARGO_HOME=''${CARGO_HOME:-~/.cargo}
      export RUSTUP_HOME=''${RUSTUP_HOME:-~/.rustup}
      export PATH=$PATH:''${CARGO_HOME}/bin
      export SHELL=${pkgs.bashInteractive}/bin/bash
      unset RUSTFLAGS
      codium .
    '';
    # Add precompiled library to rustc search path
    # RUSTFLAGS = builtins.map (a: ''-L ${a}/lib'') [
    #   # add libraries here (e.g. pkgs.libvmi)
    # ];

    # Add glibc, clang, glib, and other headers to bindgen search path
    BINDGEN_EXTRA_CLANG_ARGS =
      # Includes normal include path
      (builtins.map (a: ''-I"${a}/include"'') [
        # add dev libraries here (e.g. pkgs.libvmi.dev)
      ])
      # Includes with special directory paths
      ++ [
      ];
  }

ajundi avatar May 29 '25 17:05 ajundi