Git Product home page Git Product logo

cortex-m-rt's People

Contributors

adamgreen avatar adamgreig avatar aurabindo avatar birkenfeld avatar bors[bot] avatar bytex64 avatar crawford avatar disasm avatar dtolnay avatar eldruin avatar guilucand avatar hug-dev avatar japaric avatar jduchniewicz avatar jonas-schievink avatar jonathanpallant avatar jordens avatar kjetilkjeka avatar korken89 avatar lulf avatar mattico avatar mciantyre avatar pftbest avatar sekineh avatar thejpster avatar therealprof avatar tiwalun avatar tstellanova avatar whitequark avatar yodaldevoid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cortex-m-rt's Issues

.bss allocated outside RAM

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.
sbss_ebss_error

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.

Linker errors with 0.5.2 and arm-none-eabi-gcc

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.

DefaultPreInit gets random address in debug mode [Stack pointer initialization issue]

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

Linking with LLD produces "Address ... is out of bounds" in the output of objdump

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.

Unable to upgrade to cortex-m 0.4.3

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.

Strange addresses when using both _stack_start and _heap_size

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.

Depend on a no_std compatible version of chrono

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

add some unsafe method to run code before RAM is initialized

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.

Reserve flash memory after .vector_table

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

  • Some MCU stores configurations right after .vector_table (for instance the NXP S32K series store flash configuration from 0x400-0x40C)
  • Reserving space for an alternative program (like a bootloader)

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?

null dereference before main is called

STR

#![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?

Support vector table relocation?

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.

Linker warning recommends a nonexistant `gcc::Config.fpic` method

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 the gcc crate
then modify your build script to compile the C code without the
-fPIC flag. See the documentation of the gcc::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.

Document default 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.

Linker script doesn't put .data into FLASH section, preventing overflow detection

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.

Interrupt handlers error

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 ...

Global offset table not initialized by bootstrap code.

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:

  • Either not compile the C library as PIC code. In my case, this was possible using gcc::Config::pic, which defaults to true.
  • Or add .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.

LLVM error on High Sierra

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.

(Zero cost) stack overflow protection

Today, the layout of RAM looks like this (assuming no heap and a single RAM region):

today

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:

ideal

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.

Implementation

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.

Other options for stack overflow protection

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.

arm-none-eabi-ld not working with v0.3.8

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`.

RFC: Provide defaults for `HardFault` and `DefaultHandler`?

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

Should we do this?

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.

What should the defaults be?

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:

  • CMSIS sets DefaultHandler (and HardFault) to an infinite loop.

Other considerations:

  • DefaultHandler and UserHardFault are stable unmangled symbols that one can place breakpoints
    at. So if you have a debugger attached to the device you can always catch hard fault and unhandled
    exceptions before the handlers are executed.

cc @therealprof @jcsoo @thejpster

Interrupt handlers discarded when compiling with (fat) LTO

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)

BAD: release profile (+LTO) - cortex-m-rt v0.6.3

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.

GOOD: release profile (no LTO) - cortex-m-rt v0.6.3

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"

GOOD - dev profile - cortex-m-rt v0.6.3

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

Static byte resources in .rodata are not properly aligned/padded

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

New cortex-m-rt rand dependency breaks builds

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.

default_handler! doesn't work

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

[RFC] make sections .bss and .data opt in

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.

Design

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.

Bonus

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.

Drawbacks

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.

cc @cr1901 @therealprof

Serious compile-time regression (1-2 min to 1 hour)

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?

Invalid .vector_table.exceptions section

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.

[RFC] [breaking-change] Turn entry!, exception! into attributes

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)

Unresolved questions

  • Choose a syntax for adding state to #[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).

Missing DebugMonitor Exception

According 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?

Exception configuration support?

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.

New `entry` attribute hides error locations

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?)

Compiling fails due to `compiler_builtins`

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.

LLD support (AKA LLD *almost* works out of the box)

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).

The reset, exception, and interrupt vectors are missing.

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)

Regression on 0.6 on rust messages with attribute macro

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 {}
}

Confused C Compiler Call

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.

Separate default handler for ADC_COMP emitted

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>

remove dependency on `compiler_builtins`

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.

Support a heap memory region

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?

[RFC] [breaking-change] don't depend on GCC by default

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

RAM initialization routines are huge

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 ?

cortex-m-rt doesn't build on Windows anymore

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.

arm-none-eabi-ld: The exception handlers are missing

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:

  • rustc 1.24.0-nightly (560a5da9f 2017-11-27)
  • xargo 0.3.8
  • cargo 0.24.0-nightly (abd137ad1 2017-11-12)

xargo

P.S. I'm new to rust embedded so this maybe something on my side

v0.6.5 lacks tag

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.