diff --git a/components/partition_table/gen_esp32part.py b/components/partition_table/gen_esp32part.py index 933b59263f..f1423a310e 100755 --- a/components/partition_table/gen_esp32part.py +++ b/components/partition_table/gen_esp32part.py @@ -92,6 +92,19 @@ def get_subtype_as_int(ptype, subtype): return subtype +ALIGNMENT = { + APP_TYPE: 0x10000, + DATA_TYPE: 0x4, +} + + +STRICT_DATA_ALIGNMENT = 0x1000 + + +def get_alignment_for_type(ptype): + return ALIGNMENT.get(ptype, ALIGNMENT[DATA_TYPE]) + + quiet = False md5sum = True secure = False @@ -161,7 +174,7 @@ class PartitionTable(list): raise InputError('CSV Error: Partitions overlap. Partition at line %d sets offset 0x%x. Previous partition ends 0x%x' % (e.line_no, e.offset, last_end)) if e.offset is None: - pad_to = 0x10000 if e.type == APP_TYPE else 4 + pad_to = get_alignment_for_type(e.type) if last_end % pad_to != 0: last_end += pad_to - (last_end % pad_to) e.offset = last_end @@ -211,10 +224,10 @@ class PartitionTable(list): # print sorted duplicate partitions by name if len(duplicates) != 0: - print('A list of partitions that have the same name:') + critical('A list of partitions that have the same name:') for p in sorted(self, key=lambda x:x.name): if len(duplicates.intersection([p.name])) != 0: - print('%s' % (p.to_csv())) + critical('%s' % (p.to_csv())) raise InputError('Partition names must be unique') # check for overlaps @@ -230,12 +243,12 @@ class PartitionTable(list): otadata_duplicates = [p for p in self if p.type == TYPES['data'] and p.subtype == SUBTYPES[DATA_TYPE]['ota']] if len(otadata_duplicates) > 1: for p in otadata_duplicates: - print(p.name, p.type, p.subtype) + critical('%s' % (p.to_csv())) raise InputError('Found multiple otadata partitions. Only one partition can be defined with type="data"(1) and subtype="ota"(0).') if len(otadata_duplicates) == 1 and otadata_duplicates[0].size != 0x2000: p = otadata_duplicates[0] - print(p.name, p.type, p.subtype, p.offset, p.size) + critical('%s' % (p.to_csv())) raise InputError('otadata partition must have size = 0x2000') def flash_size(self): @@ -287,11 +300,6 @@ class PartitionTable(list): class PartitionDefinition(object): MAGIC_BYTES = b'\xAA\x50' - ALIGNMENT = { - APP_TYPE: 0x10000, - DATA_TYPE: 0x04, - } - # dictionary maps flag name (as used in CSV flags list, property name) # to bit set in flags words in binary format FLAGS = { @@ -388,10 +396,15 @@ class PartitionDefinition(object): raise ValidationError(self, 'Subtype field is not set') if self.offset is None: raise ValidationError(self, 'Offset field is not set') - align = self.ALIGNMENT.get(self.type, 4) + align = get_alignment_for_type(self.type) if self.offset % align: raise ValidationError(self, 'Offset 0x%x is not aligned to 0x%x' % (self.offset, align)) - if self.size % align and secure: + # The alignment requirement for non-app partition is 4 bytes, but it should be 4 kB. + # Print a warning for now, make it an error in IDF 5.0 (IDF-3742). + if self.type != APP_TYPE and self.offset % STRICT_DATA_ALIGNMENT: + critical('WARNING: Partition %s not aligned to 0x%x.' + 'This is deprecated and will be considered an error in the future release.' % (self.name, STRICT_DATA_ALIGNMENT)) + if self.size % align and secure and self.type == APP_TYPE: raise ValidationError(self, 'Size 0x%x is not aligned to 0x%x' % (self.size, align)) if self.size is None: raise ValidationError(self, 'Size field is not set') diff --git a/components/partition_table/test_gen_esp32part_host/gen_esp32part_tests.py b/components/partition_table/test_gen_esp32part_host/gen_esp32part_tests.py index 8ae9b6c7be..11dd2170e2 100755 --- a/components/partition_table/test_gen_esp32part_host/gen_esp32part_tests.py +++ b/components/partition_table/test_gen_esp32part_host/gen_esp32part_tests.py @@ -451,6 +451,19 @@ ota_1, 0, ota_1, , 1M, self.assertIn('WARNING', sys.stderr.getvalue()) self.assertIn('partition subtype', sys.stderr.getvalue()) + sys.stderr = io.StringIO() + csv_3 = 'nvs, data, nvs, 0x8800, 32k' + gen_esp32part.PartitionTable.from_csv(csv_3).verify() + self.assertIn('WARNING', sys.stderr.getvalue()) + self.assertIn('not aligned to 0x1000', sys.stderr.getvalue()) + + sys.stderr = io.StringIO() + csv_4 = 'factory, app, factory, 0x10000, 0x100100\n' \ + 'nvs, data, nvs, , 32k' + gen_esp32part.PartitionTable.from_csv(csv_4).verify() + self.assertIn('WARNING', sys.stderr.getvalue()) + self.assertIn('not aligned to 0x1000', sys.stderr.getvalue()) + finally: sys.stderr = sys.__stderr__