cancel
Showing results for 
Search instead for 
Did you mean: 

How to Use a Variable in SRAM to Communicate between Bootloader and Application

Chao
Senior

Hi,

I have a bootloader for my application, at the moment they exchange their working status by flash write. I think a better way is to declare a variable in RAM with the same address in both bootloader and application. Someone mentioned, in a post, that the linker script could be used for this, but didn't give an example.

Anybody could do me a favour and show me an example ? Thanks.

1 ACCEPTED SOLUTION

Accepted Solutions

Set the memory origin at 0x20000004 and your common variable at 0x20000000.

 

_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */

/* Memories definition */
MEMORY
{
...
RAM (xrw) : ORIGIN = 0x20000004, LENGTH = 49152 /* 48K - 4 bytes*/
...
}

 

#define COMMON_VAR_ADDRESS 0x20000000 /* Define a common RAM address */

uint32_t* common_var = (uint32_t*)COMMON_VAR_ADDRESS; /* Declare a pointer at that address */
*common_var = y; /* access to that address */
To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

View solution in original post

11 REPLIES 11
SofLit
ST Employee

@Chao wrote:

Someone mentioned, in a post, that the linker script could be used for this, but didn't give an example.

Anybody could do me a favour and show me an example ? Thanks.


Using __attribute . See this link: https://www.openstm32.org/Using%2BCCM%2BMemory

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
MM..1
Chief II

Maybe we require info how working status you mean... And most simple method to share is move start RAM +somethink for example 0x20000020 and use direct pointers to 0-1F arrea. 

Yes @MM..1 it could be also a solution.

 

 

#define COMMON_VAR_ADDRESS 0x2000XXXX /* Define a common RAM address */

uint32_t* common_var = (uint32_t*)COMMON_VAR_ADDRESS; /* Declare a pointer at that address */
*common_var = y; /* access to that address */

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Many thanks to @SofLit  and @MM..1 .

Is the way given in the example safe? How could we be sure that the variable  value would not be modified by other part of the bootloader code and app code? The both code are written in C++.


@Chao wrote:

Is the way given in the example safe? How could we be sure that the variable  value would not be modified by other part of the bootloader code and app code? The both code are written in C++.


For the second example (using pointers), it's up to you to ensure and select an address that will not be accessible by other parts of bootloader and application. For example, the last RAM address that the linker doesn't include it in the RAM range declaration.

For the first case (using the linker), no need to take care about this as it's already managed by it.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Hi @SofLit ,

For the first case (using the linker), I read the doc you suggested, it's all about the use of CCM, and I checked the reference manuals of F103 and F407, and found F103 doesn't have CCM though F407 has 64KB CCM.

For the second example (using pointers), it looks like a good solution if we could change the value of _estack in the linker script. At the moment, _estack = 0x2000C000 for F103 with 48KB SRAM, would it have any negative impact if change _estack to 0x2000BFFC in the linker script with #define COMMON_VAR_ADDRESS 0x2000BFFC defined in both bootloader and application?

Hello,


@Chao wrote:

For the first case (using the linker), I read the doc you suggested, it's all about the use of CCM, and I checked the reference manuals of F103 and F407, and found F103 doesn't have CCM though F407 has 64KB CCM.


CCM RAM (Core Coupled Memory RAM) is a RAM managed as any regular SRAM. So the method applies to any SRAM.

 


@Chao wrote:

For the second example (using pointers), it looks like a good solution if we could change the value of _estack in the linker script. At the moment, _estack = 0x2000C000 for F103 with 48KB SRAM, would it have any negative impact if change _estack to 0x2000BFFC in the linker script with #define COMMON_VAR_ADDRESS 0x2000BFFC defined in both bootloader and application?


The stack is decrementing and the stack start address (the bottom of the stack), corresponds to the largest address. So the variable address you need to set needs to be > the Stack start address otherwise your application will crash.

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

there is one thing I don't understand: the largest address of the SRAM in F103RC should be 0x2000BFFF, but _estack = 0x2000C000 in the linker script, so I set _estack = 0x2000C000 - 4 = 0x2000BFFC, if I set the COMMON_VAR_ADDRESS to one that is greater than 0x2000BFFC, then I won't get 4 bytes for the variable which contradicts to the fact that I have told the linker to reserve 4 bytes on the bottom of the SRAM.  What's wrong?

Set the memory origin at 0x20000004 and your common variable at 0x20000000.

 

_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */

/* Memories definition */
MEMORY
{
...
RAM (xrw) : ORIGIN = 0x20000004, LENGTH = 49152 /* 48K - 4 bytes*/
...
}

 

#define COMMON_VAR_ADDRESS 0x20000000 /* Define a common RAM address */

uint32_t* common_var = (uint32_t*)COMMON_VAR_ADDRESS; /* Declare a pointer at that address */
*common_var = y; /* access to that address */
To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.