blob: 339e4c546f6353c5f4b781c0a79cac4850c4dde6 [file] [log] [blame]
Roman Okhrimenko977b3752022-03-31 14:40:48 +03001"""MCUBoot Flash Map Converter (JSON to .h)
2Copyright (c) 2022 Infineon Technologies AG
3"""
4
5import sys
6import getopt
7import json
8
9# Supported Platforms
10platDict = {
11 'PSOC_062_2M': {
12 'flashAddr': 0x10000000,
13 'flashSize': 0x200000, # 2 MBytes
14 'eraseSize': 0x200, # 512 bytes
15 'smifAddr': 0x18000000,
16 'smifSize': 0x8000000 # i.e., window size
17 },
18 'PSOC_062_1M': {
19 'flashAddr': 0x10000000,
20 'flashSize': 0x100000, # 1 MByte
21 'eraseSize': 0x200, # 512 bytes
22 'smifAddr': 0x18000000,
23 'smifSize': 0x8000000 # i.e., window size
24 },
25 'PSOC_062_512K': {
26 'flashAddr': 0x10000000,
27 'flashSize': 0x80000, # 512 KBytes
28 'eraseSize': 0x200, # 512 bytes
29 'smifAddr': 0x18000000,
30 'smifSize': 0x8000000 # i.e., window size
31 },
32 'CYW20829': {
33 'flashSize': 0, # n/a
34 'smifAddr': 0x60000000,
35 'smifSize': 0x8000000 # i.e., window size
36 }
37}
38
39# Supported SPI Flash ICs
40flashDict = {
41 # Fudan
42 'FM25Q04': {
43 'flashSize': 0x80000, # 4 Mbits
44 'eraseSize': 0x1000, # 128 uniform sectors with 4K-byte each
45 },
46 'FM25W04': {
47 'flashSize': 0x80000, # 4 Mbits
48 'eraseSize': 0x1000, # 128 uniform sectors with 4K-byte each
49 },
50 'FM25Q08': {
51 'flashSize': 0x100000, # 8 Mbits
52 'eraseSize': 0x1000, # 256 uniform sectors with 4K-byte each
53 },
54 'FM25W08': {
55 'flashSize': 0x100000, # 8 Mbits
56 'eraseSize': 0x1000, # 256 uniform sectors with 4K-byte each
57 },
58 # Puya
59 'P25Q05H': {
60 'flashSize': 0x10000, # 512 Kbits
61 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase
62 },
63 'P25Q10H': {
64 'flashSize': 0x20000, # 1 Mbit
65 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase
66 },
67 'P25Q20H': {
68 'flashSize': 0x40000, # 2 Mbits
69 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase
70 },
71 'P25Q40H': {
72 'flashSize': 0x80000, # 4 Mbits
73 'eraseSize': 0x1000, # Uniform 4K-byte Sector Erase
74 },
75 # Infineon
76 'S25HS256T': {
77 'flashSize': 0x2000000, # 256 Mbits
78 'eraseSize': 0x40000, # Uniform Sector Architecture
79 },
80 'S25HS512T': {
81 'flashSize': 0x4000000, # 512 Mbits
82 'eraseSize': 0x40000, # Uniform Sector Architecture
83 },
84 'S25HS01GT': {
85 'flashSize': 0x8000000, # 1 Gbit
86 'eraseSize': 0x40000, # Uniform Sector Architecture
87 }
88}
89
90
91def is_overlap(fa1off, fa1size, fa2off, fa2size, align):
92 """Check if two flash areas on the same device overlap"""
93 mask = align - 1
94 assert align > 0 and (align & mask) == 0 # ensure align is a power of 2
95 fa1end = (fa1off + fa1size + mask) & ~mask
96 fa2end = (fa2off + fa2size + mask) & ~mask
97 fa1off = fa1off & ~mask
98 fa2off = fa2off & ~mask
99 return fa1off < fa2end and fa2off < fa1end
100
101
102def is_same_mem(fa1addr, fa2addr):
103 """Check if two addresses belong to the same memory"""
104 if fa1addr is None or fa2addr is None:
105 return False
106 mask = 0xFF000000
107 return (fa1addr & mask) == (fa2addr & mask)
108
109
110class CmdLineParams:
111 """Command line parameters"""
112
113 def __init__(self):
114 self.plat_id = ''
115 self.in_file = ''
116 self.out_file = ''
117 self.img_id = None
118
119 usage = 'USAGE:\n' + sys.argv[0] + \
120 ''' -p <platform> -i <flash_map.json> -o <flash_map.h> -d <img_id>
121
122OPTIONS:
123-h --help Display the usage information
124-p --platform= Target (e.g., PSOC_062_512K)
125-i --ifile= JSON flash map file
126-o --ofile= C header file to be generated
127-d --img_id ID of application to build'''
128
129 try:
130 opts, unused = getopt.getopt(
131 sys.argv[1:], 'hi:o:p:d:',
132 ['help', 'platform=', 'ifile=', 'ofile=', 'img_id='])
133 if len(unused) > 0:
134 print(usage, file=sys.stderr)
135 sys.exit(1)
136 except getopt.GetoptError:
137 print(usage, file=sys.stderr)
138 sys.exit(1)
139
140 for opt, arg in opts:
141 if opt in ('-h', '--help'):
142 print(usage, file=sys.stderr)
143 sys.exit()
144 elif opt in ('-p', '--platform'):
145 self.plat_id = arg
146 elif opt in ('-i', '--ifile'):
147 self.in_file = arg
148 elif opt in ('-o', '--ofile'):
149 self.out_file = arg
150 elif opt in ('-d', '--img_id'):
151 self.img_id = arg
152
153 if len(self.in_file) == 0 or len(self.out_file) == 0:
154 print(usage, file=sys.stderr)
155 sys.exit(1)
156
157
158class AreaList:
159 """List of flash areas"""
160
161 def __init__(self, plat, flash, use_overwrite):
162 self.plat = plat
163 self.flash = flash
164 self.use_overwrite = use_overwrite
165 self.areas = []
166 self.peers = {}
167 self.trailers = {}
168 self.internal_flash = False
169 self.external_flash = False
170 self.external_flash_xip = False
171
172 def get_min_erase_size(self):
173 """Calculate minimum erase block size for int./ext. Flash """
174 return self.plat['eraseSize'] if self.plat['flashSize'] > 0 \
175 else self.flash['eraseSize']
176
177 def get_img_trailer_size(self):
178 """Calculate image trailer size"""
179 return self.get_min_erase_size()
180
181 def process_int_area(self, title, fa_addr, fa_size,
182 img_trailer_size, shared_slot):
183 """Process internal flash area"""
184 fa_device_id = 'FLASH_DEVICE_INTERNAL_FLASH'
185 fa_off = fa_addr - self.plat['flashAddr']
186 if img_trailer_size is not None:
187 if self.use_overwrite:
188 if shared_slot:
189 print('Shared slot', title,
190 'is not supported in OVERWRITE mode',
191 file=sys.stderr)
192 sys.exit(7)
193 else:
194 # Check trailer alignment (start at the sector boundary)
195 align = (fa_off + fa_size - img_trailer_size) % \
196 self.plat['eraseSize']
197 if align != 0:
198 fa_addr += self.plat['eraseSize'] - align
199 if fa_addr + fa_size <= \
200 self.plat['flashAddr'] + self.plat['flashSize']:
201 print('Misaligned', title,
202 '- suggested address', hex(fa_addr),
203 file=sys.stderr)
204 else:
205 print('Misaligned', title, file=sys.stderr)
206 sys.exit(7)
207 else:
208 # Check alignment (flash area should start at the sector boundary)
209 if fa_off % self.plat['eraseSize'] != 0:
210 print('Misaligned', title, file=sys.stderr)
211 sys.exit(7)
212 slot_sectors = int((fa_off % self.plat['eraseSize'] +
213 fa_size + self.plat['eraseSize'] - 1) //
214 self.plat['eraseSize'])
215 return fa_device_id, fa_off, slot_sectors
216
217 def process_ext_area(self, title, fa_addr, fa_size,
218 img_trailer_size, shared_slot):
219 """Process external flash area"""
220 if self.flash is None:
221 print('Unspecified SPI Flash IC',
222 file=sys.stderr)
223 sys.exit(3)
224 if fa_addr + fa_size <= \
225 self.plat['smifAddr'] + self.flash['flashSize']:
226 flash_idx = 'CY_BOOT_EXTERNAL_DEVICE_INDEX'
227 fa_device_id = f'FLASH_DEVICE_EXTERNAL_FLASH({flash_idx})'
228 fa_off = fa_addr - self.plat['smifAddr']
229 else:
230 print('Misfitting', title, file=sys.stderr)
231 sys.exit(7)
232 if img_trailer_size is not None:
233 if self.use_overwrite:
234 if shared_slot:
235 print('Shared slot', title,
236 'is not supported in OVERWRITE mode',
237 file=sys.stderr)
238 sys.exit(7)
239 else:
240 # Check trailer alignment (start at the sector boundary)
241 align = (fa_off + fa_size - img_trailer_size) % \
242 self.flash['eraseSize']
243 if align != 0:
244 peer_addr = self.peers.get(fa_addr)
245 if shared_slot:
246 # Special case when using both int. and ext. memory
247 if self.plat['flashSize'] > 0 and \
248 align % self.plat['eraseSize'] == 0:
249 print('Note:', title, 'requires', align,
250 'padding bytes before trailer',
251 file=sys.stderr)
252 else:
253 print('Misaligned', title, file=sys.stderr)
254 sys.exit(7)
255 elif is_same_mem(fa_addr, peer_addr) and \
256 fa_addr % self.flash['eraseSize'] == \
257 peer_addr % self.flash['eraseSize']:
258 pass # postpone checking
259 else:
260 fa_addr += self.flash['eraseSize'] - align
261 if fa_addr + fa_size <= \
262 self.plat['smifAddr'] + self.flash['flashSize']:
263 print('Misaligned', title,
264 '- suggested address', hex(fa_addr),
265 file=sys.stderr)
266 else:
267 print('Misaligned', title, file=sys.stderr)
268 sys.exit(7)
269 else:
270 # Check alignment (flash area should start at the sector boundary)
271 if fa_off % self.flash['eraseSize'] != 0:
272 print('Misaligned', title, file=sys.stderr)
273 sys.exit(7)
274 slot_sectors = int((fa_off % self.flash['eraseSize'] +
275 fa_size + self.flash['eraseSize'] - 1) //
276 self.flash['eraseSize'])
277 self.external_flash = True
278 if self.flash['XIP']:
279 self.external_flash_xip = True
280 return fa_device_id, fa_off, slot_sectors
281
282 def chk_area(self, fa_addr, fa_size, peer_addr=None):
283 """Check area location (internal/external flash)"""
284 if peer_addr is not None:
285 self.peers[peer_addr] = fa_addr
286 fa_limit = fa_addr + fa_size
287 if self.plat['flashSize'] and \
288 fa_addr >= self.plat['flashAddr'] and \
289 fa_limit <= self.plat['flashAddr'] + self.plat['flashSize']:
290 # Internal flash
291 self.internal_flash = True
292
293 def add_area(self, title,
294 fa_id, fa_addr, fa_size,
295 img_trailer_size=None, shared_slot=False):
296 """Add flash area to AreaList.
297 Internal/external flash is detected by address.
298 Returns number of sectors in a slot"""
299 if fa_size == 0:
300 print('Empty', title, file=sys.stderr)
301 sys.exit(7)
302
303 fa_limit = fa_addr + fa_size
304 if self.plat['flashSize'] and \
305 fa_addr >= self.plat['flashAddr'] and \
306 fa_limit <= self.plat['flashAddr'] + self.plat['flashSize']:
307 # Internal flash
308 fa_device_id, fa_off, slot_sectors = self.process_int_area(
309 title, fa_addr, fa_size, img_trailer_size, shared_slot)
310 align = self.plat['eraseSize']
311 elif self.plat['smifSize'] and \
312 fa_addr >= self.plat['smifAddr'] and \
313 fa_limit <= self.plat['smifAddr'] + self.plat['smifSize']:
314 # External flash
315 fa_device_id, fa_off, slot_sectors = self.process_ext_area(
316 title, fa_addr, fa_size, img_trailer_size, shared_slot)
317 align = self.flash['eraseSize']
318 else:
319 print('Invalid', title, file=sys.stderr)
320 sys.exit(7)
321
322 if shared_slot:
323 assert img_trailer_size is not None
324 tr_addr = fa_addr + fa_size - img_trailer_size
325 tr_name = self.trailers.get(tr_addr)
326 if tr_name is not None:
327 print('Same trailer address for', title, 'and', tr_name,
328 file=sys.stderr)
329 sys.exit(7)
330 self.trailers[tr_addr] = title
331
332 # Ensure no flash areas on this device will overlap, except the
333 # shared slot
334 for area in self.areas:
335 if fa_device_id == area['fa_device_id']:
336 over = is_overlap(fa_off, fa_size,
337 area['fa_off'], area['fa_size'],
338 align)
339 if shared_slot and area['shared_slot']:
340 if not over: # images in shared slot should overlap
341 print(title, 'is not shared with', area['title'],
342 file=sys.stderr)
343 sys.exit(7)
344 elif over:
345 print(title, 'overlaps with', area['title'],
346 file=sys.stderr)
347 sys.exit(7)
348
349 self.areas.append({'title': title,
350 'shared_slot': shared_slot,
351 'fa_id': fa_id,
352 'fa_device_id': fa_device_id,
353 'fa_off': fa_off,
354 'fa_size': fa_size})
355 return slot_sectors
356
357 def generate_c_source(self, params):
358 """Generate C source"""
359 c_array = 'flash_areas'
360
361 try:
362 with open(params.out_file, "w", encoding='UTF-8') as out_f:
363 out_f.write('/* AUTO-GENERATED FILE, DO NOT EDIT.'
364 ' ALL CHANGES WILL BE LOST! */\n')
365 out_f.write(f'/* Platform: {params.plat_id} */\n')
366 out_f.write(f'\nstatic struct flash_area {c_array}[] = {{\n')
367 comma = len(self.areas)
368 area_count = 0
369 for area in self.areas:
370 comma -= 1
371 if area['fa_id'] is not None:
372 sss = ' /* Shared secondary slot */' \
373 if area['shared_slot'] else ''
374 out_f.writelines('\n'.join([
375 ' {' + sss,
376 f" .fa_id = {area['fa_id']},",
377 f" .fa_device_id = {area['fa_device_id']},",
378 f" .fa_off = {hex(area['fa_off'])}U,",
379 f" .fa_size = {hex(area['fa_size'])}U",
380 ' },' if comma else ' }', '']))
381 area_count += 1
382 out_f.write('};\n\n'
383 'struct flash_area *boot_area_descs[] = {\n')
384 for area_index in range(area_count):
385 out_f.write(f' &{c_array}[{area_index}U],\n')
386 out_f.write(' NULL\n};\n')
387 except (FileNotFoundError, OSError):
388 print('Cannot create', params.out_file, file=sys.stderr)
389 sys.exit(4)
390
391
392def cvt_dec_or_hex(val, desc):
393 """Convert (hexa)decimal string to number"""
394 try:
395 return int(val, 0)
396 except ValueError:
397 print('Invalid value', val, 'for', desc, file=sys.stderr)
398 sys.exit(6)
399
400
401def get_val(obj, attr):
402 """Get JSON 'value'"""
403 obj = obj[attr]
404 try:
405 return cvt_dec_or_hex(obj['value'], obj['description'])
406 except KeyError as key:
407 print('Malformed JSON:', key,
408 'is missing in', "'" + attr + "'",
409 file=sys.stderr)
410 sys.exit(5)
411
412
413def get_bool(obj, attr, def_val=False):
414 """Get JSON boolean value (returns def_val if it missing)"""
415 ret_val = def_val
416 obj = obj.get(attr)
417 if obj is not None:
418 try:
419 val = str(obj['value']).lower()
420 desc = obj['description']
421 if val == 'true':
422 ret_val = True
423 elif val == 'false':
424 ret_val = False
425 else:
426 print('Invalid value', val, 'for', desc, file=sys.stderr)
427 sys.exit(6)
428 except KeyError as key:
429 print('Malformed JSON:', key,
430 'is missing in', "'" + attr + "'",
431 file=sys.stderr)
432 sys.exit(5)
433 return ret_val
434
435
436class AddrSize:
437 """Bootloader area"""
438
439 def __init__(self, bootloader, addr_name, size_name):
440 self.fa_addr = get_val(bootloader, addr_name)
441 self.fa_size = get_val(bootloader, size_name)
442
443
444def calc_status_size(boot_swap_status_row_sz, max_img_sectors,
445 img_number, scratch_flag=True):
446 """Estimate status size, see swap_status.h"""
447 boot_swap_status_cnt_sz = 4
448 boot_swap_status_crc_sz = 4
449 boot_swap_status_mgcrec_sz = 4
450 boot_swap_status_trailer_size = 64
451 boot_swap_status_payld_sz = \
452 boot_swap_status_row_sz - boot_swap_status_mgcrec_sz - \
453 boot_swap_status_cnt_sz - boot_swap_status_crc_sz
454 boot_swap_status_sect_rows_num = \
455 int((max_img_sectors - 1) //
456 boot_swap_status_payld_sz) + 1
457 boot_swap_status_trail_rows_num = \
458 int((boot_swap_status_trailer_size - 1) //
459 boot_swap_status_payld_sz) + 1
460 boot_swap_status_d_size = \
461 boot_swap_status_row_sz * \
462 (boot_swap_status_sect_rows_num + boot_swap_status_trail_rows_num)
463 boot_swap_status_mult = 2
464 boot_swap_status_size = boot_swap_status_mult * boot_swap_status_d_size
465 status_zone_cnt = 2 * img_number
466 if scratch_flag:
467 status_zone_cnt += 1
468 return boot_swap_status_size * status_zone_cnt
469
470
471def process_json(in_file):
472 """Process JSON"""
473 try:
474 with open(in_file, encoding='UTF-8') as in_f:
475 try:
476 flash_map = json.load(in_f)
477 except ValueError:
478 print('Cannot parse', in_file, file=sys.stderr)
479 sys.exit(4)
480 except (FileNotFoundError, OSError):
481 print('Cannot open', in_file, file=sys.stderr)
482 sys.exit(4)
483 flash = flash_map.get('external_flash')
484 if flash is not None:
485 flash = flash[0]
486 model = flash.get('model')
487 mode = flash.get('mode')
488 if model is not None:
489 try:
490 flash = flashDict[model]
491 except KeyError:
492 print('Supported SPI Flash ICs are:',
493 ', '.join(flashDict.keys()),
494 file=sys.stderr)
495 sys.exit(3)
496 else:
497 try:
498 flash = {'flashSize': cvt_dec_or_hex(flash['flash-size'],
499 'flash-size'),
500 'eraseSize': cvt_dec_or_hex(flash['erase-size'],
501 'erase-size')}
502 except KeyError as key:
503 print('Malformed JSON:', key,
504 "is missing in 'external_flash'",
505 file=sys.stderr)
506 sys.exit(3)
507 flash.update({'XIP': str(mode).upper() == 'XIP'})
508 return flash_map['boot_and_upgrade'], flash
509
510
511def process_images(area_list, boot_and_upgrade):
512 """Process images"""
513 app_count = 0
514 slot_sectors_max = 0
515 all_shared = get_bool(boot_and_upgrade['bootloader'], 'shared_slot')
516 any_shared = all_shared
517
518 apps_flash_map = [None, ]
519
520 for stage in range(2):
521 for app_index in range(1, 5):
522
523 app_flash_map = {}
524
525 try:
526 app_ident = f'application_{app_index}'
527 application = boot_and_upgrade[app_ident]
528 try:
529 primary_addr = get_val(application, 'address')
530 primary_size = get_val(application, 'size')
531 secondary_addr = get_val(application, 'upgrade_address')
532 secondary_size = get_val(application, 'upgrade_size')
533 except KeyError as key:
534 print('Malformed JSON:', key, 'is missing',
535 file=sys.stderr)
536 sys.exit(5)
537 if stage == 0:
538 if primary_size != secondary_size:
539 print('Primary and secondary slot sizes'
540 ' are different for', app_ident,
541 file=sys.stderr)
542 sys.exit(6)
543 area_list.chk_area(primary_addr, primary_size)
544 area_list.chk_area(secondary_addr, secondary_size,
545 primary_addr)
546 else:
547 slot_sectors_max = max(
548 slot_sectors_max,
549 area_list.add_area(
550 f'{app_ident} (primary slot)',
551 f'FLASH_AREA_IMG_{app_index}_PRIMARY',
552 primary_addr, primary_size,
553 area_list.get_img_trailer_size()))
554 shared_slot = get_bool(application, 'shared_slot', all_shared)
555 any_shared = any_shared or shared_slot
556 slot_sectors_max = max(
557 slot_sectors_max,
558 area_list.add_area(
559 f'{app_ident} (secondary slot)',
560 f'FLASH_AREA_IMG_{app_index}_SECONDARY',
561 secondary_addr, secondary_size,
562 area_list.get_img_trailer_size(),
563 shared_slot))
564
565 app_slot_prim = {"address": hex(primary_addr), "size": hex(primary_size)}
566 app_slot_sec = {"address": hex(secondary_addr), "size": hex(secondary_size)}
567
568 app_flash_map.update({"primary": app_slot_prim, "secondary": app_slot_sec})
569 apps_flash_map.append(app_flash_map)
570
571 app_count = app_index
572
573 except KeyError:
574 break
575 if app_count == 0:
576 print('Malformed JSON: no application(s) found',
577 file=sys.stderr)
578 sys.exit(5)
579
580 return app_count, slot_sectors_max, apps_flash_map, any_shared
581
582
583def main():
584 """Flash map converter"""
585 params = CmdLineParams()
586
587 try:
588 plat = platDict[params.plat_id]
589 except KeyError:
590 print('Supported platforms are:', ', '.join(platDict.keys()),
591 file=sys.stderr)
592 sys.exit(2)
593
594 try:
595 boot_and_upgrade, flash = process_json(params.in_file)
596 bootloader = boot_and_upgrade['bootloader']
597 boot = AddrSize(bootloader, 'address', 'size')
598 except KeyError as key:
599 print('Malformed JSON:', key, 'is missing',
600 file=sys.stderr)
601 sys.exit(5)
602
603 try:
604 scratch = AddrSize(bootloader, 'scratch_address', 'scratch_size')
605 except KeyError:
606 scratch = None
607
608 try:
609 swap_status = AddrSize(bootloader, 'status_address', 'status_size')
610 except KeyError:
611 swap_status = None
612
613 # Create flash areas
614 area_list = AreaList(plat, flash, scratch is None and swap_status is None)
615 area_list.add_area('bootloader', 'FLASH_AREA_BOOTLOADER',
616 boot.fa_addr, boot.fa_size)
617
618 # Service RAM app (optional)
619 service_app = boot_and_upgrade.get('service_app')
620 app_binary = None
621 input_params = None
622 app_desc = None
623 if service_app is not None:
624 if plat['flashSize'] > 0:
625 print('service_app is unsupported on this platform',
626 file=sys.stderr)
627 sys.exit(7)
628 try:
629 app_binary = AddrSize(service_app, 'address', 'size')
630 input_params = AddrSize(service_app, 'params_address', 'params_size')
631 app_desc = AddrSize(service_app, 'desc_address', 'desc_size')
632 if input_params.fa_addr != app_binary.fa_addr + app_binary.fa_size or \
633 app_desc.fa_addr != input_params.fa_addr + input_params.fa_size or \
634 app_desc.fa_size != 0x20:
635 print('Malformed service_app definition', file=sys.stderr)
636 sys.exit(7)
637 area_list.add_area('service_app', None, app_binary.fa_addr,
638 app_binary.fa_size + input_params.fa_size + app_desc.fa_size)
639 except KeyError as key:
640 print('Malformed JSON:', key, 'is missing',
641 file=sys.stderr)
642 sys.exit(5)
643
644 # Fill flash areas
645 app_count, slot_sectors_max, apps_flash_map, shared_slot = \
646 process_images(area_list, boot_and_upgrade)
647
648 slot_sectors_max = max(slot_sectors_max, 32)
649
650 if swap_status is not None:
651 status_size_min = calc_status_size(area_list.get_min_erase_size(),
652 slot_sectors_max,
653 app_count,
654 scratch is not None)
655
656 if swap_status.fa_size < status_size_min:
657 print('Insufficient swap status area - suggested size',
658 hex(status_size_min),
659 file=sys.stderr)
660 sys.exit(7)
661 area_list.add_area('swap status partition',
662 'FLASH_AREA_IMAGE_SWAP_STATUS',
663 swap_status.fa_addr, swap_status.fa_size)
664
665 if scratch is not None:
666 area_list.add_area('scratch area',
667 'FLASH_AREA_IMAGE_SCRATCH',
668 scratch.fa_addr, scratch.fa_size)
669
670 # Image id parameter is not used for MCUBootApp
671 if params.img_id is None:
672 area_list.generate_c_source(params)
673
674 # Report necessary values back to make
675 print('# AUTO-GENERATED FILE, DO NOT EDIT. ALL CHANGES WILL BE LOST!')
676
677 if params.img_id is not None:
678 primary_img_start = (apps_flash_map[int(params.img_id)].get("primary")).get("address")
679 secondary_img_start = (apps_flash_map[int(params.img_id)].get("secondary")).get("address")
680 bootloader_size = (bootloader.get("size")).get("value")
681 slot_size = (apps_flash_map[int(params.img_id)].get("primary")).get("size")
682
683 print('PRIMARY_IMG_START := ' + primary_img_start)
684 print('SECONDARY_IMG_START := ' + secondary_img_start)
685 print('SLOT_SIZE := ' + slot_size)
686 print('BOOTLOADER_SIZE := ' + bootloader_size)
687 else:
688 print('MCUBOOT_IMAGE_NUMBER :=', app_count)
689 print('MAX_IMG_SECTORS :=', slot_sectors_max)
690
691 if area_list.use_overwrite:
692 print('USE_OVERWRITE := 1')
693 if area_list.external_flash:
694 print('USE_EXTERNAL_FLASH := 1')
695 if area_list.external_flash_xip:
696 print('USE_XIP := 1')
697 if shared_slot:
698 print('USE_SHARED_SLOT := 1')
699 if service_app is not None:
700 print('PLATFORM_SERVICE_APP_OFFSET :=',
701 hex(app_binary.fa_addr - plat['smifAddr']))
702 print('PLATFORM_SERVICE_APP_INPUT_PARAMS_OFFSET :=',
703 hex(input_params.fa_addr - plat['smifAddr']))
704 print('PLATFORM_SERVICE_APP_DESC_OFFSET :=',
705 hex(app_desc.fa_addr - plat['smifAddr']))
706 print('USE_HW_ROLLBACK_PROT := 1')
707
708
709if __name__ == '__main__':
710 main()