2014-03-21 02:34 AM
hello,
I know that I should post this in Coocox forum, but I what to know if one of STM32 users faced this issue before:I have a strange issue with Coocox (COIDE V1.7.6), it may be a bug:
- Optimization is set to -O0,here is part of my code that causes the issue : Inside a function, I have declared a local variabes as volatile :
*****************************************************************************
volatile uint32_t tmpcounter = 0x00, indexoffset = 0x00;
volatile uint32_t counterread = 0x00;/* Read flash memory */
while ((indexoffset != USER_FLASH_SIZE) && (HCD_IsDeviceConnected(&USB_OTG_Core) == 1)) { for (counterread = 0; counterread < BUFFER_SIZE; counterread++) { /* Check the read bytes versus the end of flash */ if (indexoffset + counterread != USER_FLASH_SIZE) { tmpcounter = counterread; RAM_Buf[tmpcounter] = (*(uint8_t*)(address++)); } /* In this case all flash was read */ else { break; } } /* Write buffer to file */ f_write (&file, RAM_Buf, BUFFER_SIZE, (void *)&bytesWritten); /* Number of byte written */ indexoffset = indexoffset + counterread;*****************************************************************
When reaching the last line and before executing it : ''indexoffset = indexoffset + counterread;'' I see that counterread is equal to 0 which is wrong (it should be equal to BUFFER_SIZE )
If I declared ''indexoffse'' and ''counterread'' without being volatile the issue is solved.
If I declared ''indexoffse'' and ''counterread'' as volatile but global variables , the issue is also solved.
I can't understand it ? it may be a bug is COIDE ?
Thanks,
franco
#volatile #stm32f4 #coide #coocox #fwupgrade-volatile-stack-fault2014-03-21 03:54 AM
Hi
Why are you declaring a local variable as 'volatile'? Do you understand what the volatile keyword does? (Therefore why it is used for certain scenarios) I do not think using volatile for a local variable which is only used for a loop counter is appropriate or valid use in this case.2014-03-21 06:46 AM
Perhaps not, but it should be innocuous.
CooCox didn't write the compiler, understand what version of the GNU/GCC compiler is being used here. Review the assembler generated, if it's incorrect, then provide an analysis and post it to a compiler mailing list (if it occurs with the CURRENT version of the GNU/GCC compiler), or the CooCox forum.2014-03-21 08:52 AM
Thanks Clive,
I'm using this version: GNU Tools ARM Embedded\4.8 2013q4\bin2014-03-21 09:16 AM
Your code lacks adequate context to analyze.
Could it be that your stack just isn't big enough? In the non-volatile sense the values will likely be held in registers. In the global sense the memory will not be on the stack. In the local-volatile sense the variables will likely be on the stack and read/written at each usage, corruption of the stack would be more evident. Perhaps the comparison/break causes it to leave one of the loops early? The other loop lacks scope.2015-05-26 06:36 AM
I had the same problem. The example above is the firmware upgrade from
STM32CubeF4/Projects/STM32F429I-Discovery/Applications/USB_Host/FWupgrade_Standalone/Src/command.c The volatile is defined in the __IO directive. If i declare counterread as not volatile it works. Else it looses his value after calling function f_write(). If it is declared as volatile the variable is stored (at my project) at 0x2002ffd0 - this is near the stack. If i move the declaration (with volatile) from local to global it works also. So i get the same result like franco! Dont't know why this is declared as volatile - but regardless, it should work also with volatile. Is there a bug in the linker file, that stack overlaps with sram? I stored ''RAM_Buf'' in the external SD-RAM, but also with this i get the same result. I have another application which is much bigger in size (~300k binary), also with volatile variables - there is no problem. Is there already an solution or what is the cause? I use gcc-arm-none-eabi-4_8-2013q4 with eclipse (no CoIDE,...) and ST-Link v2 with openocd.2015-05-26 10:25 AM
I wouldn't attribute compiler/linker bugs to half-assed allocation of heap/stack within the memory arena.
There's a habit in GNU/GCC circles to assign the stack address in the linker script and arbitrarily stick it at the end of memory, hoping to catch errors with section definitions. In more considered implementations the stack and heap space is allocated within a specific section, and left to the linker manage the exact address it's placed at along with all the other items it has to fix. This won't of course protect you if your stack allocation is inadequately sized for the call tree, but the linker will flag that you have over-subscribed the memory arena.2015-06-01 11:38 PM
Here is my Linker Script (see attachment). It's the same which i use for application - except the lines:
/* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128k /* 2048K - bootloader is about 48k */ USER_APP(rx) : ORIGIN = 0x08020000, LENGTH = 2048K-128k RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K /* SRAM */ CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K /* Core Coupled Memory - must enable clock */ } The Linker script for the application has these lines: /* Specify the memory areas */ MEMORY { BOOT_SKIP (rx) : ORIGIN = 0x08000000, LENGTH = 128K /* keep in mind erase size of flash */ FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 2048K-128K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K } ________________ Attachments : STM32F429ZI_FLASH.ld : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0RU&d=%2Fa%2F0X0000000bac%2FttTFrYc1WVM680BBKxDArJ33nMu83HU_KW01mdmLfQ0&asPdf=false