Keil Logo

UNINIT section gets initialized

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Details Message
Author
Antoine Gardiol
Posted
30-Oct-2018 08:01 GMT
Toolset
ARM
New! UNINIT section gets initialized

Hello,

I am trying to define an RAM area that should not be initialized by the C library init function. I found an old thread about that (http://www.keil.com/forum/11937/) but the proposed solution does not work.

I use a scatter file that define the section like that :

RW_BOOTLOADER 0x10000020 UNINIT 0x0000FFE0  {
        *.o (Bootram)
        *.o (Bootstack)
}

I try to define the area in assembly code or also in C code by :

BLStackSize     EQU     0x00004000
                AREA    Bootstack, NOINIT, READWRITE, ALIGN=3
BLStackMem      SPACE   BLStackSize
BLStackTop

U32 __attribute__((section("Bootstack"),zero_init)) Bootstack[0x1000];

In any case I get the following result in the map file :

    Execution Region RW_BOOTLOADER (Exec base: 0x10000020, Load base: 0x0001ef14, Size: 0x00005030, Max: 0x0000ffe0, ABSOLUTE, UNINIT, COMPRESSED[0x00000024])

    Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object

    0x10000020   COMPRESSED   0x00001030   Data   RW          328    Bootram             fiveco_bootloader.o
    0x10001050        -       0x00004000   Zero   RW          329    Bootstack           fiveco_bootloader.o

My understand is that any zero init or uninit area in any section with UNINIT keyword should not be initialized by the C lib as explained in http://www.keil.com/support/man/docs/armlink/armlink_pge1362075670305.htm

But tests with standard lib (or microlib) with Keil toolchain 5.24.1 show always an initialization by __scatter_zi.o object.

What is wrong in my approach ??

Many thanks by advance !
Antoine

Author
Ron Wedge
Posted
2-Nov-2018 06:38 GMT
Toolset
ARM
New! RE: UNINIT section gets initialized

Hello Antoine ,

What does your scatterfile (the file with the .sct extension) look like? What section of the scatterfile is your assembly code being placed?

Are these articles relevant to you?

http://www.keil.com/support/docs/3480.htm

http://www.keil.com/support/man/docs/armcc/armcc_chr1359124243221.htm.

Author
Antoine Gardiol
Posted
2-Nov-2018 09:46 GMT
Toolset
ARM
New! RE: UNINIT section gets initialized

Hi Ron,

Thanks for your reply.
I already read those articles and tried to solve this issue using them, but it does not change anything.

Here is my full scatter file :

LR_IROM1 0x00000000 0x00080000  {    ; load region size_region

        ER_BOOTLOADER 0x00000000 0x00001000 {
                *.o (BLRESET, +First)
                *.o (.bl_start)
                *.o (Bootloader)
        }

        RO_PARAMETERS0 0x00001000 FIXED 0x00001000 {
                *.o (ModuleParameters0, +First)
        }

        RO_PARAMETERS1 0x00002000 FIXED 0x00001000 {
                *.o (ModuleParameters1, +First)
        }

        ER_BOOT 0x00003000 FIXED 0x00000100 {
                *.o (MAINSTART, +First)
        }

        ; Following section needed to align vector table to a multiple of 256
        ER_ACTUAL 0x00003100 FIXED 0x0003CF00 {
                *.o (IRQVECT, +First)
                *(InRoot$$Sections)
                .ANY (+RO)
        }

        RW_BOOTLOADER 0x10000020 UNINIT 0x0000FFE0  {   ; Overlap RW_ACTUAL. Must be defined before RW_ACTUAL.
                *.o (Bootram)                                                           ; Use --diag_warning=L6221E linker cmd line option
                *.o (Bootstack)
        }

        RW_ACTUAL 0x10000020 0x0000FFE0  {
                .ANY (+RW, +ZI)
                file_config.o (+RW, +ZI)
        }

        RW_SUP_1 0x20000000 0x00004000  {
                .ANY (+RW, +ZI)
        }

        RW_SUP_2 0x20004000 0x00004000  {
                mci_*.o
                emac_*.o (+RW, +ZI)
                .ANY (+RW, +ZI)
        }
}

Please note that it is intended that RW_ACTUAL overlap RW_BOOTLOADER. That's the reason why I need that RW_BOOTLOADER region not to be initialized.

Thanks by advance.
Antoine

Author
Kevin From Support
Posted
2-Nov-2018 18:12 GMT
Toolset
ARM
New! RE: UNINIT section gets initialized

From this page:

http://www.keil.com/support/man/docs/armclang_asm/armclang_asm_dom1361290002714.htm

We see that

NOINIT Indicates that the data section is uninitialized, or initialized to zero... You can decide at link time whether an area is uninitialized or zero-initialized.

To choose at linker time how this is handled use the bss_threshold command:

http://www.keil.com/support/man/docs/armcc/armcc_chr1359124903636.htm

This page has an example of setting bss_threshold

http://www.keil.com/support/man/docs/armcc/armcc_chr1359124243221.htm

an except:

"Specify --bss_threshold=0 when compiling this example code, to ensure that k and l are placed in a ZI data section. If --bss_threshold=0 is not used, section name rwdata must be used instead of zidata."

Author
Antoine Gardiol
Posted
6-Nov-2018 15:59 GMT
Toolset
ARM
New! RE: UNINIT section gets initialized

Hi Kevin,

Thanks for your answer. Unfortunately, it is exactly what I already tried.

In fact, as explained in article, --bss_threshold=0 is intended to force compiler to place "small global ZI data items in ZI data sections". My area is not small at all.
Additionally, my area is specified in an assembly file and not in C file. So compiler is not used.

In the first article, as you wrote, it is explained that NOINIT keyword in AREA tell "NOINIT Indicates that the data section is uninitialized, or initialized to zero... You can decide at link time whether an area is uninitialized or zero-initialized.".

But, HOW can I tell the linker to not init this space to zero ? As I understand, the UNINIT keyword in scatter file should do the job. Am I wrong ?

Thanks again by advance.
Antoine

Author
Robert McNamara
Posted
6-Nov-2018 19:21 GMT
Toolset
ARM
New! RE: UNINIT section gets initialized
        RW_BOOTLOADER 0x10000020 UNINIT 0x0000FFE0  {   ; Overlap RW_ACTUAL. Must be defined before RW_ACTUAL.
                *.o (Bootram)                                                           ; Use --diag_warning=L6221E linker cmd line option
                *.o (Bootstack)
        }

        RW_ACTUAL 0x10000020 0x0000FFE0  {
                .ANY (+RW, +ZI)
                file_config.o (+RW, +ZI)
        }

There is something I am not understanding here. Here is what I would expect to happen before main

1) Bootram would be initialized to appropriate values

2) Bootstack would not be initialized to zero

3) RW_ACTUAL .ANY would be initialized (to zero or values) It seems to me that it is highly likely that variables in RW_ACTUAL are at the same location as variables from RW_BOOTLOADER. (You would see this in the map file and see if this is the case.

4) file_config.o would have already matched the .ANY section and would have been located and initialized based the .ANY rules.

Are you expecting something different and if so, what is it that you are expecting.

I think the Error L6221E was there for a reason and would require some work to make sure everything in the overlapping regions worked correctly when you changed it to a warning.

Author
Antoine Gardiol
Posted
7-Nov-2018 10:11 GMT
Toolset
ARM
New! RE: UNINIT section gets initialized

Hi Robert,

Your understanding is nearly correct. Bootram and bootstack are used in a pre-main code et are no more used in main code. It is why the two regions can overlap and so, yes I now what I do when I turn error L6221E to a warning.

But since the initialization is done by the call to __main function of Keil lib, the bootram and bootstack are not initialized at startup because I use them before that call.

It is so why I do not want them to be initialized by the lib, since they are no more useful at that time.

So, in your points :
1) Yes, but it is done by my code and not by the lib.
2) Yes, it is correct before main code. But it is initialized later when calling __main and it is what I try to avoid.
3) Yes and overlap is under control.
4) It is not relevant for my problem, but to be clear, since their is 3 regions with .ANY, this force the linker to put file_config object in this one (due to limitations of NXP LPC RAM architecture).

I hope that I am clear.

Thanks.
Antoine

Author
Rom Wedge
Posted
7-Nov-2018 15:00 GMT
Toolset
ARM
New! RE: UNINIT section gets initialized

It sounds like you might need to overlay directive

http://www.keil.com/support/docs/3723.htm

Author
Robert McNamara
Posted
7-Nov-2018 16:20 GMT
Toolset
ARM
New! RE: UNINIT section gets initialized

That helps some.

1) Yes, but it is done by my code and not by the lib.

OK, you initialize Bootram yourself, but when __scatter is called (as part of calling __main) it seems like it will will be initialized again.

2) Yes, it is correct before main code. But it is initialized later when calling __main and it is what I try to avoid.

It appears as if you are doing it correct such that Bootstack will not be zero initialized and Bootram will be re-initialized when __main is called. Please just verify that BootRam is being initialized and that even though I think Bootstack should not be initialized to 0, it is being initialized to zero. (obviously if you are still using that stack, having it set back to zero is an issue)

Author
Robert McNamara
Posted
7-Nov-2018 21:27 GMT
Toolset
ARM
New! RE: UNINIT section gets initialized

Only ZI data in UNINIT sections remain un-initialized, however any RW data in the UNINIT section does get initialized.

Everything posted so far addresses how to make a Zero Init section to not initialize. It explains why if your Zero Init data gets optimized into a RW region that even though you said it should not be initialized, it will still be initialized.

Author
Antoine Gardiol
Posted
9-Nov-2018 08:37 GMT
Toolset
ARM
New! RE: UNINIT section gets initialized

Problem did not exist!

Hi,
Thanks all for your help. After further analysis I found that the problem did not exist.
The keyword UNINIT in the scatter file with the keyword NOINIT in the assembly area (as explained in my first message of this thread) do the job very well. My test case was not well done and the memory was cleared by another source.

Note that --bss_threshold=0 is also useless.

Sorry for that.
Thanks again.

Best regards,
Antoine

Next Thread | Thread List | Previous Thread Start a Thread | Settings

  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.