rust-embedded / cortex-m-rt Goto Github PK
View Code? Open in Web Editor NEWMinimal startup / runtime for Cortex-M microcontrollers
Home Page: https://rust-embedded.github.io/cortex-m-rt/
License: Apache License 2.0
Minimal startup / runtime for Cortex-M microcontrollers
Home Page: https://rust-embedded.github.io/cortex-m-rt/
License: Apache License 2.0
I am trying to compile programs for nRF51822 using https://github.com/japaric/cortex-m-quickstart
Not sure if copying the file memory.x
from https://github.com/japaric/cortex-m-template is a good start though.
Repro @ krk/nrf51822-env@f887f25
Device crate @ https://github.com/krk/nrf51822
P:\nrf51822-quickstart>xargo build --example hello
Compiling nrf51822-quickstart v0.1.0 (file:///P:/nrf51822-quickstart)
error: linking with `lld` failed: exit code: 1
|
= note: "lld" "-flavor" "gnu" "-L" "C:\\Users\\user\\.xargo\\lib\\rustlib\\thumbv6m-none-eabi\\lib" "P:\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\examples\\hello-5a42319867414f41.16i0u6jlhoj1fwbo.rcgu.o" "P:\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\examples\\hello-5a42319867414f41.16u6js6g0l3k1ic6.rcgu.o" "P:\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\examples\\hello-5a42319867414f41.1ljmpmvy3lddvhvj.rcgu.o" "P:\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\examples\\hello-5a42319867414f41.1y16o1qfye96o7m0.rcgu.o" "P:\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\examples\\hello-5a42319867414f41.32d6pip9z2306v3e.rcgu.o" "P:\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\examples\\hello-5a42319867414f41.4xq48u46a1pwiqn7.rcgu.o" "P:\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\examples\\hello-5a42319867414f41.544l4wfz89vbhoea.rcgu.o" "P:\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\examples\\hello-5a42319867414f41.81jpvh8cn5k8ng8.rcgu.o" "P:\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\examples\\hello-5a42319867414f41.8xzrsc1ux72v29j.rcgu.o" "P:\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\examples\\hello-5a42319867414f41.98g0d9x8aw3akpe.rcgu.o" "-o" "P:\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\examples\\hello-5a42319867414f41" "--gc-sections" "-L" "P:\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\deps" "-L" "P:\\nrf51822-quickstart\\target\\debug\\deps" "-L" "P:\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\build\\nrf51822-quickstart-05171852e03d71bb\\out" "-L" "C:\\Users\\user\\OneDrive\\projects\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\build\\cortex-m-rt-ae6f5d14da7c895c\\out" "-L" "C:\\Users\\user\\.xargo\\lib\\rustlib\\thumbv6m-none-eabi\\lib" "--start-group" "-Bstatic" "C:\\Users\\user\\OneDrive\\projects\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\deps\\libpanic_abort-2f330f43ad42d1b1.rlib" "C:\\Users\\user\\OneDrive\\projects\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\deps\\libcortex_m_semihosting-c9f6894640cb30d5.rlib" "C:\\Users\\user\\OneDrive\\projects\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\deps\\libcortex_m_rt-dc19072626600a25.rlib" "C:\\Users\\user\\OneDrive\\projects\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\deps\\libr0-6961cc14348fbbc6.rlib" "C:\\Users\\user\\OneDrive\\projects\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\deps\\libcortex_m-a8e157e993bff1ad.rlib" "C:\\Users\\user\\OneDrive\\projects\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\deps\\libcortex_m-4b0a49094f3979b4.rlib" "C:\\Users\\user\\OneDrive\\projects\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\deps\\libvolatile_register-76b3bd280dc6877b.rlib" "C:\\Users\\user\\OneDrive\\projects\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\deps\\libvcell-98265b6ccf4f897d.rlib" "C:\\Users\\user\\OneDrive\\projects\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\deps\\libuntagged_option-30e8fbf04007ec6d.rlib" "C:\\Users\\user\\OneDrive\\projects\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\deps\\libbare_metal-15f225b5f3f522d6.rlib" "C:\\Users\\user\\OneDrive\\projects\\nrf51822-quickstart\\target\\thumbv6m-none-eabi\\debug\\deps\\libaligned-d04a39feab752f54.rlib" "C:\\Users\\user\\.xargo\\lib\\rustlib\\thumbv6m-none-eabi\\lib\\libcore-a94023b3d447d900.rlib" "--end-group" "C:\\Users\\user\\.xargo\\lib\\rustlib\\thumbv6m-none-eabi\\lib\\libcompiler_builtins-e4b6cc3e4adb13df.rlib" "-Tlink.x" "-Bdynamic"
= note: C:\Users\user\.xargo\lib\rustlib\x86_64-pc-windows-msvc\bin\lld.exe: warning: lld may use movt/movw, no object with architecture supporting feature detected.
C:\Users\user\.xargo\lib\rustlib\x86_64-pc-windows-msvc\bin\lld.exe: error: exceptions not linked where expected
C:\Users\user\.xargo\lib\rustlib\x86_64-pc-windows-msvc\bin\lld.exe: error:
Invalid '.vector_table.exceptions' section. This is likely a
cortex-m-rt bug. Please file a bug report at:
https://github.com/japaric/cortex-m-rt/issues
error: aborting due to previous error
error: Could not compile `nrf51822-quickstart`.
To learn more, run the command again with --verbose.
As we found out in #84 our linker script is not supported by GCC 4.8 / binutils 2.24. We should document the minimum version that we support.
I know that binutils 2.31 works.
when compiling with optimizations because LLVM loop unrolls zero_bss and init_data. This causes binaries to be about 500 bytes bigger in size compared to non-loop unrolled version. Here are the disassemblies:
NOTE: I have inserted BKPTs before and after zero_bss and init_data
opt-level = "z"
$ size -A app
.text 78 0x400
00000400 <Reset>:
400: f000 f820 bl 444 <DefaultPreInit>
404: 4809 ldr r0, [pc, #36] ; (42c <_stext+0x2c>)
406: 2200 movs r2, #0
408: 4909 ldr r1, [pc, #36] ; (430 <_stext+0x30>)
40a: be00 bkpt 0x0000
40c: e000 b.n 410 <Reset+0x10>
40e: c004 stmia r0!, {r2}
410: 4288 cmp r0, r1
412: d3fc bcc.n 40e <Reset+0xe>
414: 4807 ldr r0, [pc, #28] ; (434 <_stext+0x34>)
416: be00 bkpt 0x0000
418: 4907 ldr r1, [pc, #28] ; (438 <_stext+0x38>)
41a: 4a08 ldr r2, [pc, #32] ; (43c <_stext+0x3c>)
41c: e001 b.n 422 <Reset+0x22>
41e: c908 ldmia r1!, {r3}
420: c008 stmia r0!, {r3}
422: 4290 cmp r0, r2
424: d3fb bcc.n 41e <Reset+0x1e>
426: be00 bkpt 0x0000
428: e7fe b.n 428 <Reset+0x28>
42a: bf00 nop
42c: 20000000 .word 0x20000000
430: 20000000 .word 0x20000000
434: 20000000 .word 0x20000000
438: 00000450 .word 0x00000450
43c: 20000000 .word 0x20000000
opt-level = "3"
(default)$ size -A app
.text 594 0x400
00000400 <Reset>:
400: f000 f922 bl 648 <DefaultPreInit>
404: f240 0000 movw r0, #0
408: f240 0200 movw r2, #0
40c: f2c2 0000 movt r0, #8192 ; 0x2000
410: f2c2 0200 movt r2, #8192 ; 0x2000
414: 4282 cmp r2, r0
416: be00 bkpt 0x0000
418: d25a bcs.n 4d0 <Reset+0xd0>
41a: 1d11 adds r1, r2, #4
41c: ea6f 0c02 mvn.w ip, r2
420: 4281 cmp r1, r0
422: f04f 0401 mov.w r4, #1
426: 460b mov r3, r1
428: bf38 it cc
42a: 4603 movcc r3, r0
42c: 4463 add r3, ip
42e: eb04 0393 add.w r3, r4, r3, lsr #2
432: 079b lsls r3, r3, #30
434: 4613 mov r3, r2
436: d024 beq.n 482 <Reset+0x82>
438: f04f 0e00 mov.w lr, #0
43c: 4613 mov r3, r2
43e: f843 eb04 str.w lr, [r3], #4
442: 4283 cmp r3, r0
444: 461d mov r5, r3
446: bf38 it cc
448: 4605 movcc r5, r0
44a: 4465 add r5, ip
44c: eb04 0495 add.w r4, r4, r5, lsr #2
450: f004 0403 and.w r4, r4, #3
454: 2c01 cmp r4, #1
456: d014 beq.n 482 <Reset+0x82>
458: 4613 mov r3, r2
45a: 2701 movs r7, #1
45c: f843 ef04 str.w lr, [r3, #4]!
460: 4283 cmp r3, r0
462: bf38 it cc
464: 4603 movcc r3, r0
466: 4463 add r3, ip
468: eb07 0393 add.w r3, r7, r3, lsr #2
46c: f003 0303 and.w r3, r3, #3
470: 2b02 cmp r3, #2
472: d004 beq.n 47e <Reset+0x7e>
474: 2300 movs r3, #0
476: 6093 str r3, [r2, #8]
478: f102 030c add.w r3, r2, #12
47c: e001 b.n 482 <Reset+0x82>
47e: f102 0308 add.w r3, r2, #8
482: 4281 cmp r1, r0
484: bf38 it cc
486: 4601 movcc r1, r0
488: 4461 add r1, ip
48a: 0889 lsrs r1, r1, #2
48c: 2903 cmp r1, #3
48e: d31f bcc.n 4d0 <Reset+0xd0>
490: 2100 movs r1, #0
492: f103 0210 add.w r2, r3, #16
496: 6019 str r1, [r3, #0]
498: 4282 cmp r2, r0
49a: 6059 str r1, [r3, #4]
49c: 6099 str r1, [r3, #8]
49e: 60d9 str r1, [r3, #12]
4a0: bf3f itttt cc
4a2: 6011 strcc r1, [r2, #0]
4a4: 6051 strcc r1, [r2, #4]
4a6: 6091 strcc r1, [r2, #8]
4a8: 60d1 strcc r1, [r2, #12]
4aa: bf3c itt cc
4ac: 3210 addcc r2, #16
4ae: 4282 cmpcc r2, r0
4b0: d20e bcs.n 4d0 <Reset+0xd0>
4b2: 6011 str r1, [r2, #0]
4b4: 6051 str r1, [r2, #4]
4b6: 6091 str r1, [r2, #8]
4b8: 60d1 str r1, [r2, #12]
4ba: 3210 adds r2, #16
4bc: 4282 cmp r2, r0
4be: d207 bcs.n 4d0 <Reset+0xd0>
4c0: f102 0310 add.w r3, r2, #16
4c4: 6011 str r1, [r2, #0]
4c6: 4283 cmp r3, r0
4c8: 6051 str r1, [r2, #4]
4ca: 6091 str r1, [r2, #8]
4cc: 60d1 str r1, [r2, #12]
4ce: d3e0 bcc.n 492 <Reset+0x92>
4d0: f240 0e00 movw lr, #0
4d4: f240 0000 movw r0, #0
4d8: f2c2 0e00 movt lr, #8192 ; 0x2000
4dc: f2c2 0000 movt r0, #8192 ; 0x2000
4e0: 4570 cmp r0, lr
4e2: be00 bkpt 0x0000
4e4: f080 8089 bcs.w 5fa <Reset+0x1fa>
4e8: 1d02 adds r2, r0, #4
4ea: ea6f 0c00 mvn.w ip, r0
4ee: 4572 cmp r2, lr
4f0: f04f 0501 mov.w r5, #1
4f4: 4611 mov r1, r2
4f6: f240 6454 movw r4, #1620 ; 0x654
4fa: bf38 it cc
4fc: 4671 movcc r1, lr
4fe: f2c0 0400 movt r4, #0
502: 4461 add r1, ip
504: eb05 0191 add.w r1, r5, r1, lsr #2
508: 0789 lsls r1, r1, #30
50a: d027 beq.n 55c <Reset+0x15c>
50c: 4621 mov r1, r4
50e: 4603 mov r3, r0
510: f851 6b04 ldr.w r6, [r1], #4
514: f843 6b04 str.w r6, [r3], #4
518: 4573 cmp r3, lr
51a: 461e mov r6, r3
51c: bf38 it cc
51e: 4676 movcc r6, lr
520: 4466 add r6, ip
522: eb05 0596 add.w r5, r5, r6, lsr #2
526: f005 0503 and.w r5, r5, #3
52a: 2d01 cmp r5, #1
52c: d018 beq.n 560 <Reset+0x160>
52e: 6861 ldr r1, [r4, #4]
530: 4603 mov r3, r0
532: f843 1f04 str.w r1, [r3, #4]!
536: 4573 cmp r3, lr
538: bf38 it cc
53a: 4673 movcc r3, lr
53c: eb03 010c add.w r1, r3, ip
540: 2301 movs r3, #1
542: eb03 0191 add.w r1, r3, r1, lsr #2
546: f001 0103 and.w r1, r1, #3
54a: 2902 cmp r1, #2
54c: d067 beq.n 61e <Reset+0x21e>
54e: 68a1 ldr r1, [r4, #8]
550: f100 030c add.w r3, r0, #12
554: 6081 str r1, [r0, #8]
556: f104 010c add.w r1, r4, #12
55a: e001 b.n 560 <Reset+0x160>
55c: 4603 mov r3, r0
55e: 4621 mov r1, r4
560: 4572 cmp r2, lr
562: bf38 it cc
564: 4672 movcc r2, lr
566: eb02 000c add.w r0, r2, ip
56a: 0880 lsrs r0, r0, #2
56c: 2803 cmp r0, #3
56e: d344 bcc.n 5fa <Reset+0x1fa>
570: f103 0210 add.w r2, r3, #16
574: 4670 mov r0, lr
576: 4572 cmp r2, lr
578: ea6f 0603 mvn.w r6, r3
57c: bf88 it hi
57e: 4610 movhi r0, r2
580: eb00 0c06 add.w ip, r0, r6
584: 2001 movs r0, #1
586: eb00 101c add.w r0, r0, ip, lsr #4
58a: f010 0003 ands.w r0, r0, #3
58e: d00a beq.n 5a6 <Reset+0x1a6>
590: e891 00f0 ldmia.w r1, {r4, r5, r6, r7}
594: 2801 cmp r0, #1
596: e883 00f0 stmia.w r3, {r4, r5, r6, r7}
59a: d130 bne.n 5fe <Reset+0x1fe>
59c: 3110 adds r1, #16
59e: f1bc 0f30 cmp.w ip, #48 ; 0x30
5a2: d204 bcs.n 5ae <Reset+0x1ae>
5a4: e029 b.n 5fa <Reset+0x1fa>
5a6: 461a mov r2, r3
5a8: f1bc 0f30 cmp.w ip, #48 ; 0x30
5ac: d325 bcc.n 5fa <Reset+0x1fa>
5ae: e891 0089 ldmia.w r1, {r0, r3, r7}
5b2: e9d1 6503 ldrd r6, r5, [r1, #12]
5b6: e9d1 4c05 ldrd r4, ip, [r1, #20]
5ba: f8d1 801c ldr.w r8, [r1, #28]
5be: e882 0089 stmia.w r2, {r0, r3, r7}
5c2: f101 0720 add.w r7, r1, #32
5c6: e9c2 6503 strd r6, r5, [r2, #12]
5ca: e9c2 4c05 strd r4, ip, [r2, #20]
5ce: f8c2 801c str.w r8, [r2, #28]
5d2: cf89 ldmia r7, {r0, r3, r7}
5d4: e9d1 650b ldrd r6, r5, [r1, #44] ; 0x2c
5d8: e9d1 4c0d ldrd r4, ip, [r1, #52] ; 0x34
5dc: f8d1 803c ldr.w r8, [r1, #60] ; 0x3c
5e0: 3140 adds r1, #64 ; 0x40
5e2: 6210 str r0, [r2, #32]
5e4: 6253 str r3, [r2, #36] ; 0x24
5e6: 6297 str r7, [r2, #40] ; 0x28
5e8: e9c2 650b strd r6, r5, [r2, #44] ; 0x2c
5ec: e9c2 4c0d strd r4, ip, [r2, #52] ; 0x34
5f0: f8c2 803c str.w r8, [r2, #60] ; 0x3c
5f4: 3240 adds r2, #64 ; 0x40
5f6: 4572 cmp r2, lr
5f8: d3d9 bcc.n 5ae <Reset+0x1ae>
5fa: be00 bkpt 0x0000
5fc: e7fe b.n 5fc <Reset+0x1fc>
5fe: f101 0610 add.w r6, r1, #16
602: 2802 cmp r0, #2
604: ce74 ldmia r6, {r2, r4, r5, r6}
606: 611a str r2, [r3, #16]
608: 615c str r4, [r3, #20]
60a: 619d str r5, [r3, #24]
60c: 61de str r6, [r3, #28]
60e: d10b bne.n 628 <Reset+0x228>
610: 3120 adds r1, #32
612: f103 0220 add.w r2, r3, #32
616: f1bc 0f30 cmp.w ip, #48 ; 0x30
61a: d2c8 bcs.n 5ae <Reset+0x1ae>
61c: e7ed b.n 5fa <Reset+0x1fa>
61e: f104 0108 add.w r1, r4, #8
622: f100 0308 add.w r3, r0, #8
626: e79b b.n 560 <Reset+0x160>
628: f101 0520 add.w r5, r1, #32
62c: 3130 adds r1, #48 ; 0x30
62e: cd35 ldmia r5, {r0, r2, r4, r5}
630: 6218 str r0, [r3, #32]
632: 625a str r2, [r3, #36] ; 0x24
634: f103 0230 add.w r2, r3, #48 ; 0x30
638: 629c str r4, [r3, #40] ; 0x28
63a: 62dd str r5, [r3, #44] ; 0x2c
63c: f1bc 0f30 cmp.w ip, #48 ; 0x30
640: d2b5 bcs.n 5ae <Reset+0x1ae>
642: e7da b.n 5fa <Reset+0x1fa>
Possible solutions:
Recommend using "z". I don't like this solution because optimizations for size penalize inlining and can cause other code to not be properly optimized.
Implement zero_bss and init_data using assembly making them tight loops like the ones you see in the output of opt-level = "z"
.
Thoughts @rust-embedded/cortex-m ?
error[E0463]: can't find crate for `compiler_builtins`
--> /Users/nixpulvis/.cargo/git/checkouts/cortex-m-rt-c229622fecd03225/d11471e/src/lib.rs:160:1
|
160 | extern crate compiler_builtins;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
$ xargo --version
xargo 0.3.7 (994cd7b 2017-03-29)
cargo 0.20.0-nightly (82733b014 2017-05-28)
$ rustc --version
rustc 1.19.0-nightly (5de00925b 2017-05-29)
I've even tried adding it as a dependency to my crate, with no luck. Here's my Cargo.toml
.
[package]
name = "rtfm-playground"
version = "0.1.0"
[dependencies]
compiler_builtins = { git = "https://github.com/rust-lang-nursery/compiler-builtins" }
cortex-m = { git = "https://github.com/japaric/cortex-m.git" }
cortex-m-rt = { git = "https://github.com/japaric/cortex-m-rt.git" }
cortex-m-rtfm = { git = "https://github.com/japaric/cortex-m-rtfm.git" }
I've also tried sourcing from crates.io.
Today, the layout of RAM looks like this (assuming no heap and a single RAM region):
With this layout when a stack overflow occurs static
variables end up being overwritten /
corrupted silently.
This scenario can be avoided by simply changing the memory layout to look like this:
In this new scenario a stack overflow will hit the lower RAM boundary. Trying to write beyond the
RAM boundaries raises a HardFault exception. Thus, in theory, the HardFault exception handler
could be used as a stack overflow handler.
In systems where heap memory, which by default starts where the static
region ends and grows
upwards, exists a similar reordering of the regions can be applied.
To my knowledge this can't be implement using only linker scripts. With a linker script you can
instruct the linker where to start a memory region but you can't specify the end address of the
region.
The related bits of the linker script we use are shown below:
PROVIDE(_stack_start = ORIGIN(RAM) + LENGTH(RAM));
SECTIONS
{
/* .. */
.bss : ALIGN(4)
{
_sbss = .;
*(.bss .bss.*);
. = ALIGN(4);
_ebss = .;
} > RAM
.data : ALIGN(4)
{
_sidata = LOADADDR(.data);
_sdata = .;
*(.data .data.*);
. = ALIGN(4);
_edata = .;
} > RAM AT > FLASH
/* The heap starts right after the .bss + .data section ends */
_sheap = _edata;
/* .. */
}
A C implementation of this region reordering uses a two step linking process. See
this StackOverflow answer for details.
Assuming that we can't change the memory layout. We could:
Use the MPU (Memory Protection Unit) to mark the upper boundary of the static
region as
read-only. In this scenario when a stack overflow occurs a MemManage exception is raised. This has
an initialization cost but no runtime cost. The downside is that not all microcontrollers have a
MPU.
Implement stack probes for the Cortex-M targets. I believe enabling stack probes carries a runtime
cost (per function call?) but I'm not sure.
Static resources which end up in .rodata are not properly aligned which is especially evident with strings. I've defined a string in my executable like
let s = &"Hello World!\n";
which resulted in an invalid binary. Most tools will complain about such a binary and of course there's no way this will run; e.g. st-flash will say something like:
2017-07-16T15:31:07 INFO src/common.c: Device connected is: F04x device, id 0x10006445
2017-07-16T15:31:07 INFO src/common.c: SRAM size: 0x1800 bytes (6 KiB), Flash: 0x8000 bytes (32 KiB) in pages of 1024 bytes
2017-07-16T15:31:07 INFO src/common.c: Attempting to write 1025 (0x401) bytes to stm32 address: 134217728 (0x8000000)
2017-07-16T15:31:07 WARN src/common.c: unaligned len 0x401 -- padding with zero
Flash page at addr: 0x08000400 erased
2017-07-16T15:31:07 INFO src/common.c: Finished erasing 2 pages of 1024 (0x400) bytes
A black magic probe will even hang completely after this:
(gdb) load
Loading section .vector_table, size 0xc0 lma 0x8000000
Loading section .text, size 0x334 lma 0x80000c0
Loading section .rodata, size 0xd lma 0x80003f4
Error writing data to flash
It seems there's currently no good way to configure system exceptions at the moment. Neither does svd2rust generate a code for the configuration of the SCB nor does cortex-m-rt provide provide proper support for all registers.
Without the ability to configure the SCB it is e.g. not possible to change the priorities of user configurable exceptions like SysTick which means it'll always run at the highest priority thus pre-empting or at least competing (if interrupts are all set to highest priority, too) with all other interrupts when used.
In cortex-m, default_handler had a local variable for the exception for convenience when debugging:
rust-embedded/cortex-m@8394581#diff-86a9d5942521ed33df4dccb8dbf23016R164
It's missing now that default_handler is in cortex-m-rt:
https://github.com/japaric/cortex-m-rt/blob/8842d0efd7863c2dc23edd75548a658af59afe6b/src/lib.rs#L458
Is this intentional?
When using cortex-m-rt .bss is allocated outside RAM which again causes hard fault when reset_handler calls zero_bss.
The microcontroller in use is NXP S32K144
The memory.x file looks like the following:
MEMORY
{
/* NOTE K = KiBi = 1024 bytes /
/ TODO Adjust these memory regions to match your device memory layout */
FLASH : ORIGIN = 0x00000000, LENGTH = 512K
RAM : ORIGIN = 0x1FFF1000, LENGTH = 60K
}
/* This is where the call stack will be allocated. */
/* The stack is of the full descending type. */
/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */
_stack_start = ORIGIN(RAM) + LENGTH(RAM);
The ram on s32k series ends at 0x1FFF FFFF and extends downwards
When entering a debug session and inspecting sbss and ebss i find that the .bss section is outside ram.
Both the memory.x and link.x seems sane so not exactly sure where this bug is.
Im also quite certain that the memory.x script is in fact linked in as the stack pointer seem to start at 0x1FFFFFFF.
Some people have expressed that they would like to configure the CPU clock before RAM initialization to speed up the initialization process (specially when lots of RAM need to be initialized).
This has to be unsafe because all the static variables stored in .bss / .data would be uninitialized during the execution of this pre-init routine.
Possible user facing interface:
#[macro_use]
extern crate cortex_m_rt;
pre_init!(unsafe {
// something
});
where pre_init!
can only be used once.
I 'm trying to compile the blinky.rs example for STM32F072RBT6
xargo rustc --release --target thumbv6m-none-eabi --example blinky -- -C link-arg=-Tlink.x -C linker=arm-none-eabi-ld -Z linker-flavor=ld
I'm getting this error :
arm-none-eabi-ld:
Invalid '.vector_table.exceptions' section.
arm-none-eabi-ld:
The interrupt handlers are missing. If you are not linking to a device
crate then you supply the interrupt handlers yourself. Check the
documentation.
May be I missed something ...
The zero_bss
and init_data
routines will run before main even if the
application makes use of neither or only one of these sections. This may not
matter much if your device has plenty of Flash memory / ROM but if you are
targeting really small devices with e.g. only 512 bytes of ROM then every byte
you can save counts.
The only safe way to opt out of these routines is to forbid the existence of the
.bss
and / or .data
sections. That can be easily done in this crate because
it controls the linker script of the application.
We add two opt-in Cargo features: "bss" and "data". If neither is enabled then
static
variables can't be used at all (unless they end up in .rodata
) and
neither, zero_bss
or init_data
, will run before "main".
If only "bss" is enabled then zero_bss
will run before main but only static
variables that end up in .bss
are allowed in the program. For instance this
would compile:
static mut STATE: bool = false;
but this would not:
static mut STATE: bool = true;
Something similar would happen with the "data" feature.
Enabling both features gives you today's behavior.
For the really brave we could allow this pattern when both "bss" and "data" are
disabled:
#[link_section = ".uninit"]
static mut STATE: bool = false;
STATE
is uninitialized because neither zero_bss
and init_data
runs before
main. Reading this variable before assigning it any value at runtime will return
junk and could even cause undefined behavior, for example if the variable is an
enum
.
This is a breaking change and it's also kind of annoying for people that usually
use both .bss
and .data
because they'll now have to enable both features or
their program won't compile.
I was just trying to port the microbit
crate to cortex-m-rt
0.6.0 but I'm facing this here:
Compiling rand_core v0.2.1
Compiling cortex-m-rt v0.6.0
error[E0463]: can't find crate for `std`
|
= note: the `thumbv6m-none-eabi` target may not be installed
error: aborting due to previous error
For more information about this error, try `rustc --explain E0463`.
error: Could not compile `rand_core`.
warning: build failed, waiting for other jobs to finish...
error: build failed
@japaric Seems something is messing (or not) with the required flags for no_std
.
Hi!
When using the new attribute macro (#[entry] fn main() -> ! { loop {} }
, I have a big regression when compiling and using a debugger: everything (error, warning and debugger) point to the attribute line, making debugging tricky.
A workaround is to directly call another function, but that's quite dirty:
#[entry]
fn entry() -> ! {
main()
}
fn main() -> ! {
loop {}
}
Hello,
I have updated to version 0.3.8 of this crate to avoid this issue : ICE when trying to cross compile with xargo.
It now compiles but it seems there is a problem when linking.
I am using the cortex-m-rtfm framework and stm32f3disovery board. I use the f3 crate (latest git) and I was successful compiling the exact same program before.
It seems the problem is coming from interrupts. I have the following interrupts setup : I2C1_EV_EXTI23 and I2C1_ER. When I remove all interrupts, program compiles and links successfully.
Here is the nightly I am using : rustc 1.24.0-nightly (77e189cd7 2017-12-28)
This is the ld output :
Compiling i2c_magnetic v0.1.0 (file:///home/clement/atom-projects/cortex/i2c_magnetic)
error: linking with `arm-none-eabi-ld` failed: exit code: 1
|
= note: "arm-none-eabi-ld" "-L" "/home/clement/.xargo/lib/rustlib/thumbv7em-none-eabihf/lib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.__rustc_fallback_codegen_unit.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.bare_metal.volatile.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.core-cell.volatile.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.core-char.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.core-fmt.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.core-fmt.volatile.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.core-num.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.core-ops-range.volatile.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.core-ptr.volatile.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.core-result.volatile.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.core-slice.volatile.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.core-str.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.cortex_m-peripheral.volatile.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.cortex_m_rt-lang_items.volatile.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.cortex_m_rtfm.volatile.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.cortex_m_semihosting-hio.volatile.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.i2c_magnetic.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.i2c_magnetic-I2C1_ER.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.i2c_magnetic-I2C1_EV_EXTI23.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.i2c_magnetic.volatile.rcgu.o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b.static_ref.volatile.rcgu.o" "-o" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/i2c_magnetic-c094ee808221889b" "--gc-sections" "-L" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps" "-L" "/home/clement/atom-projects/cortex/i2c_magnetic/target/debug/deps" "-L" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/build/cortex-m-rt-986ccafb8ce49ac6/out" "-L" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/build/f3-0569b571bc6c2bfd/out" "-L" "/home/clement/.xargo/lib/rustlib/thumbv7em-none-eabihf/lib" "-Bstatic" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libcortex_m_rtfm-6e6f4a688986a923.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/librtfm_core-2047840c54fc7908.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libuntagged_option-983345c6d1de8ec5.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libf3-df303aac69aa2c04.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libstm32f30x-3f7de102ea6e6017.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libcortex_m_rt-b675d40d94fb56f4.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libr0-2f265f8ff98e4ae6.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libstatic_ref-0d8916cd22b1d3af.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libembedded_hal-1316f468aecd520d.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libcast-53ac32fcf11bdfe7.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libnb-5107a94c34bdea80.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libcortex_m-18bde24940ccf3ce.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libbare_metal-d5e58ad0a5570173.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libaligned-1ac77a68d10d4b67.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libvolatile_register-fb080589ac340895.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libvcell-95a1d9c5f049d0fb.rlib" "/home/clement/atom-projects/cortex/i2c_magnetic/target/thumbv7em-none-eabihf/debug/deps/libcortex_m_semihosting-953ef35a657c1fc9.rlib" "/home/clement/.xargo/lib/rustlib/thumbv7em-none-eabihf/lib/libcore-12794acabb4ff5e4.rlib" "/home/clement/.xargo/lib/rustlib/thumbv7em-none-eabihf/lib/libcompiler_builtins-b967dc43a87dce64.rlib" "-Tlink.x" "-Bdynamic"
= note: /home/clement/.xargo/lib/rustlib/thumbv7em-none-eabihf/lib/libcore-12794acabb4ff5e4.rlib(core-12794acabb4ff5e4.core13-fbd2c624a359fb315320b7ce9e430956.rs.rcgu.o): In function `core::panicking::panic_fmt':
/home/clement/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/panicking.rs:71: undefined reference to `rust_begin_unwind'
error: aborting due to previous error
error: Could not compile `i2c_magnetic`.
For some reason I couldn't quite figure out there's still a separate default handler for ADC_COMP emitted:
080002c4 <_ZN11cortex_m_rt15default_handler17h264a3b21ccda1ce5E>:
80002c4: be00 bkpt 0x0000
80002c6: e7fe b.n 80002c6 <_ZN11cortex_m_rt15default_handler17h264a3b21ccda1ce5E+0x2>
080002c8 <ADC_COMP>:
80002c8: f3ef 8008 mrs r0, MSP
80002cc: e7fa b.n 80002c4 <_ZN11cortex_m_rt15default_handler17h264a3b21ccda1ce5E>
Hi all,
I have stumbled on a strange issue that took some work to find as it does not happen often.
My issue was that when compiling in debug mode the address provided by __pre_init
becomes different addresses, depending on when the system was reset. And this comes from the stack pointer not being initialized yet, and a corrupt stack pointer passing through.
This can occur if the system's stack pointer has been corrupted and a soft-reset has been requested, then the erroneous value of the stack pointer sticks until after reset.
I wrongly assumed that the system always read the stack pointer from the vector table and wrote it, hence I recommend that we add an assembler instruction to set MSP and not allow this kind of undefined behavior.
Comments @rust-embedded/cortex-m ?
Example of corrupt stack pointer after reset:
r0 0x8000251 134218321
r1 0xf00000 15728640
r2 0x20000000 536870912
r3 0x0 0
r4 0x0 0
r5 0x0 0
r6 0x0 0
r7 0x0 0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
sp 0xfffffe90 0xfffffe90
lr 0x8000315 0x8000315 <core::mem::uninitialized+12>
pc 0x80001c4 0x80001c4 <Reset+12>
xpsr 0x61000003 1627389955
fpscr 0x0 0
msp 0xfffffe90 0xfffffe90
psp 0x0 0x0
primask 0x0 0
basepri 0x0 0
faultmask 0x0 0
control 0x0 0
The obvious place to place this region is right after the .data + .bss
region. Should we go ahead with that or should we support placing it at a custom address?
When using #[entry]
on main
, any rustc errors produced there lose location information.
It's pretty easy to work around this with an extra function main_inner
, but this should be not too hard to solve (if I remember correctly, some recent version of quote
allows keeping original spans?)
On Windows, with a fresh clean install of arm-none-eabi-gcc
, building cortex-m-rt
eventually fails with:
Internal error occurred: Failed to find tool. Is `ar` installed? (see https://github.com/alexcrichton/cc-rs#compile-time-requirements for help)
As a workaround, setting the TARGET_AR
environment variable to arm-none-eabi-ar
fixes it. This was not necessary before, and is not documented anywhere if it is a new requirement.
This is an interesting case with memory.x
that I encountered today. Host machine is Arch Linux x86, target machine is ARM Cortex M4, thumbv7em-none-eabihf
. This is the memory.x file I was working with:
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 1M
RAM : ORIGIN = 0x20000000, LENGTH = 256K
}
_stack_start = ORIGIN(RAM) + 32K;
_heap_size = ORIGIN(RAM) + LENGTH(RAM) - _edata;
This is specifically targeting a Teensy 3.6. The ultimate goal is to follow the order that the cortex-m-rt-ld
linker follows, with 32K of stack size, an unlimited .data + .bss segment size, and a heap taking up the remaining space (up to 224K). Given this file, I expected the the .stack segment to start at 0x2000_0000
with length 0x8000
, and .bss, .data, and .heap to be located at 0x2000_8000
, assuming .bss and .data are empty and .heap taking up the remaining space with a length of 0x38000
. That is,
section size addr
.vector_table 0x400 0x8000000
.text 0x37e 0x8000400
.rodata 0x8 0x8000780
.stack 0x8000 0x20000000
.bss 0x0 0x20008000
.data 0x0 0x20008000
.heap 0x38000 0x20008000
from thumbv7em-none-eabihf
. However, this is the table I get instead:
.vector_table 0x400 0x8000000
.text 0x37e 0x8000400
.rodata 0x8 0x8000780
.stack 0x8000 0x20000000
.bss 0x0 0x1ffc8000
.data 0x0 0x1ffc8000
.heap 0x78000 0x1ffc8000
Notice that the .data, .bss, and .heap all start at 0x1ffc8000
.
I've found a workaround for this, however. If I add this line after _stack_start = ...
and before _heap_size = ...
:
_sbss = _stack_start;
...it produces the expected result. I imagine this has to do with _stack_start and _heap_size not playing nicely together. This isn't a show-stopper, but I figure you would like to know about this.
There should be some way to reserve a section of flash so nothing will be placed there. Particularly right after .vector_table
Some use cases for this feature
I guess the simple solution will be to introduce a text_offset (or text_start) symbol which can be defined in the memory.x and if defined be used to place a reserved region between .vector_table and .text (or simply offsetting .text)
Alternatively are there any semi-simple ways to implement support for reserving a region of flash(/ram) in an arbitrary location without breaking the way the memory.x files work?
#![feature(used)]
#![no_std]
extern crate cortex_m_rt;
fn main() {}
#[used]
#[link_section = ".rodata.interrupts"]
static INTERRUPTS: [u32; 240] = [0; 240];
with cortex-m-quickstart v0.1.8 and cortex-m-rt v0.2.4.
Produces:
08000400 <cortex_m_rt::reset_handler>:
8000400: b580 push {r7, lr}
8000402: 466f mov r7, sp
8000404: f240 0000 movw r0, #0
8000408: f240 0100 movw r1, #0
800040c: f2c2 0000 movt r0, #8192 ; 0x2000
8000410: f2c2 0100 movt r1, #8192 ; 0x2000
8000414: 1a09 subs r1, r1, r0
8000416: f021 0103 bic.w r1, r1, #3
800041a: f000 f851 bl 80004c0 <__aeabi_memclr4>
800041e: f240 0000 movw r0, #0
8000422: f240 0100 movw r1, #0
8000426: f2c2 0000 movt r0, #8192 ; 0x2000
800042a: f2c2 0100 movt r1, #8192 ; 0x2000
800042e: 1a09 subs r1, r1, r0
8000430: f021 0203 bic.w r2, r1, #3
8000434: f240 41d4 movw r1, #1236 ; 0x4d4
8000438: f6c0 0100 movt r1, #2048 ; 0x800
800043c: f000 f836 bl 80004ac <__aeabi_memcpy4>
8000440: f240 0000 movw r0, #0
8000444: f2c0 0000 movt r0, #0
8000448: 7800 ldrb r0, [r0, #0]
800044a: bf30 wfi
800044c: e7fd b.n 800044a <cortex_m_rt::reset_handler+0x4a>
In this case there's no main to execute but this:
8000440: f240 0000 movw r0, #0
8000444: f2c0 0000 movt r0, #0
8000448: 7800 ldrb r0, [r0, #0]
is loading the byte stored at address 0x0. This doesn't crash on Cortex-M devices because that's a valid address (the start of the vector table).
I'm not exactly sure why that's being generated but it doesn't appear if I remove the start lang_item from cortex-m-rt and directly call a the binary crate main function.
cc @pftbest do you see something like this on msp430?
As discussed, see rust-embedded/cortex-m#19 (comment) for details.
That crate is an implementation detail of the compiler. It contains the implementation of intrinsics that LLVM may emit calls to when lowering Rust code to machine code. It's unknown what the future of compiler_builtins
will be but likely it will not exist in the future (it might be merged into the core crate).
So this a breaking change that will come from upstream at some point: extern crate compiler_builtins
is unstable.
to reduce the probability of foreign object files (that, for example, come from C code) from corrupting the vector table.
This will, at least, break the cortex-m-quickstart template and the cortex-m-rtfm crate.
I see this problem with both v0.6.3 and v0.5.3. I find odd that this had not been reported yet. cc @rust-embedded/cortex-m
Test program
#![no_main]
#![no_std]
extern crate panic_halt;
use cortex_m_rt::entry;
use stm32f30x::interrupt; // version = "0.7.1", features = ["rt"]
#[entry]
fn main() -> ! {
loop {}
}
interrupt!(EXTI0, exti0);
fn exti0() {}
Compiler version
$ rustc -V
rustc 1.30.0-nightly (cb6d2dfa8 2018-09-16)
Profile settings
[profile.release]
codegen-units = 1 # better optimizations
debug = true # symbols are nice and they don't increase the size on Flash
lto = true # better optimizations
Vector table
$ cargo objdump --bin bug --release -- -s -j .vector_table
bug: file format ELF32-arm-little
Contents of section .vector_table:
8000000 00200010 89010008 eb030008 ef030008 . ..............
8000010 eb030008 eb030008 eb030008 00000000 ................
8000020 00000000 00000000 00000000 eb030008 ................
8000030 eb030008 00000000 eb030008 eb030008 ................
8000040 eb030008 eb030008 eb030008 eb030008 ................
8000050 eb030008 eb030008 ed030008 eb030008 ................
^^^^^^^^
EXTI0
Symbols
$ cargo nm --bin bug --release | grep EXTI0
Linker invocation
$ cargo rustc --release -- -Z print-link-args
"rust-lld" "-flavor" "gnu" "-L" "/home/japaric/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv7em-none-eabihf/lib" "/tmp/bug/target/thumbv7em-none-eabihf/release/deps/bug-381b87155f198187.bug.mifurchn-cgu.0.rcgu.o" "-o" "/tmp/bug/target/thumbv7em-none-eabihf/release/deps/bug-381b87155f198187" "--gc-sections" "-L" "/tmp/bug/target/thumbv7em-none-eabihf/release/deps" "-L" "/tmp/bug/target/release/deps" "-L" "/tmp/bug/target/thumbv7em-none-eabihf/release/build/cortex-m-rt-bd6bf01cb3a46dff/out" "-L" "/tmp/bug/target/thumbv7em-none-eabihf/release/build/stm32f30x-13a6d998304332c3/out" "-L" "/tmp/bug/target/thumbv7em-none-eabihf/release/build/cortex-m-6c79e89034c44e69/out" "-L" "/home/japaric/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv7em-none-eabihf/lib" "-Bstatic" "/tmp/rustcgt6dmx/libcortex_m-970363bd53c192d1.rlib" "/tmp/rustcgt6dmx/libcortex_m_rt-0c4e2c073c41d9d6.rlib" "--start-group" "--end-group" "/home/japaric/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv7em-none-eabihf/lib/libcompiler_builtins-40deee36c8e269ec.rlib" "-Tlink.x" "-Bdynamic"
These trailing rlibs look suspicious: "/tmp/rustcgt6dmx/libcortex_m-970363bd53c192d1.rlib" "/tmp/rustcgt6dmx/libcortex_m_rt-0c4e2c073c41d9d6.rlib"
. I would expect compiler-builtins to be the only rlib explicitly linked -- the rest of the dependency graph should be in bug-381b87155f198187.bug.mifurchn-cgu.0.rcgu.o
.
Profile settings
[profile.release]
codegen-units = 1 # better optimizations
debug = true # symbols are nice and they don't increase the size on Flash
# lto = true # better optimizations
Vector table
$ cargo objdump --bin bug --release -- -s -j .vector_table
bug: file format ELF32-arm-little
Contents of section .vector_table:
8000000 00200010 8d010008 09030008 0d030008 . ..............
8000010 09030008 09030008 09030008 00000000 ................
8000020 00000000 00000000 00000000 09030008 ................
8000030 09030008 00000000 09030008 09030008 ................
8000040 09030008 09030008 09030008 09030008 ................
8000050 09030008 09030008 8b010008 09030008 ................
^^^^^^^^
EXTI0
Symbols
$ cargo nm --bin bug --release | grep EXTI0
0800018a T EXTI0
Linker invocation
$ cargo rustc --release -- -Z print-link-args
"rust-lld" "-flavor" "gnu" "-L" "/home/japaric/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv7em-none-eabihf/lib" "/tmp/bug/target/thumbv7em-none-eabihf/release/deps/bug-e3271edbb1a4a9d3.bug.bycyyss2-cgu.0.rcgu.o" "-o" "/tmp/bug/target/thumbv7em-none-eabihf/release/deps/bug-e3271edbb1a4a9d3" "--gc-sections" "-L" "/tmp/bug/target/thumbv7em-none-eabihf/release/deps" "-L" "/tmp/bug/target/release/deps" "-L" "/tmp/bug/target/thumbv7em-none-eabihf/release/build/cortex-m-rt-1a9f89a71984e973/out" "-L" "/tmp/bug/target/thumbv7em-none-eabihf/release/build/stm32f30x-e12194a73271042f/out" "-L" "/tmp/bug/target/thumbv7em-none-eabihf/release/build/cortex-m-153b6429f645ce66/out" "-L" "/home/japaric/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv7em-none-eabihf/lib" "-Bstatic" "/tmp/bug/target/thumbv7em-none-eabihf/release/deps/libstm32f30x-334ca52eebd48eb6.rlib" "/tmp/bug/target/thumbv7em-none-eabihf/release/deps/libcortex_m-d74627c3356a931c.rlib" "/tmp/bug/target/thumbv7em-none-eabihf/release/deps/libvolatile_register-6ea530f7efd13473.rlib" "/tmp/bug/target/thumbv7em-none-eabihf/release/deps/libvcell-7b77ecd77a022d87.rlib" "/tmp/bug/target/thumbv7em-none-eabihf/release/deps/libaligned-0687a852eeab2dd7.rlib" "/tmp/bug/target/thumbv7em-none-eabihf/release/deps/libbare_metal-7490e1f4567463a8.rlib" "/tmp/bug/target/thumbv7em-none-eabihf/release/deps/libcortex_m_rt-0c546b13b674a5a8.rlib" "/tmp/bug/target/thumbv7em-none-eabihf/release/deps/libr0-6c6eaa23e446b5cb.rlib" "--start-group" "/tmp/bug/target/thumbv7em-none-eabihf/release/deps/libpanic_halt-ed71d3f284218cfe.rlib" "/home/japaric/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv7em-none-eabihf/lib/libcore-f764daaf6861df53.rlib" "--end-group" "/home/japaric/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv7em-none-eabihf/lib/libcompiler_builtins-40deee36c8e269ec.rlib" "-Tlink.x" "-Bdynamic"
Vector table
$ cargo objdump --bin bug -- -s -j .vector_table
bug: file format ELF32-arm-little
Contents of section .vector_table:
8000000 00200010 ad010008 25020008 3d020008 . ......%...=...
8000010 25020008 25020008 25020008 00000000 %...%...%.......
8000020 00000000 00000000 00000000 25020008 ............%...
8000030 25020008 00000000 25020008 25020008 %.......%...%...
8000040 25020008 25020008 25020008 25020008 %...%...%...%...
8000050 25020008 25020008 8f010008 25020008 %...%.......%...
^^^^^^^^
EXTI0
When I try to link embed-rs/stm32f7-dicovery-rewrite with arm-none-eabi-gcc 4.9.3, I get the following error with cortex-m-rt 0.5.2:
error: linking with `arm-none-eabi-gcc` failed: exit code: 1
|
= note: "arm-none-eabi-gcc" "-L" [โฆ]
= note: /usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/bin/ld:
BUG(cortex-m-rt): the reset vector is missing
/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/bin/ld:
BUG(cortex-m-rt): the exception vectors are missing
collect2: error: ld returned 1 exit status
With cortex-m-rt 0.5.1, it builds without problems.
Just noticed v0.6.5 is not tagged and thus doesn't show up under releases.
@adamgreig Do you have the tag already and just forgot to push it by accident?
What the title says. I believe attributes would be more ergonomic and less redundant. Compare this:
entry!(main);
fn main() -> ! {
// .. user code ..
}
exception!(HardFault, handler);
fn handler() -> ! {
// .. user code ..
}
to this:
#[entry]
fn main() -> ! {
// .. user code ..
}
#[exception(HardFault)]
fn handler() -> ! {
// .. user code ..
}
As a bonus point we get rid of the indirection that the entry!
macro requires.
entry!
expands into this for type safety:
#[export_name = "main"]
fn __impl_main() -> ! {
// check the signature of `main`
let f: fn() -> ! = main;
f()
}
The function call doesn't always get inlined (unless you marked main
as #[inline(always)]
, which
looks a bit odd).
On the other hand, #[entry]
expands into this:
#[export_name = "main"]
pub fn main() -> ! {
// .. user code ..
}
so there's no function call even when compiling without optimizations. (The type check is done
syntactically during the macro expansion)
#[exception]
s.#[proc_macro_attribute]
, which is required to write these macros, has already been stabilized in
nightly. #![feature(use_extern_macros)]
, which is required to use these macros, has not been
stabilized yet, but it's planned for the 2018 edition (1.31).
According to the changelog and docs, since v5
This crate requires
arm-none-eabi-gcc
to be installed and available in$PATH
.
I thought that would be no problem, as my setup fulfills this requirement. However, when I try to build, this happens:
$ where arm-none-eabi-gcc
C:\Program Files (x86)\GNU Tools ARM Embedded\bin\arm-none-eabi-gcc.exe
$ cargo build
Compiling demo v0.1.0 (file:///C:/Users/โฆ/demo)
Compiling cortex-m-rt v0.5.1
error: failed to run custom build command for `cortex-m-rt v0.5.1`
process didn't exit successfully: `C:\Users\โฆ\demo\target\debug\build\cortex-m-rt-4eb45f2a4d8a1423\build-script-build` (exit code: 101)
--- stdout
cargo:rustc-cfg=has_fpu
TARGET = Some("thumbv7em-none-eabihf")
OPT_LEVEL = Some("0")
TARGET = Some("thumbv7em-none-eabihf")
HOST = Some("x86_64-pc-windows-msvc")
TARGET = Some("thumbv7em-none-eabihf")
TARGET = Some("thumbv7em-none-eabihf")
HOST = Some("x86_64-pc-windows-msvc")
CC_thumbv7em-none-eabihf = None
CC_thumbv7em_none_eabihf = None
TARGET_CC = None
CC = Some("x86_64-w64-mingw32-gcc.exe")
TARGET = Some("thumbv7em-none-eabihf")
HOST = Some("x86_64-pc-windows-msvc")
CFLAGS_thumbv7em-none-eabihf = None
CFLAGS_thumbv7em_none_eabihf = None
TARGET_CFLAGS = None
CFLAGS = None
DEBUG = Some("true")
running: "x86_64-w64-mingw32-gcc.exe" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-mthumb" "-mfloat-abi=hard" "-march=armv7e-m" "-mfpu=fpv4-sp-d16" "-Wall" "-Wextra" "-o" "C:\\Users\\โฆ\\demo\\target\\thumbv7em-none-eabihf\\debug\\build\\cortex-m-rt-57618b7d7114300a\\out\\asm.o" "-c" "asm.s"
cargo:warning=x86_64-w64-mingw32-gcc: error: unrecognized command line option ยป-mthumbยซ
cargo:warning=x86_64-w64-mingw32-gcc: error: unrecognized command line option ยป-mfloat-abi=hardยซ
cargo:warning=x86_64-w64-mingw32-gcc: error: unrecognized command line option ยป-mfpu=fpv4-sp-d16ยซ
exit code: 1
--- stderr
thread 'main' panicked at '
Internal error occurred: Command "x86_64-w64-mingw32-gcc.exe" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-mthumb" "-mfloat-abi=hard" "-march=armv7e-m" "-mfpu=fpv4-sp-d16" "-Wall" "-Wextra" "-o" "C:\\Users\\โฆ\\demo\\target\\thumbv7em-none-eabihf\\debug\\build\\cortex-m-rt-57618b7d7114300a\\out\\asm.o" "-c" "asm.s" with args "x86_64-w64-mingw32-gcc.exe" did not execute successfully (status code exit code: 1).
', C:\Users\โฆ\.cargo\registry\src\github.com-1ecc6299db9ec823\cc-1.0.15\src\lib.rs:2158:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
warning: build failed, waiting for other jobs to finish...
error: build failed
It seems that you're using the cc
crate to invoke the compilation of some assembly, but for some reason it selects x86_64-w64-mingw32-gcc
(which doesn't know the arm options) instead of arm-none-eabi-gcc
. I have studied the options of cc
, but I'm not sure whether I need to setup my environment differently or whether there is a bug in the build script.
Hi Jorge and friends,
For various reasons I'm trying to use cortex-m-rt on a stm32l151 with a bootloader at 0x0800_0000.
This means my memory.x looks like this:
MEMORY
{
FLASH : ORIGIN = 0x08004000, LENGTH = 48K
RAM : ORIGIN = 0x20000000, LENGTH = 16K
}
so my user code plus the vector table starts at 0x0800_4000.
On startup the bootloader runs first, and once it's done it jumps to the reset handler at *0x0800_4004.
So far this works, and my main (well actually RTFMs init and idle) runs as expected.
However, none of the interrupts work, as the stm32 still uses the bootloader vector table at 0x0800_0000.
To fix that I'm currently running unsafe { p.core.SCB.vtor.write(0x4000) };
in init
, after which everything runs just fine again.
Would it make sense to handle this vector table relocation in cortex-m-rt or should we consider this a bug of the bootloader?
If we want to fix it in cortex-m-rt, how could the fix look like? We'd need to write the relative offset from start of flash to where the vector table ends up, but as far as I can tell we don't know anymore that the original start of FLASH was at 0x8000_0000.
If you switch the linker from arm-none-eabi-ld to ld.lld you'll get the following error:
$ ld.lld --version
LLD 7.0.0 (https://github.com/llvm-mirror/lld 527f7fd20d23a54ae30ccdf5071312b24e28776b) (compatible with GNU linkers)
$ xargo build
error: linking with `ld.lld` failed: exit code: 1
|
= note: "ld.lld" (..)
= note: ld.lld: error: $PWD/target/thumbv7em-none-eabihf/debug/build/cortex-m-rt-f07298b7bbb47f59/out/link.x:92: NOLOAD expected, but got INFO
>>> .debug_gdb_scripts _stext (INFO) : {
>>> ^
But if you modify this crate link.x like this:
/* a rustc hack will force the program to read the first byte of this section,
so we'll set the (fake) start address of this section to something we're
sure can be read at runtime: the start of the .text section */
- .debug_gdb_scripts _stext (INFO) : {
+ .debug_gdb_scripts _stext (NOLOAD) : {
KEEP(*(.debug_gdb_scripts))
- }
+ } > FLASH
Programs link correctly. The resulting binaries are well formed and debug information works. ๐
However, this results in an artifical increase of size of the text section as reported by arm-none-eabi-size
:
$ # before (linked with GNU ld)
$ arm-none-eabi-size (..)
text data bss dec hex filename
1300 0 0 1300 514 (..)
$ arm-none-eabi-size -Ax (..)
section size addr
.vector_table 0x188 0x8000000
.text 0x384 0x8000188
.rodata 0x8 0x800050c
.bss 0x0 0x20000000
.data 0x0 0x20000000
.debug_gdb_scripts 0x88 0x8000188
$ # after (linked with GNU ld)
$ arm-none-eabi-size (..)
text data bss dec hex filename
1436 0 0 1436 59c (..)
$ arm-none-eabi-size -Ax (..)
section size addr
.vector_table 0x188 0x8000000
.text 0x384 0x8000188
.rodata 0x8 0x800050c
.bss 0x0 0x20000000
.data 0x0 0x20000000
.debug_gdb_scripts 0x88 0x8000188 <- NOTE overlaps with .text
$ # after (linked with LLVM lld)
$ arm-none-eabi-size (..)
text data bss dec hex filename
1436 0 0 1436 59c (..)
$ arm-none-eabi-size -Ax (..)
section size addr
.vector_table 0x188 0x8000000
.text 0x384 0x8000188
.rodata 0x8 0x800050c
.bss 0x0 0x20000000
.data 0x0 0x20000000
.got 0x0 0x20000000
.debug_gdb_scripts 0x88 0x8000514 <- NOTE comes after .text
This is just an error in the report though. The .debug_gdb_scripts doesn't end up in FLASH even with the linker script changes.
> # GDB console after flashing the binary linked using LLD
> x/12x 0x8000514
0x8000514 <__rustc_debug_gdb_scripts_section__>: 0xffffffff 0xffffffff 0xffffffff 0xffffffff
0x8000524 <__rustc_debug_gdb_scripts_section__+16>: 0xffffffff 0xffffffff 0xffffffff 0xffffffff
0x8000534 <__rustc_debug_gdb_scripts_section__+32>: 0xffffffff 0xffffffff 0xffffffff 0xffffffff
This issue is to gauge interested in adding LLD support right now (by applying the above diff).
Alternatively we can hold off until LLD lands in rustc (hopefully sometime this year) since it's only then when we'll be able to drop the dependency on a external linker (arm-none-eabi-ld).
I've tried to update the cortex-m crate to version 0.4.3.
There is a problem to get peripherals to enable the FPU. I didn't found a solution to get peripherals without taking the sole ownership of it.
The current code is :
let scb = &*cortex_m::peripheral::SCB.get();
scb.enable_fpu();
We can't do that because peripherals will not be accessible from other scopes :
let mut scb: cortex_m::peripheral::SCB = cortex_m::Peripherals::steal().SCB;
scb.enable_fpu();
Maybe I am missing somethind or we can't upgrade to this version of cortex-m crate.
Building cortex-m-rt
on nightly
, beta
and stable
in Mac OS High Sierra (tested on two machines) results in the following error:
LLVM ERROR: Global variable '__RESET_VECTOR' has an invalid section specifier '.vector_table.reset_vector': mach-o section specifier requires a segment whose length is between 1 and 16 characters.
It build correctly on my Ubuntu 18.04 machine.
Linking a minimal program using LLD and then inspecting with with arm-none-eabi-objdump
produces:
Disassembly of section .text:
00000400 <Reset>:
400: f000 f81b bl 43a <DefaultPreInit>
404: f240 0000 movw r0, #0
408: f240 0100 movw r1, #0
40c: f2c2 0000 movt r0, #8192 ; 0x2000
410: f2c2 0100 movt r1, #8192 ; 0x2000
414: f000 f816 bl 444 <__zero_bss>
418: f240 0000 movw r0, #0
41c: f240 415c movw r1, #1116 ; 0x45c
420: f240 0200 movw r2, #0
424: f2c2 0000 movt r0, #8192 ; 0x2000
428: f2c0 0100 movt r1, #0
42c: f2c2 0200 movt r2, #8192 ; 0x2000
430: f000 f80e bl 450 <__init_data>
434: defe udf #254 ; 0xfe
00000436 <UserHardFault_>:
436: Address 0x0000000000000436 is out of bounds.
00000437 <UserHardFault>:
437: Address 0x0000000000000437 is out of bounds.
00000438 <DefaultHandler_>:
438: Address 0x0000000000000438 is out of bounds.
00000439 <BusFault>:
439: Address 0x0000000000000439 is out of bounds.
0000043a <DefaultPreInit>:
43a: Address 0x000000000000043a is out of bounds.
0000043b <__pre_init>:
43b: Address 0x000000000000043b is out of bounds.
0000043c <HardFault>:
43c: f3ef 8008 mrs r0, MSP
440: f7ff fff9 bl 436 <UserHardFault_>
00000444 <__zero_bss>:
444: 2200 movs r2, #0
446: e000 b.n 44a <__zero_bss+0x6>
448: c004 stmia r0!, {r2}
44a: 4288 cmp r0, r1
44c: d3fc bcc.n 448 <__zero_bss+0x4>
44e: 4770 bx lr
00000450 <__init_data>:
450: e001 b.n 456 <__init_data+0x6>
452: c908 ldmia r1!, {r3}
454: c008 stmia r0!, {r3}
456: 4290 cmp r0, r2
458: d3fb bcc.n 452 <__init_data+0x2>
45a: 4770 bx lr
Linking the same program using GNU LD and then inspecting with with arm-none-eabi-objdump
produces:
Disassembly of section .text:
00000400 <Reset>:
400: f000 f81b bl 43a <DefaultPreInit>
404: f240 0000 movw r0, #0
408: f240 0100 movw r1, #0
40c: f2c2 0000 movt r0, #8192 ; 0x2000
410: f2c2 0100 movt r1, #8192 ; 0x2000
414: f000 f816 bl 444 <__zero_bss>
418: f240 0000 movw r0, #0
41c: f240 415c movw r1, #1116 ; 0x45c
420: f240 0200 movw r2, #0
424: f2c2 0000 movt r0, #8192 ; 0x2000
428: f2c0 0100 movt r1, #0
42c: f2c2 0200 movt r2, #8192 ; 0x2000
430: f000 f80e bl 450 <__init_data>
434: defe udf #254 ; 0xfe
00000436 <UserHardFault_>:
436: e7fe b.n 436 <UserHardFault_>
00000438 <DefaultHandler_>:
438: e7fe b.n 438 <DefaultHandler_>
0000043a <DefaultPreInit>:
43a: 4770 bx lr
0000043c <HardFault>:
43c: f3ef 8008 mrs r0, MSP
440: f7ff fff9 bl 436 <UserHardFault_>
00000444 <__zero_bss>:
444: 2200 movs r2, #0
446: e000 b.n 44a <__zero_bss+0x6>
448: c004 stmia r0!, {r2}
44a: 4288 cmp r0, r1
44c: d3fc bcc.n 448 <__zero_bss+0x4>
44e: 4770 bx lr
00000450 <__init_data>:
450: e001 b.n 456 <__init_data+0x6>
452: c908 ldmia r1!, {r3}
454: c008 stmia r0!, {r3}
456: 4290 cmp r0, r2
458: d3fb bcc.n 452 <__init_data+0x2>
45a: 4770 bx lr
Upstream LLVM bug report: https://bugs.llvm.org/show_bug.cgi?id=38725
There are no known workarounds but it would be great to fix this in time for the 2018 edition.
I'm running into a dependency conflict where I can't depend on uom
because it depends on num-traits
, which has been made no_std compatible since the most recent version of chrono
. The problem is, the released version of chrono
depends on a conflicting version of num-traits
that requires std
. Why cargo can't sort out conflicts of this sort is beyond me, but since it can't, would cortex-m-rt
switching to the github version of chrono
be permissible (at least until chrono
gets their act together and cuts a no_std compatible release)?
To recreate the problem for yourself, all you have to do is start a blank no_std library project, add a dep for
uom = { git = "https://github.com/iliekturtles/uom", branch = "dev-num-std", default-features=false, features =["si", "f32"] }
verify that xargo can build it, then add a dep for cortex-m-rt = "*"
and try to build again
I am getting the following when trying to build my application.
cortex-m-rt: The reset vector is missing. This is a bug in cortex-m-rt. Please file a bug
report at: https://github.com/japaric/cortex-m-rt/issues
/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/bin/ld:
cortex-m-rt: The exception vectors are missing. This is a bug in cortex-m-rt. Please file
a bug report at: https://github.com/japaric/cortex-m-rt/issues
/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/bin/ld:
cortex-m-rt: The interrupt vectors are missing. Possible solutions, from most likely to
less likely:
- Link to a device crate
- Disable the 'device' feature of cortex-m-rt to build a generic application (a dependency
may be enabling it)
- Supply the interrupt handlers yourself. Check the documentation for details.
After running cargo rustc --target thumbv7em-none-eabihf -- -C link-arg=-nostartfiles -C link-arg=-Tlink.x
per the documentation here.
Per the provided instruction I am filing a bug here.
I tried disabling the device
feature (by way of disabling the rt
feature on the device crate) and that did not work. My code is here https://github.com/jcreedon/bitsy-blinky and my device crate is here https://github.com/jcreedon/stm32f41x (generated on 0.13.0)
It's very likely that the thumb targets will soon switch to rust-lld as their default linker (see
rust-embedded/wg#160). If we want to achieve the goal of not depending on GCC, by default, to
build Cortex-M applications then we also have to make core crates like this one not depend on GCC by
default. This RFC is exactly about that.
I propose that in the next minor (breaking) release, v0.6.0, we add an opt-in Cargo feature named
"exception-frame" that changes the signature of the HardFault handler as it's shown below:
// "exception-frame" disabled
#[exception(HardFault)]
fn handler(/* no `ExceptionFrame` here */) -> ! {
// ..
}
// "exception-frame" enabled
#[exception(HardFault)]
fn handler(ef: &ExceptionFrame) -> ! {
// ..
}
The rationale for this change is that providing ExceptionFrame
information to the handler requires
an external assembly file and that
makes this crate depend on GCC. By making this information opt-in this crate would, by default, work
w/o GCC being present. If the user wants the ExceptionFrame
information they'll need to have GCC
installed.
cc @rust-embedded/cortex-m @hannobraun @crawford
... once there's a typed and stable mechanism to specify the behavior of panic!
cf rust-lang/rfcs#2070.
If you have an application where .vector_table
+ .text
+ .rodata
fit into FLASH
, but with .data
included as well it does not fit, gcc (haven't tried lld) will fail to notice the overflow.
I believe this is because .data
has an LMA which is a computed address rather than a section:
/* In current link.x.in, note LMA at the top but no use of FLASH section */
.data : AT(ADDR(.rodata) + SIZEOF(.rodata)) /* LMA */
{
*(.data .data.*);
. = ALIGN(4); /* 4-byte align the end (VMA) of this section */
} > RAM
Instead we might use:
/* Hypothetical alternative example which correctly detects overflow, note "AT > FLASH" */
.data : ALIGN(4)
{
*(.data .data.*)
. = ALIGN(4);
} > RAM AT > FLASH
I assume there's a reason for doing it the current way (perhaps compatibility with lld? I'm not sure), but anyway failing to detect the overflow should be treated as a bug in the linker script.
The alternative above correctly detects overflow, and seems to do the right thing when everything does fit, but I've not tested it extensively (it's what I'd usually use on a typical embedded C gcc project though). Using ALIGN(4)
in the declaration of .data
seems to ensure it's aligned without requiring the . = ALIGN(4)
we currently have in the end of .rodata
, too.
Now that we have the fantastic new #[entry]
and #[exception]
macros, how do we deal with interrupt handlers?
After #85 was merged we never updated the documentation to mention the new default handlers. Instead, it still says
It's mandatory to set the
HardFault
handler somewhere in the dependency graph of an application
which is technically true but a little misleading. We should probably mention the defaults in any event, and possibly update the example in the crate-level documentation to not manually specify the handlers.
Currently these two symbols must be defined somewhere in the dependency graph of an application --
though they are usually defined in the application crate itself.
We could provide defaults for these two symbols in this crate obviating the need to define them in
some cases. The questions to answer are: should we? and if we do what should the defaults be?
Some thoughts to kick off the discussion
There's a trade-off between ergonomics for the experienced used (as in knows what exceptions are
and what the HardFault exception means) and learnability for people getting started on embedded
development.
For the experienced user defaults are good because that just means "less boilerplate" for trivial
applications, examples and programs that are being debugged; and they know when they should override
these exception handlers: non trivial applications, production builds, etc.
On the other hand, defaults may make the beginner never learn about these handlers, think that they
are not important and/or think that the defaults do the right thing in every possible situation ("sane
defaults"). This can turn into a nasty surprise down road when they run their application detached
from the debugger and end up experiencing a crash / lockup with no means of investigating the cause
because they didn't override the handlers to log faults.
Likely bad options:
Hardware breakpoint (bkpt
). bkpt
triggers a HardFault
exception. When used from the
HardFault
handler it results in infinite recursion.
intrinsics::abort
. abort
triggers a HardFault
exception so same problem as above.
panic!
. The semantics of panic!
varies per application making it not general enough to be used
here. For example, panic!
could trigger a hardware breakpoint or call abort
.
What others do:
DefaultHandler
(and HardFault
) to an infinite loop.Other considerations:
DefaultHandler
and UserHardFault
are stable unmangled symbols that one can place breakpointsAccording to the ARMv7-M Architecture Reference Manual there should be a DebugMonitor exception handler after the one for SVCall. This crate does not expose this exception. Was this done intentionally or was the DebugMonitor exception simply overlooked?
When using bindgen + gcc_rs to wrap bare metal C code, gcc_rs defaults to building with -fPIC, even though dynamic relocation never happens, making position independent code nonessential.
At link time when linking to a library built with -fPIC, the cortex-m-rt link script will error with:
.got section detected in the input files. Dynamic relocations are not
supported. If you are linking to C code compiled using thegcc
crate
then modify your build script to compile the C code without the
-fPIC flag. See the documentation of thegcc::Config.fpic
method for
details.
However, gcc::Config.fpic
doesn't appear anywhere in the gcc-rs docs. The solution for me was to use the gcc::Config.flag
method, passing it -fno-pic
, e.g.
gcc::Build::new().flag("-fno-pic")
I'm not sure if I'm misunderstanding the warning or if it's outdated. If the latter, I tracked the error message down to here & I'm happy to make a PR that updates the message if requested.
Hi, so I was trying to run the example (hello.rs) from here and I got an error when trying `xargo build --example hello.
xargo build works (I did have to add #![feature(const_unsafe_cell_new)] to the bare-metal file)
I've attached a picture with the exact bug. Please let me know if there's anything I can do to help.
I'm using:
P.S. I'm new to rust embedded so this maybe something on my side
Hi, with the latest changes here I have seen a compile time regression from 1-2 min to now a little over 1 hour.
I am not sure what caused the regression, but it can be tested there (I have reproduced it on the latest nightly on both a Ubuntu 16.04 and Arch Linux distribution):
https://github.com/korken89/trustflight_firmware - enter the binary folder and run cargo build --release
.
The time is in @adamgreig's stm32f3
crate in this case, which at the update to 0.2.3
updated the cortex-m-rt
version (at 0.2.2
this did not happen), leading me to place the issue here.
Does anyone know what caused this to happen and a possible mitigation?
Thanks!
Rustc: rustc 1.30.0-nightly (2d4e34ca8 2018-09-09)
Edit: Also, the compiler is not allocating any memory, which seems strange to me. Only allocating 107 MB and then not any change at all. Perhaps a compiler issue?
The default_handler!
doesn't work in this example code. This was tested with rust-1.26.0-nightly-2018-02-27-29f5c699b:
Debug Build:
000004de <_ZN11cortex_m_rt15default_handler17h87e495993753afeeE>:
///
/// That exception frame is a snapshot of the program state right before the
/// exception occurred.
#[allow(unused_variables)]
#[cfg(target_arch = "arm")]
extern "C" fn default_handler(ef: &ExceptionFrame) -> ! {
4de: b082 sub sp, #8
4e0: 4601 mov r1, r0
4e2: 9001 str r0, [sp, #4]
/// cause an exception
#[inline(always)]
pub fn bkpt() {
#[cfg(target_arch = "arm")]
unsafe {
asm!("bkpt"
4e4: be00 bkpt 0x0000
asm::bkpt();
4e6: 9100 str r1, [sp, #0]
4e8: e7ff b.n 4ea <_ZN11cortex_m_rt15default_handler17h87e495993753afeeE+0xc>
loop {}
4ea: e7fe b.n 4ea <_ZN11cortex_m_rt15default_handler17h87e495993753afeeE+0xc>
000004ec <BUS_FAULT>:
#[export_name = "DEFAULT_HANDLER"]
#[linkage = "weak"]
#[naked]
extern "C" fn trampoline() -> ! {
unsafe {
asm!("mrs r0, MSP
4ec: f3ef 8008 mrs r0, MSP
4f0: f7ff bff5 b.w 4de <_ZN11cortex_m_rt15default_handler17h87e495993753afeeE>
:
: "i"(default_handler as extern "C" fn(&ExceptionFrame) -> !)
:
: "volatile");
intrinsics::unreachable()
4f4: defe udf #254 ; 0xfe
Release Build:
00000598 <_ZN11cortex_m_rt15default_handler17h6304dc68fb71af89E>:
598: be00 bkpt 0x0000
59a: e7fe b.n 59a <_ZN11cortex_m_rt15default_handler17h6304dc68fb71af89E+0x2>
0000059c <BUS_FAULT>:
59c: f3ef 8008 mrs r0, MSP
5a0: f7ff bffa b.w 598 <_ZN11cortex_m_rt15default_handler17h6304dc68fb71af89E>
5a4: defe udf #254 ; 0xfe
When linking a C library compiled as position independent code, the resulting binary contains a section .got
which contains a 'global offset table'. This section needs to be initialized like .data
by initialization code, as far as I can tell.
Symptoms were accesses to random memory addresses at runtime, of course leading to a non-working binary.
I found two changes I could do to avoid this issue:
true
..got
to the .data
section using a modified link script:diff --git a/link.x b/link.x
index e6c90fa..f820b73 100644
--- a/link.x
+++ b/link.x
@@ -43,7 +43,7 @@ SECTIONS
.data : ALIGN(4)
{
_sdata = .;
- *(.data .data.*);
+ *(.data .data.* .got);
_edata = ALIGN(4);
} > RAM AT > FLASH
Each one of those changes lead to a working binary. But I'm not sure if changing the link script is a proper solution for this issue or just a dirty workaround.
Maybe PIC code doesn't even make much sense for typical cortex-m use cases. But currently, this leads to hard to debug issues, as there isn't even a warning, just a broken binary.
So, just generating an error message when one tries to link PIC code would help, as well. But I have no idea how to achieve that.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.