소스 검색

Pull in the vector table. Patch the vector table to suite the

Michael Hope 5 년 전
부모
커밋
cdab2b29ec
1개의 변경된 파일82개의 추가작업 그리고 12개의 파일을 삭제
  1. 82 12
      prog.py

+ 82 - 12
prog.py 파일 보기

@@ -5,6 +5,7 @@ import binascii
5 5
 import random
6 6
 import pprint
7 7
 import collections
8
+import struct
8 9
 
9 10
 import elffile
10 11
 
@@ -36,7 +37,20 @@ RETURN_CODE = {
36 37
 
37 38
 Section = collections.namedtuple('Section', 'name address content')
38 39
 
40
+def fix_vectors(data):
41
+    """Patch the vector table so the bootloader recognises the code
42
+    as valid.  Sum of the first eight is zero.
43
+    """
44
+    first = data[:4*7]
45
+    remainder = data[4*8:]
46
+
47
+    vectors = struct.unpack('<IIIIIII', first)
48
+    last = -sum(vectors) & 0xFFFFFFFF
49
+
50
+    return first + struct.pack('<I', last) + remainder
51
+
39 52
 class ELFReader:
53
+    """Reads an ELF file into sections."""
40 54
     def __init__(self, name):
41 55
         elf = elffile.open(name)
42 56
 
@@ -44,17 +58,24 @@ class ELFReader:
44 58
         self.sections = []
45 59
 
46 60
         for header in elf.sectionHeaders:
47
-            if header.name in ['.text', '.data']:
48
-                self.sections.append(Section(header.name, header.addr, header.content))
61
+            if header.name in ['.text', '.data', '.vectors']:
62
+                content = header.content
63
+
64
+                if header.name == '.vectors':
65
+                    content = fix_vectors(content)
66
+
67
+                self.sections.append(Section(header.name, header.addr, content))
49 68
         
50 69
 class Loader:
70
+    """Talk with a LPC1114 over the serial bootloader protocol."""
71
+
51 72
     SYNCHRONIZED = 'Synchronized\r\n'
52 73
     OK = 'OK\r\n'
53 74
 
54
-    def __init__(self, verbose=False):
75
+    def __init__(self, port='/dev/ttyUSB0', verbose=True):
55 76
         self.verbose = verbose
56 77
 
57
-        self.port = serial.Serial('/dev/ttyUSB0', 115200, timeout=0.5)
78
+        self.port = serial.Serial(port, 115200, timeout=0.5)
58 79
 
59 80
     def log(self, msg, eol=True):
60 81
         if self.verbose:
@@ -69,6 +90,12 @@ class Loader:
69 90
     def set_bsl(self, level):
70 91
         self.port.setRTS(level == 0)
71 92
 
93
+    def run(self):
94
+        self.set_bsl(1)
95
+        self.set_reset(1)
96
+        self.set_reset(0)
97
+        self.set_reset(1)
98
+
72 99
     def sync(self):
73 100
         for tries in range(3):
74 101
             self.set_bsl(0)
@@ -123,6 +150,40 @@ class Loader:
123 150
             else:
124 151
                 raise Error('Protocol error')
125 152
 
153
+    def prepare(self, first, last=None):
154
+        if last == None:
155
+            last = first
156
+
157
+        self.execute('P', (), first, last)
158
+
159
+    def erase(self, first, last=None):
160
+        if last == None:
161
+            last = first
162
+
163
+        self.prepare(first, last)
164
+        self.execute('E', (), first, last)
165
+
166
+    def program(self, address, data):
167
+        page_size = 256
168
+        chunk = 512
169
+        load_address = 0x10000400
170
+
171
+        if address % page_size != 0:
172
+            raise Error('Address must be page size aligned')
173
+
174
+        remainder = len(data) % page_size
175
+
176
+        if remainder != 0:
177
+            data += '\xff' * (page_size - remainder)
178
+
179
+        assert len(data) % page_size == 0
180
+
181
+        for offset in range(0, len(data), chunk):
182
+            part = data[offset:offset+chunk]
183
+            self.load(load_address, part)
184
+            self.prepare(0)
185
+            self.execute('C', (), address + offset, load_address, len(part))
186
+
126 187
     def go(self, address):
127 188
         self.execute('G', (), address, 'T')
128 189
 
@@ -138,7 +199,15 @@ class Loader:
138 199
         self.execute('U', (), 23130)
139 200
 
140 201
     def check_ok(self):
141
-        assert self.readline() == '0'
202
+        code = self.readline()
203
+
204
+        try:
205
+            code = int(code)
206
+        except ValueError:
207
+            raise Error('Invalid result code')
208
+
209
+        if code != 0:
210
+            raise Error(RETURN_CODE[code])
142 211
 
143 212
     def execute(self, command, result, *kargs):
144 213
         send = command
@@ -147,11 +216,7 @@ class Loader:
147 216
             send += ' %s' % arg
148 217
 
149 218
         self.send(send)
150
-
151
-        code = int(self.readline())
152
-
153
-        if code != 0:
154
-            raise Error(RETURN_CODE[code])
219
+        self.check_ok()
155 220
 
156 221
         values = []
157 222
 
@@ -210,13 +275,18 @@ def main():
210 275
     loader.sync()
211 276
     loader.unlock()
212 277
 
278
+    loader.erase(0)
279
+
213 280
     for arg in sys.argv[1:]:
214 281
         data = ELFReader(arg)
215 282
 
216 283
         for section in data.sections:
217
-            loader.load(section.address, section.content)
284
+            loader.program(section.address, section.content)
218 285
 
219
-    loader.go(data.entry)
286
+    loader.sync()
287
+    loader.run()
288
+#    loader.unlock()
289
+#    loader.go(data.entry)
220 290
 
221 291
 if __name__ == '__main__':
222 292
     main()