actuino / stm32flash

Automatically exported from code.google.com/p/stm32flash
0 stars 0 forks source link

[patch] Reset code, STM32F3 & STM32F0 support, small improvements #34

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Hi,

I've fixed & added this to stm32flash:
 * new reset code common for Cortex-M0, Cortex-M3, Cortex-M4(untested)
 * support for STM32F3(untested) and STM32F0 family
 * new option -o for erase only operation
 * -e 0 option now work correctly

Greetings,
Daniel Strnad

Original issue reported on code.google.com by strna...@gmail.com on 31 Oct 2012 at 8:05

Attachments:

GoogleCodeExporter commented 9 years ago
In absence of the maintainer, I have set up a git repository where I will try 
to incorporate all outstanding patches: 
https://gitorious.org/stm32flash/stm32flash#more

But before your changes can be applied, they need to be split up into separate 
patches for each logical change. Using git, you can use "git add -p" to add 
selected hunks to each commit. Please use "git format-patch" to produce patch 
files, including a name/e-mail address for patch authorship.

These changes should be split among at least 4 commits. Don't worry about a 
patch becoming very small, it just makes it easier to apply it to different 
trees.

Original comment by lists.to...@gmail.com on 17 Nov 2012 at 9:08

GoogleCodeExporter commented 9 years ago
I went ahead and split the patch up and merged it with all the other 
outstanding patches. I pushed it all to my "merging" branch, awaiting your 
author name/address (and some more testing) before I push it to master.

Original comment by lists.to...@gmail.com on 24 Nov 2012 at 1:52

GoogleCodeExporter commented 9 years ago
After studying your reset assembly code and trying to reproduce the byte code, 
it seems wrong to me. Did you assemble it or tweak it by hand? In this case you 
probably missed the alignment conditions on PC relative addressing, or maybe 
you "optimised" away some alignment bytes?

0000:       0x02, 0x49,             // ldr     r1, [pc, #8] ; (<AIRCR_OFFSET>)

Loading r1 at 0x02 x words offset from aligned(pc): 0004 + 8 = 000c (wrong).
So r1 gets the value 0004e000

0002:       0x02, 0x4A,             // ldr     r2, [pc, #8] ; 
(<AIRCR_RESET_VALUE>)

Loading r2 at 0x02 x 4 bytes offset from pc (already aligned) = 0004 + 8 = 000c 
(also wrong)
So r2 also gets the value 0004e000

0004:        0x0A, 0x60,             // str     r2, [r1, #0]
0006:        0xff, 0xf7, 0xfe, 0xff, // endless: bl endless
000a:        0x0c, 0xed, 0x00, 0xe0, // .word 0xe000ed0c <AIRCR_OFFSET> = NVIC 
AIRCR register address
000e:        0x04, 0x00, 0xfa, 0x05  // .word 0x05fa0004 <AIRCR_RESET_VALUE> = 
VECTK

So we end up storing 0004e000 into address 0004e000...

I verified this with qemu, and I also on a real processor with JTAG where it 
generated a hardfault. I guess the boot loader code do reset on hardfault so it 
worked anyway :)

I have generated new code with the GNU assembler, and changed the code in my 
"merging" branch.

Original comment by lists.to...@gmail.com on 25 Nov 2012 at 3:32

GoogleCodeExporter commented 9 years ago
I see where the wrong code was coming from. It was compiled for, and will run 
correctly, if it starts at somewhere word-aligned + 2. Probably the original 
compiled code had 4n+2 bytes at the beginning that was cut away. In our case it 
will be loaded at RAM start, which should always be word-aligned. BTW that is 
something we should generally verify in stm32_run_raw_code(), something like 
assert(target_address % 4 == 0).

Original comment by lists.to...@gmail.com on 26 Nov 2012 at 12:29

GoogleCodeExporter commented 9 years ago
You're absolutely right and I also agree with assert. BTW It's funny, that 
reset code failed and it caused ...reset :-)

Original comment by strna...@gmail.com on 26 Nov 2012 at 5:38

GoogleCodeExporter commented 9 years ago
This has now been fixed in the official repository and is included in version 
0.3beta2.

Original comment by lists.to...@gmail.com on 9 Dec 2013 at 11:16