0

I'm working on a bigger project in my Cortex M3 chip and I'm running low on the RAM. My proposed idea is, I need to make space in my RAM by removing the global variables on the bootloader code so that the RAM is cleared in the region after the bootloader jumps to the application code. I don't have direct access to the bootloader code in the chip, so I must change these global variables within the application code. How can I remove this global variables with custom_delete() function or any code . I use ARM cortex M3 (LPC1769).

To summarize, basically what I'm running is:


Custom_Delete ( ? ){

??

}

int foo[1000];

int main(){

/*
 Bootloader Code
*/

Custom_Delete ( foo ) // I'm trying to remove the "foo" variable once the bootloader code is executed and the application code is run.

SCB->VTOR = (APP_START_ADDRESS) & 0x1FFFFF80  // jump to application code

}
Flamador
  • 43
  • 1
  • 8
  • You had already asked the question previously here: https://stackoverflow.com/questions/63390349/delete-global-variable-in-c and it seems to be deleted. – Rohan Bari Aug 13 '20 at 10:18
  • 1
    First thing you should do is to get rid of naive `int` and similar. Replace them with the relevant fixed size variables from stdint.h. – Lundin Aug 13 '20 at 10:20
  • You can write your own `malloc` package that allows you to add chunks of free memory to the arena (like `free` but the chunk doesn't have to be `malloc`d previously). Once you are done with `foo`, you add it to the `malloc` arena. – n. m. could be an AI Aug 13 '20 at 11:15
  • 1
    This might help you: https://stackoverflow.com/questions/8832114/what-does-init-mean-in-the-linux-kernel-code – Cosinus Aug 13 '20 at 11:15

3 Answers3

4

Removing variables with static lifetime is not possible.

You might try to reuse the area.

  union {
    struct { // bootcode data
      int foo[100];
    };
    struct { // application data
      int var1;
      long var2;
    };
  } data;

The names of the members should be unique between boot code and application. Then you can use unnamed members and access the fields without extra level of nesting. Data that is used both by boot code and application must be placed outside that union. This approach has the drawback that you cannot initialize data of the application that is in the union. Only first field of the union (i.e. the boot code part) can be initialized.

Note:

This applies if you have the bootcode and the application in the same executable.

If both are created in independently, then you can just use tailored linker scripts to place data in same location. As soon as you pass controll to the applicatin, the memory layout of the boot code is no longer relevant. This also allows initialization of application data if the startup code for the application is run when starting the application. That is normally true if you build the application as an independent binary.

Gerhardh
  • 11,688
  • 4
  • 17
  • 39
  • 1
    I'd like to add that it's important in both approaches to make sure that initializer code for application variables is ran when switching from bootloader to application. – user694733 Aug 13 '20 at 10:34
  • You are right. Jumping to a fixed address seems to be a hint that the application is built independently as a full application. Should not be a problem then. In first approach it is not possible to initialize the second field of the union. This has to be done manually – Gerhardh Aug 13 '20 at 10:39
1

You could force the linker to put a global variable into an self defined section:

__attribute__ ((__section__(".init.text"))) int my_global[128];

Then you have to edit your linker script so that this section can be reused later.

Linux does that too: What does __init mean in the Linux kernel code?

Cosinus
  • 534
  • 4
  • 10
0

Arrays cannot be deleted, and since it is a global array, it is static and will exist until the program terminates.

The only solution I can see is something like this:

//int foo[1000];
int *foo;

int main(){
    foo = malloc(sizeof *foo * 1000);

/*
 Bootloader Code
*/

    free(foo);

    SCB->VTOR = (APP_START_ADDRESS) & 0x1FFFFF80  // jump to application code
}

You could possibly change the malloc to alloca and skip free. But then you need to move the alloca call inside the boot loader code. malloc allocates on the heap and alloca on the stack.

Another alternative is to simply rewrite the code so that the array simply is not global, but declared inside a function called by main().

klutt
  • 30,332
  • 17
  • 55
  • 95
  • 1
    While this can work, LPC1769 has only 64 kB of RAM. I would recommend disabling heap completely, and using approach in Gerhardh answer instead. – user694733 Aug 13 '20 at 10:37