Giter VIP home page Giter VIP logo

Comments (12)

Rotule666 avatar Rotule666 commented on May 10, 2024 2

I am using this successfuly on multiple applications :
return ( ((*(__IO uint32_t*)APP_ADDRESS) - RAM_SIZE) == 0x20000000 ) ? BL_OK : BL_NO_APP;

I updated it in my implementation of the bootloader (in which I use CAN) but never raised the issue, I remember I had troubles with it.

from stm32-bootloader.

akospasztor avatar akospasztor commented on May 10, 2024 2

Hi guys, thanks for the comments.

@kubasaw: I just looked into the issue you mentioned, and you're right. The location of the stack pointer is set to the upper boundary of the RAM, seemingly 4byte outside of the RAM space (0x0020 0000). However, when there is a push instruction, the core first decreases the value of the stack pointer and then writes to the (already decreased) location. Therefore, having an initial stack pointer at 0x20200000 is valid.

I would like to point out that @Rotule666 's solution is correct, as long as the stack pointer is always configured at the end of the RAM region. However, be careful, as this is not the case if there is a custom placement, or another compiler is used (e.g. iar, armcc, etc.), and this can lead to problems. Therefore, I would advise to use the following check (<= instead of <):

return (((*(uint32_t*)APP_ADDRESS) - RAM_BASE) <= RAM_SIZE) ? BL_OK : BL_NO_APP;

I will incorporate this change in the next release.

from stm32-bootloader.

KonstantinBerezenko avatar KonstantinBerezenko commented on May 10, 2024 1

That implementation makes sense to me.

from stm32-bootloader.

akospasztor avatar akospasztor commented on May 10, 2024 1

Hi there,

You are pointing in the right direction, but the following statement is just simply not true in this form:

  1. APP_ADDRESS is the start address of the FLASH, whereas (I guess) it should be the end address of the RAM, i.e. 0x20000000 + 0x00040000 = 0x20040000 (see the info below from the .map file)

The APP_ADDRESS indicates the start address of the application firmware. The very first 32bit value (DWORD) of the firmware (which is actually the value pointed by the APP_ADDRESS) is the stack pointer location of the application firmware. This must be within the RAM range, which is somewhere between 0x20000000 and 0x20040000 in this case.

There is a next release coming up (i'm currently working full-time, so please understand that maintaining my open-source projects has a bit lower priority nowadays), which already includes a fix for this particular issue. (Over the past couple of months I've noticed that there are many comments and emails regarding this particular topic, furthermore other MCU's don't necessarily have the start of RAM address at 0x20000000, therefore I decided to rewrite this section.) It hasn't been tested out properly yet, but if you are eager to check it out, please take a look at the development branch :)

from stm32-bootloader.

pycan avatar pycan commented on May 10, 2024

There are more than one issue here

  1. APP_ADDRESS is the start address of the FLASH, whereas (I guess) it should be the end address of the RAM, i.e. 0x20000000 + 0x00040000 = 0x20040000 (see the info below from the .map file)

    • if that is the case, then I would add a new constant that is called something like (#define RAM_END_ADDRESS (uint32_t)0x20040000 ) and use it instead of APP_ADDRESS in uint8_t Bootloader_CheckForApplication(void) function
  2. Replace ~(RAM_SIZE-1) by ~(RAM_SIZE)

  3. should *(__IO uint32_t*) be removed?

Finally, this line would look like this

return (((RAM_END_ADDRESS & (~RAM_SIZE)) == (uint32_t)0x20000000 ) ? BL_OK : BL_NO_APP);

But the question now why would you need this function at all if the application is on the FLASH and not on the RAM?

.map info

Name             Origin             Length             Attributes
FLASH            0x0800c000         0x000f4000         xr
RAM              0x20000000         0x00040000         xrw
MEMORY_B1        0x60000000         0x00000000         xr
CCMRAM           0x10000000         0x00010000         rw
*default*        0x00000000         0xffffffff

Updated based on akospasztor's answer (here)

Thank you Akos for your reply.

I could not find the new implementation of this section in the develop branch, they look similar (maybe not pushed to the remote repo yet?)

In either case, I have updated this function in my code to what is shown below

return (((*(__IO uint32_t*)APP_ADDRESS & (~RAM_SIZE-1)) <= (uint32_t)(0x20000000+RAM_SIZE)) ? BL_OK : BL_NO_APP);

from stm32-bootloader.

akospasztor avatar akospasztor commented on May 10, 2024

Thank you Akos for your reply.

I could not find the new implementation of this section in the develop branch, they look similar (maybe not pushed to the remote repo yet?)

Yeah, sorry, you are absolutely right. I haven't pushed my local repo yet, as it has currently many new branches with new and experimental stuff :D As my free/time allows in the next couple of days, I will sort out my locals and push the changes. As many curious people - like you :) - want to see new stuff (which i'm always happy for), I just don't want to publish anything even to the develop branch without basic working functionality.

from stm32-bootloader.

kubasaw avatar kubasaw commented on May 10, 2024

Hi,
First of all, I want to thank you @akospasztor for publishing well commented code, what helped me a lot to understand more or less, code execution workflow on the STM.

I have some issue with porting Bootloader to STM32F446. On this MCU, there is 128KB (0x0020 0000) of SRAM available, starting at: 0x2000 0000, so the last byte of RAM is placed at: 0x201F FFFF.
For every application code which I have generated by arm-none-eabi-gcc the first DWORD is set to 0x2020 0000 what causing false evaluation of condition (0x0020 0000<0x0020 0000) in CheckForApplication.

The condition proposed by @Rotule666:
return ( ((*(__IO uint32_t*)APP_ADDRESS) - RAM_SIZE) == 0x20000000 ) ? BL_OK : BL_NO_APP;
seems correct for me in contrast to:
return (((*(uint32_t*)APP_ADDRESS) - RAM_BASE) < RAM_SIZE) ? BL_OK : BL_NO_APP;
in the v1.1.0 code.

Where I make a mistake in my way of thinking?

from stm32-bootloader.

Rotule666 avatar Rotule666 commented on May 10, 2024

@kubasaw

return ( ((*(__IO uint32_t*)APP_ADDRESS) - RAM_SIZE) == 0x20000000 ) ? BL_OK : BL_NO_APP;

this always worked out for me except for the H7

A good trick to check what should be in there is to flash your application and check at APP_ADDRESS usinf st-link utility.

from stm32-bootloader.

kubasaw avatar kubasaw commented on May 10, 2024

Hi,
Thank you @akospasztor for your confirmation, but one more question arises. We want to check if stack pointer is set to point at RAM region, is (((*(uint32_t*)APP_ADDRESS) - RAM_BASE) <= RAM_SIZE) a correct comparison?
When we change comparison operator from < to <= it virtually increases RAM_SIZE by 1, so in my opinion, in extremal case, when stack pointer is set to RAM_BASE, after push it will point at other (not valid) region.
In my opinion, (((*(uint32_t*)APP_ADDRESS) - RAM_BASE-1) < RAM_SIZE) will be better solution ;)

from stm32-bootloader.

akospasztor avatar akospasztor commented on May 10, 2024

The stack pointer location cannot be set to the RAM_BASE, because the stack grows "downwards", i.e. decreases. Therefore, it must be greater (at least 4 bytes) than the RAM_BASE.

~~Secondly, if a microcontroller has the RAM_BASE mapped to 0x0000 0000 (instead of 0x2000 0000), then your proposed solution would cause an overflow. ~~

Edit: sorry, my mistake regarding the above lines. The overflow would happen if you had the parentheses around RAM_BASE-1. If you don't have, then essentially your solution mathematically is the same as mine.

from stm32-bootloader.

kubasaw avatar kubasaw commented on May 10, 2024

You are right, I have also made mistake. I completely agree.

from stm32-bootloader.

Rotule666 avatar Rotule666 commented on May 10, 2024

@akospasztor I agree 100%, this is therefore why I had to change it for my project for H7 where I have put the Stack in DTCM RAM

good job :)

from stm32-bootloader.

Related Issues (20)

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.