rust-embedded / cortex-m-rt

Minimal startup / runtime for Cortex-M microcontrollers
https://rust-embedded.github.io/cortex-m-rt/
Apache License 2.0
358 stars 85 forks source link

undefined reference to `__sheap' #298

Closed huntc closed 3 years ago

huntc commented 4 years ago

When linking my library with the following:

    unsafe { ALLOCATOR.init(cortex_m_rt::heap_start() as usize, HEAP_SIZE_BYTES) }

I receive a:

undefined reference to `__sheap'

I didn't find a documented means by which this symbol is declared. Any pointers? I'm linking my Rust library to an nRF52 C based project. Thanks.

thalesfragoso commented 4 years ago

Do you have this line on your .cargo/config ?

https://github.com/rust-embedded/cortex-m-quickstart/blob/3cbcb9956acd638c0fb864937770f51d663fba6f/.cargo/config#L18

huntc commented 4 years ago

I don’t have that line. Also, I’m using the gcc linker so I might have to read up on those options. Is there a section in the doc discussing the need for these options? Happy to PR the doc once I learn more if not. Thanks.

On 15 Oct 2020, at 00:46, Thales notifications@github.com wrote:

 Do you have this line on your .cargo/config ?

https://github.com/rust-embedded/cortex-m-quickstart/blob/3cbcb9956acd638c0fb864937770f51d663fba6f/.cargo/config#L18

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

huntc commented 4 years ago

Unfortunately, that line, or a combo of the other lines doesn’t help to resolve the symbol.

On 15 Oct 2020, at 12:46 am, Thales notifications@github.com wrote:

Do you have this line on your .cargo/config ?

https://github.com/rust-embedded/cortex-m-quickstart/blob/3cbcb9956acd638c0fb864937770f51d663fba6f/.cargo/config#L18 https://github.com/rust-embedded/cortex-m-quickstart/blob/3cbcb9956acd638c0fb864937770f51d663fba6f/.cargo/config#L18 — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rust-embedded/cortex-m-rt/issues/298#issuecomment-708412382, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFJU3JHI4PBXHBPLIUVYSLSKWTSZANCNFSM4SQFX3BA.

adamgreig commented 4 years ago

__sheap is defined in the linker script here; if you're not getting it it probably means the linker script is not being included. Regardless of gcc or lld linker, you need to pass -Tlink.x somehow or other, which is what that line in .cargo/config does. If you have a RUSTFLAGS environment variable set, it will override .cargo/config, or perhaps you're specifying another linker script somehow?

huntc commented 4 years ago

Thanks. I’m getting the hang of this now. My situation is that I’ve got another nRF52 SDK C based project actually linking this Rust-based library statically. The nRF project is responsible for doing the linking and has a linker script already. So what’s the approach here… do I need to include just that one symbol from link.x, or am I looking to somehow merge link.x with my existing linker script?

On 15 Oct 2020, at 10:27 am, Adam Greig notifications@github.com wrote:

__sheap is defined in the linker script here https://github.com/rust-embedded/cortex-m-rt/blob/master/link.x.in#L162; if you're not getting it it probably means the linker script is not being included. Regardless of gcc or lld linker, you need to pass -Tlink.x somehow or other, which is what that line in .cargo/config does. If you have a RUSTFLAGS environment variable set, it will override .cargo/config, or perhaps you're specifying another linker script somehow?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rust-embedded/cortex-m-rt/issues/298#issuecomment-708713052, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFJU3JH6OMWK7EVZHF6DI3SKYXWXANCNFSM4SQFX3BA.

huntc commented 4 years ago

It occurs to me that I might not even need the cortex-m-rt library given that I’m calling Rust as a static lib and my nRF52 project has effectively set up its runtime. Obviously, I’ll need to take care of setting up an allocator etc… or am I in for a world of pain assuming an approach without cortex-m-rt?

On 15 Oct 2020, at 10:46 am, Christopher Hunt huntchr@gmail.com wrote:

Thanks. I’m getting the hang of this now. My situation is that I’ve got another nRF52 SDK C based project actually linking this Rust-based library statically. The nRF project is responsible for doing the linking and has a linker script already. So what’s the approach here… do I need to include just that one symbol from link.x, or am I looking to somehow merge link.x with my existing linker script?

On 15 Oct 2020, at 10:27 am, Adam Greig <notifications@github.com mailto:notifications@github.com> wrote:

__sheap is defined in the linker script here https://github.com/rust-embedded/cortex-m-rt/blob/master/link.x.in#L162; if you're not getting it it probably means the linker script is not being included. Regardless of gcc or lld linker, you need to pass -Tlink.x somehow or other, which is what that line in .cargo/config does. If you have a RUSTFLAGS environment variable set, it will override .cargo/config, or perhaps you're specifying another linker script somehow?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rust-embedded/cortex-m-rt/issues/298#issuecomment-708713052, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFJU3JH6OMWK7EVZHF6DI3SKYXWXANCNFSM4SQFX3BA.

hannobraun commented 4 years ago

I have little experience with such C/Rust integrations, but I'd assume you're in a world of pain if you try to use cortex-m-rt and have some C-based runtime. cortex-m-rt will set up the vector table, do all the setup needed before entering main (copying/zeroing memory), etc. Which is all stuff that your C runtime presumable already does.

It's required for Rust applications. For a Rust library you only need the cortex-m crate, which will provide you some APIs, but won't interfere with another program that calls into your Rust code.

Sympatron commented 4 years ago

But I suppose @huntc would still have to define a global allocator if the Rust library depends on it. Is there some allocator one could use that uses malloc and free provided by the C runtime? Otherwise you would have to define 2 separate heaps, which is probably not desirable.

huntc commented 4 years ago

Thanks for the replies, everyone. I'll keep this issue open as I'd like to ultimately raise a PR to improve the doc around calling static libs in an embedded context.

Meanwhile, I did provide my own allocator and things appear to work (although I'm having difficulty getting tests to work). Here's the gist of it - happy for feedback on the gist as I'm a Rust newbie:

https://gist.github.com/huntc/ab9a505683647aac7bccd2df0fc75f9e)

Thanks!

adamgreig commented 3 years ago

I'm closing this issue while doing some backlog triage; please feel free to re-open if you do get back to documenting calling static libs in an embedded context, that would definitely be useful! Perhaps it could go into the Rust with C chapter of the book?