cr1901 / msp430f5529

Rust Peripheral Access Crate (PAC) for MSP430F5529
Apache License 2.0
2 stars 1 forks source link

Compiling errors #1

Closed Rutherther closed 1 year ago

Rutherther commented 1 year ago

Hello, I am trying to get msp430f5529 working with Rust. I noticed that this crate is not updated to newest version of msp430 and msp430-rt, I would like to change that and I already created a fork and updated the files, but I came across some problems.

First, when I am compiling, I get linking errors saying that there is undefined reference to RTC, to PORT2, to TIMER2_A1 and so on, for all of the interrupts. I've read in msp430-rt that this would happen if device.x is not present. Strangely, these errors go away when I remove "-C" "link-arg=-Tlink.x". But I am not sure whether the program compiled is correct, could not get the LED blinking using blinky example and will have to investigate further to figure out where the error is exactly. (msp430-elf-size is saying that text has 0 bytes, that seems to me that there is no program inside the binary?) EDIT: my bad, this is not strange at all, removing this won't link, so there is nothing to fail then.

Another thing is that if I try to add interrupts to my code, I get

error[E0428]: the name `ssnh8q39h1200890` is defined multiple times
   --> src/main.rs:54:1
    |
30  | #[entry]
    | -------- previous definition of the value `ssnh8q39h1200890` here
...
54  | #[interrupt]
    | ^^^^^^^^^^^^
    | |
    | `ssnh8q39h1200890` redefined here
    | in this procedural macro expansion
    |
   ::: /home/ruther/.cargo/registry/src/index.crates.io-6f17d22bba15001f/msp430-rt-macros-0.3.1/src/lib.rs:417:1
    |
417 | pub fn interrupt(args: TokenStream, input: TokenStream) -> TokenStream {
    | ---------------------------------------------------------------------- in this expansion of `#[interrupt]`
    |
    = note: `ssnh8q39h1200890` must be defined only once in the value namespace of this module

I've also tried compiling msp430g2553 and I don't get any of these errors.

I get these errors even without any changes to this repository, I thought they would go away after updating, but nope.

Any idea where could these problems come from and how to resolve them? If more information is needed, I can provide anything.

cr1901 commented 1 year ago

Please give me the output of rustc -Vv as well as your Cargo.lock file. I've seen the "must be defined only once" error before, but I thought I fixed it.

The idea behind the random mangling is that the entry point and interrupts aren't really reentrant, so don't allow it. This is an implementation detail and may change in the future to be, e.g. supported by marking the entry point and interrupts as unsafe but with deterministic identifiers. This is what cortex-m does.

Rutherther commented 1 year ago

Sure, I've tried one of the newest nightlys as well as an older one (2022-12-12)

[ruther blinky-rust]$ rustc -Vv
rustc 1.72.0-nightly (398fa2187 2023-06-03)
binary: rustc
commit-hash: 398fa2187c88de46c13c142f600064483a563c86
commit-date: 2023-06-03
host: x86_64-unknown-linux-gnu
release: 1.72.0-nightly
LLVM version: 16.0.4

Here is the lock (as well as toml) https://gist.github.com/Rutherther/35c8218c37dca564fa467a57367fe8eb Just a note, this is using the newer version already, located here: https://github.com/Rutherther/msp430f5529/tree/regenerate I've followed instructions from msp_svd for generating the sources, and added only watchdog patch so far (but I am going to add more patches and do a PR after that to both msp_svd and here)

Rutherther commented 1 year ago

Okay, I figured it out. It was completely my fault. In my project, I was referencing msp-rt 0.4.0, but in msp430f5529 I forgot to change the version of msp-rt, so it was referencing an older version. I think the problem was that for entry it was calling one version and for interrupt the other, which meant the count in random_ident is not updated and a second has not passed, leading to same name. After updating msp-rt to 0.4.0 in msp430f5529, the problem disappeared. (isn't there something that could prevent this behavior? some kind of detection of version conflict that would lead to a meaningful error during compilation).

The version mismatch was causing the linking problems as well. After this was resolved, it compiles and the blinky program works correctly.

Sorry for bothering you with this error and thanks for explaining the random ident, I probably wouldn't have figured that out by myself.

I will add a PR today or in few days when I will be happy with all of the patches.

cr1901 commented 1 year ago

(isn't there something that could prevent this behavior? some kind of detection of version conflict that would lead to a meaningful error during compilation).

During linking, there should be a multiple symbol failure due to some symbols being no_mangle if your project brought in multiple versions of msp430-rt. It's not ideal, but it's a better error than "random idents" that stands out as "your crate graph brought in two incompatible versions of the same crate".

Since the "random idents" error reappeared, I would still be interested in the tree of your project (or a minimized version), pointing to the relevant git commit of your msp430f5529 fork (in Cargo.toml using a git dep), so that I can test myself to see if I can at least get the duplicate linker symbol error to appear.

That said, glad you solved the issue and looking forward to your PR (I'm taking a bit of a break from Rust, but I'll at least merge this).

Rutherther commented 1 year ago

Sure, that's not a problem at all since the project is really just a blinky, I wanted to make something easy work first.

When running cargo build with this project, I get the redefinition error. After commenting out #[interrupt] fn PORT1(), I get linker errors

note: /opt/ti/msp430-gcc-9.3.1.11_linux64/bin/../lib/gcc/msp430-elf/9.3.1/../../../../msp430-elf/bin/ld: /home/Documents/Shared/Documents/my_projects/embedded/just_chilling/msp430_playground/blinky-rust/target/msp430-none-elf/debug/deps/libmsp430f5529-002523f8b2a72ae4.rlib(msp430f5529-002523f8b2a72ae4.msp430f5529.3981b44f-cgu.0.rcgu.o):(.vector_table.interrupts+0x52): undefined reference to `RTC'
          /opt/ti/msp430-gcc-9.3.1.11_linux64/bin/../lib/gcc/msp430-elf/9.3.1/../../../../msp430-elf/bin/ld: /home/Documents/Shared/Documents/my_projects/embedded/just_chilling/msp430_playground/blinky-rust/target/msp430-none-elf/debug/deps/libmsp430f5529-002523f8b2a72ae4.rlib(msp430f5529-002523f8b2a72ae4.msp430f5529.3981b44f-cgu.0.rcgu.o):
{all other interrupts follow}

after switching to rev = "b8dc34b8e9d5f7d4385d2486a8a9bd3386fe7733" (only change is msp430-rt version update to 0.4.0), I get no errors when building.

blinky-rust.zip

cr1901 commented 1 year ago

Post-mortem for future-me:

I think the problem was that for entry it was calling one version and for interrupt the other, which meant the count in random_ident is not updated and a second has not passed, leading to same name.

This is a correct description of why the random-ident problem came back. The reason it was calling into one crate for entry and the other crate for interrupt is because the msp430f5529 crate reexports interrupt from msp430-rt v0.3.1, while entry comes from v0.4.0.

This is also why you got the "cannot find interrupt symbols error"; both msp430-rt v0.4.0 and msp430-rt v0.3.1 generate a linker script (link.x). The versions of the linker script differ depending on which features are enabled. If the device feature is enabled, link.x will end with an include(device.x), which the msp430f5529 provides; device.x that provides all the interrupt symbols.

However, in your original code, the two copies of msp430-rt had different features enabled. Specifically, msp430-rt v0.4.0 did not have the device feature enabled. Why would you enable a feature you don't need? Feature union will do it for you :D. Which is exactly what happened when msp430f5529 enabled the device feature for the msp430-rt v0.3.1 copy. Unfortunately, msp430-rt v0.4.0's copy of link.x wins while the linker is searching paths for link.x, and it doesn't include the device.x that provides all the interrupt symbols.

Strangely, these errors go away when I remove "-C" "link-arg=-Tlink.x"

GNU ld isn't great at telling you: "Congrats, you created an empty binary!" :). It just does it happily.