Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

not enough memory? or How to create Resource object directly in heap w/o using Stack #1

Closed
sbechet opened this issue Apr 19, 2020 · 9 comments · Fixed by #2
Closed

Comments

@sbechet
Copy link
Contributor

sbechet commented Apr 19, 2020

Hello,

I tried to test your example. Very interesting!

Nevertheless i can't make it work. It seems to be a memory problem :
stm32f103 is 20KB only.

  • 13024 bytes for pixels
  • 1628 bytes for attributes
  • 320 bytes for attribute_definitions
    14972 bytes + some reserved types rust bytes

let mut display = VgaDisplay { create a 14972 bytes stack entry then init::LateResources { seems to do a memcpy at fixed Resources space in memory heap as we can see directly in ghidra :

0800047a 09 f1 36 00     add.w      r0,r9,#0x36
0800047e 29 46           mov        r1,r5
08000480 43 f6 7c 22     movw       r2,#14972
08000484 00 f0 9e f8     bl         compiler_builtins::compiler_builtins::arm::__a   undefined __aeabi_memcpy()

So we have an overlap between heap and stack.

A solution can be not to create stack display.

$ rustup show
Default host: x86_64-unknown-linux-gnu
rustup home:  /home/myhome/rustup

installed toolchains
--------------------

stable-x86_64-unknown-linux-gnu (default)
nightly-x86_64-unknown-linux-gnu

installed targets for active toolchain
--------------------------------------

thumbv7m-none-eabi
x86_64-unknown-linux-gnu

active toolchain
----------------

stable-x86_64-unknown-linux-gnu (default)
rustc 1.42.0 (b8cedc004 2020-03-09)


$ rustup default
stable-x86_64-unknown-linux-gnu (default)

$ rustc --version
rustc 1.42.0 (b8cedc004 2020-03-09)
@abelykh0
Copy link
Owner

abelykh0 commented Apr 19, 2020

Not sure, I tried to build it, it seems to build OK. Maybe this? rust-lang/rust#65391

arm-none-eabi-size -B target\thumbv7m-none-eabi\release\stm32f103-vga-rs

text data bss dec hex filename
9508 0 15000 24508 5fbc target\thumbv7m-none-eabi\release\stm32f103-vga-rs

@sbechet
Copy link
Contributor Author

sbechet commented Apr 20, 2020

Hello Abelykh0,

No problem with compilation this is a dynamic bug with heap/stack overlap. Not sure rust compiler check that.

Memory heap start at 0x20000000 and stack start at 0x20005000.

LateResources pre-allocate memory for display, vga_draw and others at 0x20000004 (14972 bytes len for display, then 24 bytes len for vgadraw then ...) so minimal Resource len is 14996 bytes. as you can calculate : 0x20000004+14996 = 0x20003A98

main() allocate local stack variable between 0x20001544 and 0x20005000 including init() (compiler optimization).

So we have an overlap of 0x20003A98-0x20001544 = 0x2554 bytes.

I suppose this is the problem because in idle() loop i added a small code to blink led to check stm32 HardFault. When i remove Resource display variable to stop overlap: All work fine, my blink is fine else gdb return with an HardFault.

Do you try code with a real-screen recently?

Thank you.

@sbechet
Copy link
Contributor Author

sbechet commented Apr 20, 2020

Hello Abelykh0,

an other information: main() call idle()

idle() allocate 0x58 bytes local stack variable between 0x200014EC and 0x20001544. Exactly the Resource pre-allocated space. So display and render code overwrite idle() local variables => HardFault.

As I said before, space is ok but we must find solution to stop pre-allocate display in stack.

Maybe we can remove Initialize VGA part from init() ?

// Initialize VGA
        let mut display = VgaDisplay {
            pixels : [0; (vga::HSIZE_CHARS * 8 * vga::VSIZE_CHARS) as usize],
            attributes : [0; (vga::HSIZE_CHARS * vga::VSIZE_CHARS) as usize],
            attribute_definitions : [0; 320]
        };

@abelykh0
Copy link
Owner

Thank you for your interest.
I didn't try the code with the real screen. I will try to find time this week to take a look at this, also I will need to migrate to embedded-graphics 0.6.1. By the way, the debug build is taking more memory so it may work as release but not debug (just a thought).

@sbechet
Copy link
Contributor Author

sbechet commented Apr 20, 2020

Yes, debug compilation test is a bad idea, I think debug build can work with the same method (removing or modifying init::LateResources but how...)

@sbechet
Copy link
Contributor Author

sbechet commented Apr 20, 2020

Maybe we can remove Initialize VGA part from init() ?

I tried it but memcpy between stack and heap always here.

@sbechet
Copy link
Contributor Author

sbechet commented Apr 22, 2020

may be a problem related to LLVM optimizations see rust-lang/rust#56333 issue?

@sbechet sbechet changed the title not enough memory? not enough memory? or How to create Resource object directly in heap w/o using Stack Apr 22, 2020
@sbechet
Copy link
Contributor Author

sbechet commented Apr 22, 2020

see #2

@sbechet sbechet closed this as completed Apr 22, 2020
@abelykh0
Copy link
Owner

For your information, I just tried on a real board and the demo is working. Thanks again for your contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants