Comments (12)
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.
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.
That implementation makes sense to me.
from stm32-bootloader.
Hi there,
You are pointing in the right direction, but the following statement is just simply not true in this form:
- 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.
There are more than one issue here
-
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 inuint8_t Bootloader_CheckForApplication(void)
function
- if that is the case, then I would add a new constant that is called something like (
-
Replace ~(RAM_SIZE-1) by ~(RAM_SIZE)
-
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.
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.
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.
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.
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.
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.
You are right, I have also made mistake. I completely agree.
from stm32-bootloader.
@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)
- Add command line argument to provide path to clang-format
- Add support for GNU Arm Embedded Toolchain
- Fix clang-format issue on CI HOT 1
- Add GCC build job to CI pipeline
- Add support for building the projects with scons
- Linker Script Question HOT 2
- Add stale bot to repository
- Add yamllint to repository HOT 1
- Update clang-format version to 11
- Add pull request template
- CI: Use docker image for jobs
- CI: Add style check job
- Support for STM32F4 series HOT 2
- How to build the firmware image HOT 4
- OTA firmware update on stm8s HOT 2
- Not an issue - a question - SCB->VTOR issue with F103? HOT 3
- use of stm32-Bbootloader HOT 1
- CI: Fix editorconfig-checker command not found issue
- HardFault at f_read HOT 1
- Is it a bug in function Bootloader_Erase()? HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from stm32-bootloader.