gdbflasher 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,101 @@
1
+ .set PAGE_SIZE, 256
2
+
3
+ .set FLASH_BASE, 0x40023C00
4
+
5
+ .set FLASH_ACR, 0x00
6
+ .set FLASH_PECR, 0x04
7
+ .set FLASH_PDKEYR, 0x08
8
+ .set FLASH_PEKEYR, 0x0C
9
+ .set FLASH_PRGKEYR, 0x10
10
+ .set FLASH_OPTKEYR, 0x14
11
+ .set FLASH_SR, 0x18
12
+
13
+ .globl trap
14
+ .globl initialize
15
+ .globl finalize
16
+ .globl erase
17
+ .globl program
18
+ .globl page_buffer
19
+ .globl PAGE_SIZE
20
+
21
+ .arch armv7-m
22
+ .syntax unified
23
+ .thumb
24
+ .text
25
+
26
+ trap:
27
+ nop
28
+
29
+ initialize:
30
+ ldr R7, =FLASH_BASE
31
+
32
+ ldr R0, =0x89ABCDEF
33
+ str R0, [R7, #FLASH_PEKEYR]
34
+ ldr R0, =0x02030405
35
+ str R0, [R7, #FLASH_PEKEYR]
36
+
37
+ ldr R0, =0x8C9DAEBF
38
+ str R0, [R7, #FLASH_PRGKEYR]
39
+ ldr R0, =0x13141516
40
+ str R0, [R7, #FLASH_PRGKEYR]
41
+
42
+ bx LR
43
+
44
+ finalize:
45
+ mov R0, #7
46
+ str R0, [R7, #FLASH_PECR]
47
+
48
+ bx LR
49
+
50
+ erase:
51
+ mov R1, #0x20C
52
+ str R1, [R7, #FLASH_PECR]
53
+
54
+ 1:ldr R1, [R7, #FLASH_SR]
55
+ tst R1, #1
56
+ bne 1b
57
+
58
+ mov R1, #0
59
+ str R1, [R0]
60
+
61
+ 1:ldr R1, [R7, #FLASH_SR]
62
+ tst R1, #1
63
+ bne 1b
64
+ and R0, R1, #0xF00
65
+
66
+ mov R1, #4
67
+ str R1, [R7, #FLASH_PECR]
68
+
69
+ bx LR
70
+
71
+ program:
72
+ ldr R1, [R7, #FLASH_SR]
73
+ tst R1, #1
74
+ bne program
75
+
76
+ ldr R4, =page_buffer
77
+ mov R2, #0
78
+
79
+ 1:
80
+ ldr R3, [R4, R2]
81
+ str R3, [R0, R2]
82
+
83
+ 2:ldr R1, [R7, #FLASH_SR]
84
+ tst R1, #1
85
+ bne 2b
86
+ ands R1, R1, #0xF00
87
+ bne 1f
88
+
89
+ add R2, #4
90
+ cmp R2, #PAGE_SIZE
91
+ blo 1b
92
+
93
+ 1:
94
+ mov R0, R1
95
+ bx LR
96
+
97
+
98
+ .bss
99
+ page_buffer:
100
+ .fill PAGE_SIZE, 1
101
+ .size page_buffer, . - page_buffer
@@ -0,0 +1,25 @@
1
+ OUTPUT_FORMAT(elf32-littlearm)
2
+
3
+ MEMORY
4
+ {
5
+ sram : ORIGIN = 0x20000000, LENGTH = 10K
6
+ }
7
+
8
+ SECTIONS
9
+ {
10
+ .text : {
11
+ *(.text)
12
+
13
+ . = ALIGN(4);
14
+
15
+ *(.rodata)
16
+ } > sram
17
+
18
+ . = ALIGN(4);
19
+
20
+ .bss : {
21
+ *(.bss)
22
+ } > sram
23
+
24
+ . = ALIGN(4);
25
+ }
@@ -0,0 +1,12 @@
1
+ :020000042000DA
2
+ :1000000000BF1C4F1C4878601C48786070474FF058
3
+ :10001000800139617047396941F0020139617861C5
4
+ :1000200041F040013961FA6812F0010FFBD121F073
5
+ :100030004201396102F01400FA607047396941F0F9
6
+ :10004000010139610E4C4FF00002A35A8352F96846
7
+ :1000500011F0010FFBD1F96011F0140104D102F18C
8
+ :100060000202B2F5006FF0D33A6922F001023A6160
9
+ :10007000084670470020024023016745AB89EFCD59
10
+ :0400800084000020D8
11
+ :0400000520000000D7
12
+ :00000001FF
@@ -0,0 +1,7 @@
1
+ 00000800 PAGE_SIZE
2
+ 20000000 trap
3
+ 20000002 initialize
4
+ 2000000e finalize
5
+ 20000016 erase
6
+ 2000003c program
7
+ 20000084 page_buffer
@@ -0,0 +1,12 @@
1
+ :020000042000DA
2
+ :1000000000BF1C4F1C4878601C48786070474FF058
3
+ :10001000800139617047396941F0020139617861C5
4
+ :1000200041F040013961FA6812F0010FFBD121F073
5
+ :100030004201396102F01400FA607047396941F0F9
6
+ :10004000010139610E4C4FF00002A35A8352F96846
7
+ :1000500011F0010FFBD1F96011F0140104D102F18C
8
+ :100060000202B2F5806FF0D33A6922F001023A61E0
9
+ :10007000084670470020024023016745AB89EFCD59
10
+ :0400800084000020D8
11
+ :0400000520000000D7
12
+ :00000001FF
@@ -0,0 +1,7 @@
1
+ 00000400 PAGE_SIZE
2
+ 20000000 trap
3
+ 20000002 initialize
4
+ 2000000e finalize
5
+ 20000016 erase
6
+ 2000003c program
7
+ 20000084 page_buffer
@@ -0,0 +1,13 @@
1
+ :020000042000DA
2
+ :1000000000BF214F214878602148786070474FF049
3
+ :10001000004038617047F96811F4803FFBD14FF020
4
+ :10002000F001F9601B4A4FEAC00141EA020139615F
5
+ :1000300041F480313961F86810F4803FFBD100F061
6
+ :10004000F0004FF0000139617047F96811F4803F0A
7
+ :10005000FBD1114939614FF0F001F9600F4C4FF0BD
8
+ :100060000002A3588350F96811F4803FFBD111F0CE
9
+ :10007000F00104D102F10402B2F5804FF1D3084639
10
+ :100080004FF0000139617047003C02402301674591
11
+ :10009000AB89EFCD0202000001020000A0000020A9
12
+ :0400000520000000D7
13
+ :00000001FF
@@ -0,0 +1,7 @@
1
+ 00004000 PAGE_SIZE
2
+ 20000000 trap
3
+ 20000002 initialize
4
+ 2000000e finalize
5
+ 20000016 erase
6
+ 2000004a program
7
+ 200000a0 page_buffer
@@ -0,0 +1,12 @@
1
+ :020000042000DA
2
+ :1000000000BF1C4F1C48F8601C48F8601C48386151
3
+ :100010001C48386170474FF00700786070474FF414
4
+ :1000200003717960B96911F0010FFBD14FF0000144
5
+ :100030000160B96911F0010FFBD101F470604FF05C
6
+ :10004000040179607047B96911F0010FFBD10E4CC2
7
+ :100050004FF00002A3588350B96911F0010FFBD192
8
+ :1000600011F4706104D102F10402B2F5807FF1D382
9
+ :1000700008467047003C0240EFCDAB8905040302FF
10
+ :0C008000BFAE9D8C161514138C000020E0
11
+ :0400000520000000D7
12
+ :00000001FF
@@ -0,0 +1,7 @@
1
+ 00000100 PAGE_SIZE
2
+ 20000000 trap
3
+ 20000002 initialize
4
+ 20000016 finalize
5
+ 2000001e erase
6
+ 20000046 program
7
+ 2000008c page_buffer
@@ -0,0 +1,19 @@
1
+ module GdbFlasher
2
+
3
+ class CortexM < MCU
4
+ protected
5
+
6
+ def initialize_environment
7
+ @connection.write_register 25, 0x01000000
8
+ end
9
+
10
+ def breakpoint_kind
11
+ 2 # Thumb-2 breakpoint
12
+ end
13
+
14
+ def lr_offset
15
+ 1
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,189 @@
1
+ module GdbFlasher
2
+ class IHex
3
+ class Record
4
+ attr_accessor :length, :address, :type, :data
5
+
6
+ TYPES = {
7
+ 0 => :data,
8
+ 1 => :eof,
9
+ 4 => :extended_address,
10
+ 5 => :start_address
11
+ }
12
+
13
+ def initialize
14
+ @length = nil
15
+ @address = nil
16
+ @type = nil
17
+ @data = nil
18
+ end
19
+
20
+ def valid?
21
+ @length == @data.length
22
+ end
23
+
24
+ def self.parse(line)
25
+ if line.match(/^:([0-9a-fA-F]{2})+$/).nil?
26
+ raise "Malformed Intel Hex line: #{line}"
27
+ end
28
+
29
+ line.slice! 0
30
+
31
+ bytes = Array.new(line.length / 2) { |i| line[i * 2..i * 2 + 1].hex }
32
+
33
+ record = Record.new
34
+ record.length = bytes[0]
35
+ record.address = (bytes[1] << 8) | bytes[2]
36
+ record.type = TYPES[bytes[3]]
37
+ record.data = bytes[4..-2].pack("C*")
38
+
39
+ checksum = (~bytes.reduce(:+) + 1) & 0xFF
40
+
41
+ if !record.valid? || record.type.nil? || checksum != 0
42
+ raise "Malformed Intel Hex line: #{line}"
43
+ end
44
+
45
+ record
46
+ end
47
+ end
48
+
49
+ class Segment
50
+ attr_accessor :base, :data
51
+
52
+ def initialize
53
+ @base = 0
54
+ @data = ""
55
+ end
56
+
57
+ def size
58
+ @data.length
59
+ end
60
+
61
+ def intersect(region_base, region_end)
62
+ if region_base == region_end
63
+ raise ArgumentError, "Region is empty"
64
+ end
65
+
66
+ segment_range = @base...@base + size
67
+ region_range = region_base..region_end
68
+
69
+ intersection_base = nil, intersection_end = nil
70
+
71
+ if segment_range.cover? region_range.min
72
+ intersection_base = region_range.min
73
+ elsif region_range.cover? segment_range.min
74
+ intersection_base = segment_range.min
75
+ else
76
+ return Segment.new
77
+ end
78
+
79
+ if segment_range.cover? region_range.max
80
+ intersection_end = region_range.max
81
+ elsif region_range.cover? segment_range.max
82
+ intersection_end = segment_range.max
83
+ else
84
+ return Segment.new
85
+ end
86
+
87
+ segment = Segment.new
88
+ segment.base = intersection_base
89
+ segment.data = @data[intersection_base - @base..intersection_end - @base]
90
+
91
+ segment
92
+ end
93
+
94
+ def pad_segment!(psize, fill_byte = 0x00)
95
+ if @base % size != 0
96
+ padding = size - (@base % size)
97
+
98
+ @base -= padding
99
+ @data = ([ fill_byte ] * padding).pack("C*") + @data
100
+ end
101
+
102
+ if @data.size % size != 0
103
+ padding = size - (@data.size % size)
104
+
105
+ @data += ([ fill_byte ] * padding).pack "C*"
106
+ end
107
+ end
108
+ end
109
+
110
+
111
+ attr_accessor :segments
112
+
113
+ def initialize
114
+ @segments = []
115
+ end
116
+
117
+ def self.load(stream)
118
+ high_address = 0
119
+ lines = {}
120
+
121
+ stream.each_line do |line|
122
+ line.rstrip!
123
+
124
+ record = Record.parse line
125
+
126
+ case record.type
127
+ when :eof
128
+ break
129
+
130
+ when :extended_address
131
+ high_address, = record.data.unpack "n"
132
+
133
+ when :data
134
+ lines[(high_address << 16) | record.address] = record.data
135
+ end
136
+ end
137
+
138
+ segment = nil
139
+ ihex = self.new
140
+
141
+ lines.sort_by { |k1,v1,k2,b2| k1 <=> k2 }.each do |address, data|
142
+ if segment.nil? || segment.base + segment.size != address
143
+ segment = Segment.new
144
+ segment.base = address
145
+ segment.data = data
146
+
147
+ ihex.segments << segment
148
+ else
149
+ segment.data += data
150
+ end
151
+ end
152
+
153
+ ihex
154
+ end
155
+
156
+ def split_segments!(size, fill_byte = 0x00)
157
+ pad_segments! size, fill_byte
158
+
159
+ i = 0
160
+
161
+ while i < @segments.length
162
+ segment = @segments[i]
163
+ parts = segment.size / size
164
+
165
+ for j in 1...parts do
166
+ new_segment = Segment.new
167
+ new_segment.base = segment.base + size * j
168
+ new_segment.data = segment.data[j * size...(j + 1) * size]
169
+
170
+ @segments.insert i + j, new_segment
171
+ end
172
+
173
+ segment.data = segment.data[0...size]
174
+
175
+ i += parts
176
+ end
177
+
178
+ self
179
+ end
180
+
181
+ def pad_segments!(size, fill_byte = 0x00)
182
+ @segments.each do |segment|
183
+ segment.pad_segment! size, fill_byte
184
+ end
185
+
186
+ self
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,17 @@
1
+ module GdbFlasher
2
+ class Stm32f10xxHD < CortexM
3
+
4
+ SECTORS = (0...256).map { |i| [ 0x08000000 + 2048 * i, 0x08000000 + 2048 * (i + 1) - 1 ] }
5
+
6
+ protected
7
+
8
+ def helper_name
9
+ "stm32f10xx_hd"
10
+ end
11
+
12
+ def erase(sector_index)
13
+ call_helper :erase, SECTORS[sector_index][0]
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,17 @@
1
+ module GdbFlasher
2
+ class Stm32f10xxMD < CortexM
3
+
4
+ SECTORS = (0...128).map { |i| [ 0x08000000 + 1024 * i, 0x08000000 + 1024 * (i + 1) - 1 ] }
5
+
6
+ protected
7
+
8
+ def helper_name
9
+ "stm32f10xx_md"
10
+ end
11
+
12
+ def erase(sector_index)
13
+ call_helper :erase, SECTORS[sector_index][0]
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,25 @@
1
+ module GdbFlasher
2
+ class Stm32f4xx < CortexM
3
+ SECTORS = [
4
+ [ 0x08000000, 0x08003FFF ], # Sector 0, 16 KiB
5
+ [ 0x08004000, 0x08007FFF ], # Sector 1, 16 KiB
6
+ [ 0x08008000, 0x0800BFFF ], # Sector 2, 16 KiB
7
+ [ 0x0800C000, 0x0800FFFF ], # Sector 3, 16 KiB
8
+ [ 0x08010000, 0x0801FFFF ], # Sector 4, 64 KiB
9
+ [ 0x08020000, 0x0803FFFF ], # Sector 5, 64 KiB
10
+ [ 0x08040000, 0x0805FFFF ], # Sector 6, 64 KiB
11
+ [ 0x08060000, 0x0807FFFF ], # Sector 7, 64 KiB
12
+ [ 0x08080000, 0x0809FFFF ], # Sector 8, 64 KiB
13
+ [ 0x080A0000, 0x080BFFFF ], # Sector 9, 64 KiB
14
+ [ 0x080C0000, 0x080DFFFF ], # Sector 10, 64 KiB
15
+ [ 0x080E0000, 0x080FFFFF ], # Sector 11, 64 KiB
16
+ ]
17
+
18
+ protected
19
+
20
+ def helper_name
21
+ "stm32f4xx"
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,21 @@
1
+ module GdbFlasher
2
+ class Stm32l1xx < CortexM
3
+
4
+ SECTORS = (0...512).map { |i| [ 0x08000000 + 256 * i, 0x08000000 + 256 * (i + 1) - 1 ] }
5
+
6
+ protected
7
+
8
+ def helper_name
9
+ "stm32l1xx"
10
+ end
11
+
12
+ def erase(sector_index)
13
+ call_helper :erase, SECTORS[sector_index][0]
14
+ end
15
+
16
+ def blank_byte
17
+ 0x00
18
+ end
19
+ end
20
+
21
+ end