2011-09-21 08:35 AM
Hello everyone. This is my first time posting here and I am having issues with the IAP found here at STM's website. I am using Rowley Crossworks and the IAP files do not support that. Instead I created my own project and got the bootloader to run fine using USART communication. The first problem I ran into was when downloading my *.bin blinky program in FLASH_If_Write when it checks the data written to flash it was coming back and saying it did not match the SRAM content. I commented this out and was able to upload my whole bin file. If I look where blinky was written the code looks 100% fine. I am writing to 0x08008000 and my bootloader is at 0x08000000. I made sure the code doesn't overlap.
Now my real issue is jumping to the blinky application. The code sequence JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4); /* Jump to user application */ Jump_To_Application = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS); Jump_To_Application(); Jump address ends up pointing to location 0x08000351 and my debugger just goes to DEFAULT_ISR_HANDLER reset_wait in startup.s. Now I know my blinky app works as I tested stand alone. Two questions: While debugging should I expect the blinky app the execute after the jump? Has anyone experienced this or can provide an insight to what the issue maybe? Thanks in advance and sorry if anything I posted is confusing this is my first technical post.2011-09-22 10:42 AM
2011-09-22 11:04 AM
Could it be that the flash programming routine is actually overwriting RAM instead of programming flash. At some point the programming routines simply write the target value into a pointer so if that pointer is set wrong it would explain the corruption. Take a look at the FlashAddress in FLASH_If_Write to see if it's correct.
Andrew2011-09-22 11:10 AM
2011-09-22 11:30 AM
Here is a quick snippit. my buffer is 1024 bytes starting at 0x2000003c... when i get into flash write, r7 has the address 0x200001b0 ( within my buffer boundary )... when a push { r7, lr} is called that location is overwritten with the word in r7 and location 0x200001b3 gets the word in lr register. I am just confused as I havent worked with assembly code since 2003 and then is was only a few registers.
Here is a little bit of the assembly code: uint32_t FLASH_If_Write(__IO uint32_t* FlashAddress, uint32_t* Data ,uint16_t DataLength) { B580 push {r7, lr} B086 sub sp, sp, #24 AF00 add r7, sp, #0 60F8 str r0, [r7, #12] 60B9 str r1, [r7, #8] 4613 mov r3, r2 80FB strh r3, [r7, #6]2011-09-22 01:39 PM
The problem you're having is that your stack is insufficiently large for the number of local variables you're allocating against it. It would appear that it's descending into your heap and generally trashing the environment.
2011-09-23 05:29 AM
Clive,
Thanks again for your response. I seen in another thread you have some experience with Rowley Crossworks. I am assuming I can change the main and process stack sizes in the solution properties. I have tried different values ranging from 512 bytes to 1MB in both fields, as well as manipulating the heap size with the same results. No matter what size they are set to the same address in my buffer gets overwritten everytime. I did find this is in the thmb_crt0.s file: /* Setup attibutes of stack and heap sections so they don't take up room in the elf file */ .section .stack, ''wa'', %nobits .section .stack_process, ''wa'', %nobits .section .heap, ''wa'', %nobits Here is a section memory before the FLASH_If_Write is called: 0x20000158 | 0800031f, 08000321, 08000323, 08000325, 08000327, 08000329, 0800032b, 0800032d 0x20000178 | 0800032f, 08000331, 08000333, 08000335, 08000337, 08000339, 0800033b, 0800033d 0x20000198 | 0800033f, 468d4928, 49294828, f0004a29,4829f839, 4a2a4929, f834f0000, 492a4829 Afterwards: 0x20000158 is ok. 0x20000178 | 0800032f, 00000008, 20000184, 00000008, 20000190, 0800220d, 08008158, 08000080 0x20000198 | 40004800, 00000001, 200001a4, 080000118, 200001b0, 0800111b, 00000018, 200001bc The first word starting at 0x200001d8 also changes. The registers leaving flash write are: r0: 0x00000002 r1: 0x20000038 r2:0x08008158 r3: 0x00000002 r4: 0x0 r5: 0x0 r6: 0x0 r7: 0x200001bc r8-11: 0x0 sp(main): 0x200001bc sp(process): 0x0 lr: 0x080023ff pc: 0x21000000 Sorry to provide so much information I am just used to higher level programming with the older HC11's and I am new to the STM32s.2011-09-23 06:11 AM
OK. I believe I have solved the issue. I just declared nearly all the variables in the YModem Recieve fucntion as static and this seemed to take care of the issue! Not that I know exactly why... if anyone could elaborate.
Now I just need to figure out why blinky is not executing. Thanks for you insight guys.2011-09-23 07:30 AM
static will force an allocation of the memory in RAM by the linker, check the .MAP (or whatever) to see where this was actually situated, rather than decrementing the stack to accommodate the variables.
For Y-Modem I'd guess you were allocating a 1KB buffer. I don't have Rowley running on a box within reach right now, but will look to see how to specify the stack size. GCC typically sticks the stack at the top-of-RAM in the linker script, and the statics/heap at the front-of-RAM. Unless you malloc() too much memory they shouldn't meet. Now most of the Keil/ST example apps define a 1KB stack, and park it just beyond the end of the statics (within starup.s or whatever), this can cause problems with printf/scanf.2011-09-23 08:11 AM
Thanks again for the reply and explanation Clive. You have been a real help.
I gave the map a lookover and I noticed 0x00000080 __STACKSIZE__ = 0x80 as well as......stack 0x200009e8 0x80
0x200009e8 __stack_start__ = .
*(.stack .stack.*)
0x20000a68 . = ALIGN (MAX ((__stack_start__ + __STACKSIZE__), .), 0x4)
*fill* 0x200009e8 0x80 00
0x20000a68 __stack_end__ = (__stack_start__ + SIZEOF (.stack))
0x20000a68 __stack_load_end__ = __stack_end__
0x00000001 . = ASSERT (((__stack_end__ >= __RAM_segment_start__) && (__stack_end__ <= (__RAM_segment_start__ + 0x20000))), error: .stack is too large to fit in RAM memory segment)
0x20000a68 __stack_process_load_start__ = ALIGN (__stack_end__, 0x4)
I did apply a 1024 byte stack through the solution properties, which is what I was doing from the start, so I am curious why is only shows 0x80. Now I am wondering exectly what is happening here: #define APPLICATION_ADDRESS 0x08008000 JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4); /* Jump to user application */ Jump_To_Application = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS); Jump_To_Application(); I am hitting DEFAULT_ISR_HANDLER reset_wait everytime. The JumpAddress is 0x08000351. I have tried just doing: Jump_To_Application = (pFunction) 0x08008004; which it then hits the hardfault handler. In the assembly for Jump_To_Application I reach the blx r3. Where r3 is 0x08000351 and the reset wait is in the map file as 0x080000350. Do I need to provide some type of reset mechanism after my blinky(user code) is loaded/updated? Or should it actually just jump straight to main in blinky? Sorry for my ignorance as IAP is a pretty new concept to me. And I have tried loading Blinky in with the pre-loaded bootloader and the flash demo utility and it worked flawlessly. It would be great if that code was somewhere on the web so I could view it. Thanks again for you insight! Brad