Jump to page: 1 2 3
Thread overview
Cortex-M3 low level assert issue.
May 01, 2019
Jack Applegame
May 02, 2019
kinke
May 02, 2019
David Nadlinger
May 04, 2019
Jack Applegame
May 04, 2019
kinke
May 04, 2019
Jack Applegame
May 04, 2019
kinke
May 05, 2019
Jack Applegame
May 05, 2019
David Nadlinger
May 05, 2019
Mike Franklin
May 05, 2019
David Nadlinger
May 08, 2019
Jack Applegame
May 08, 2019
kinke
May 09, 2019
Jack Applegame
May 09, 2019
kinke
May 03, 2019
Mike Franklin
May 03, 2019
Mike Franklin
May 03, 2019
kinke
May 04, 2019
Mike Franklin
May 04, 2019
kinke
May 04, 2019
Jack Applegame
May 01, 2019
file test.d:

```
module test;

struct Foo {
    struct Bar {
        struct Baz {
        }
    }
}

void foo() {
    assert(0);
}
```

compile and dump:

```
$ ldc2 -c -mtriple=thumb-none-linux-eabi -mcpu=cortex-m3 test.d
$ arm-none-eabi-objdump -dhsS test.o > test.o.dump
```

LDC compiles `assert(0)` to `_d_assert(file, line)` call and puts file name (test.d) to section `.rodata.str1.1`:

```
Contents of section .rodata.str1.1:
 0000 74657374 2e466f6f 2e426172 00746573  test.Foo.Bar.tes
 0010 742e466f 6f007465 73742e64 00        t.Foo.test.d.
```

The problem is that this section also contains symbols `test.Foo.Bar` and `test.Foo`. I don't know why these symbols are needed, but they are definitely not used in the program. And because they are in the same section as `test.d`, this whole section goes into firmware.

In my real application, such useless data occupy an unacceptable amount of flash memory of the MCU. It would be nice to get rid of them.

May 02, 2019
On Wednesday, 1 May 2019 at 21:55:09 UTC, Jack Applegame wrote:
> In my real application, such useless data occupy an unacceptable amount of flash memory of the MCU. It would be nice to get rid of them.

That's what -betterC is for (omit ModuleInfos, TypeInfos etc.). If that's not an option, you can also hack your object.d and try to remove TypeInfo, ModuleInfo etc. We also have LDC-specific pragmas wrt. this.
May 02, 2019
On Thursday, 2 May 2019 at 09:24:00 UTC, kinke wrote:
> On Wednesday, 1 May 2019 at 21:55:09 UTC, Jack Applegame wrote:
>> In my real application, such useless data occupy an unacceptable amount of flash memory of the MCU. It would be nice to get rid of them.
>
> That's what -betterC is for (omit ModuleInfos, TypeInfos etc.). If that's not an option, you can also hack your object.d and try to remove TypeInfo, ModuleInfo etc. We also have LDC-specific pragmas wrt. this.

True, but shouldn't gc-sections (with llvm::TargetOptions::DataSections == true) take care of eliminating the unused strings?

 — David
May 03, 2019
On Wednesday, 1 May 2019 at 21:55:09 UTC, Jack Applegame wrote:

> LDC compiles `assert(0)` to `_d_assert(file, line)` call and puts file name (test.d) to section `.rodata.str1.1`:
>
> ```
> Contents of section .rodata.str1.1:
>  0000 74657374 2e466f6f 2e426172 00746573  test.Foo.Bar.tes
>  0010 742e466f 6f007465 73742e64 00        t.Foo.test.d.
> ```
>
> The problem is that this section also contains symbols `test.Foo.Bar` and `test.Foo`. I don't know why these symbols are needed, but they are definitely not used in the program. And because they are in the same section as `test.d`, this whole section goes into firmware.
>
> In my real application, such useless data occupy an unacceptable amount of flash memory of the MCU. It would be nice to get rid of them.

If you'd like to see a more complete cortex-m project, please see https://github.com/JinShil/stm32f42_discovery_demo

You can see how I compile with ldc2 at https://github.com/JinShil/stm32f42_discovery_demo/blob/2f6419de1c30179a85c07e0bf1e3ddd026ace93c/build.d#L78-L88

The technique I use in that project is to create my own minimal runtime: https://github.com/JinShil/stm32f42_discovery_demo/tree/master/source/runtime It just contains the runtime implementations that I need; nothing more.

If you want to have support for asserts, you'll have to implement the runtime hooks as shown here:  https://github.com/JinShil/stm32f42_discovery_demo/blob/master/source/runtime/exception.d

Note that it's ok for your .o files be full of junk.  They can be stripped out at link time with the `--gc-sections` flag.  Just be sure you're compiling with `-ffunction-sections` and `-fdata-sections` for `--gc-sections` to work well.

Question for LDC developers:  Are the above compiler flags enabled by default?  How can one confirm?

You can start your minimal runtime project with just an empty `object.d`:

object.d
```
module object;
```

test.d
```
module test;

struct Foo {
    struct Bar {
        struct Baz {
        }
    }
}

void foo() {
    assert(0);
}
```

```
ldc2 -conf= -c -mtriple=thumb-none--eabi -mcpu=cortex-m3 test.d
arm-none-eabi-size test.o
   text    data     bss     dec     hex filename
     48       0       0      48      30 test.o
```

Compare that without the object.d.  When the compiler detects a local object.d file, it will use it instead of the runtime.  The `-conf=` tells the compiler not to use the default configuration that imports the runtime that comes bundled with the compiler.  Compile with `-v` and compare with and without the `-conf=` flag to see the difference.

If this just prompts more questions, let them fly.

Mike
May 03, 2019
On Friday, 3 May 2019 at 03:00:43 UTC, Mike Franklin wrote:

> Note that it's ok for your .o files be full of junk.  They can be stripped out at link time with the `--gc-sections` flag.  Just be sure you're compiling with `-ffunction-sections` and `-fdata-sections` for `--gc-sections` to work well.
>
> Question for LDC developers:  Are the above compiler flags enabled by default?  How can one confirm?

This looks relevant:  https://github.com/ldc-developers/ldc/blob/c81a0c94e535c3d670a4fab7aca9b1de22c3778c/driver/targetmachine.cpp#L472-L481

Mike
May 03, 2019
On Friday, 3 May 2019 at 03:18:00 UTC, Mike Franklin wrote:
>> Question for LDC developers:  Are the above compiler flags enabled by default?  How can one confirm?
>
> This looks relevant:  https://github.com/ldc-developers/ldc/blob/c81a0c94e535c3d670a4fab7aca9b1de22c3778c/driver/targetmachine.cpp#L472-L481

Yep, and this for the linker cmdline:
https://github.com/ldc-developers/ldc/blob/13cc3c4ed2f4e77096313916e55ce460f9dd1ddc/driver/linker-gcc.cpp#L535-L543

So yes, these are the default settings for Linux targets (the linker-strip-dead option is enabled by default), even for debug builds. For non-Linux targets, we rely on the LLVM defaults wrt. func/data sections; --gc-section is definitely only used for Linux targets though (use `-v` in the LDC cmdline to print the linker cmdline).

May 04, 2019
On Friday, 3 May 2019 at 16:31:34 UTC, kinke wrote:
> On Friday, 3 May 2019 at 03:18:00 UTC, Mike Franklin wrote:
>>> Question for LDC developers:  Are the above compiler flags enabled by default?  How can one confirm?
>>
>> This looks relevant:  https://github.com/ldc-developers/ldc/blob/c81a0c94e535c3d670a4fab7aca9b1de22c3778c/driver/targetmachine.cpp#L472-L481
>
> Yep, and this for the linker cmdline:
> https://github.com/ldc-developers/ldc/blob/13cc3c4ed2f4e77096313916e55ce460f9dd1ddc/driver/linker-gcc.cpp#L535-L543
>
> So yes, these are the default settings for Linux targets (the linker-strip-dead option is enabled by default), even for debug builds. For non-Linux targets, we rely on the LLVM defaults wrt. func/data sections; --gc-section is definitely only used for Linux targets though (use `-v` in the LDC cmdline to print the linker cmdline).

What about `arm-none-eabi`?  There's no "linux" in that triple.  Is there any way to pass the equivalent of `-ffunction-sections` and `-fdata-sections` on the ldc2 command line?
May 04, 2019
On Saturday, 4 May 2019 at 00:51:16 UTC, Mike Franklin wrote:
>  Is there any way to pass the equivalent of `-ffunction-sections` and `-fdata-sections` on the ldc2 command line?

Yep, just strip the `f` prefix - `ldc2 -help-hidden | grep sections`
May 04, 2019
On Thursday, 2 May 2019 at 09:24:00 UTC, kinke wrote:
> If that's not an option, you can also hack your object.d and try to remove TypeInfo, ModuleInfo etc. We also have LDC-specific pragmas wrt. this.
```
module test;
pragma(LDC_no_moduleinfo);

pragma(LDC_no_typeinfo)
struct Foo {
    pragma(LDC_no_typeinfo)
    struct Bar {
        pragma(LDC_no_typeinfo)
        struct Baz {
        }
    }
}

void foo() {
    assert(0);
}
```
Nothing changes.
May 04, 2019
On Friday, 3 May 2019 at 03:00:43 UTC, Mike Franklin wrote:
> Note that it's ok for your .o files be full of junk.  They can be stripped out at link time with the `--gc-sections` flag.  Just be sure you're compiling with `-ffunction-sections` and `-fdata-sections` for `--gc-sections` to work well.

I'm already using `--gc-sections` flag.
The junk gets into the same section as useful data. In this case `--gc-sections` flag doesn't help.
Also `-data-sections` and `-function-sections` doesn't help too.

> ldc2 -conf= -c -mtriple=thumb-none--eabi -mcpu=cortex-m3 test.d

Wow! Result looks nice. Thanks. But unfortunately `-conf=` flag also makes impossible to use the standard library at compile time.

I was also inspired by your `MMIO` library. Great idea! By the way, I personally prefer to use `interface` instead of `final abstract class`.
« First   ‹ Prev
1 2 3