mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/fatfs-support-detection-minimal-partition-size' into 'master'
fatfsgen.py: Support for detection of minimal partition size Closes IDF-4122 See merge request espressif/esp-idf!20178
This commit is contained in:
commit
95c4749a5f
@ -14,6 +14,7 @@ from construct import BitsInteger, BitStruct, Int16ul
|
||||
# the regex pattern defines symbols that are allowed by long file names but not by short file names
|
||||
INVALID_SFN_CHARS_PATTERN = re.compile(r'[.+,;=\[\]]')
|
||||
|
||||
FATFS_MIN_ALLOC_UNIT: int = 128
|
||||
FAT12_MAX_CLUSTERS: int = 4085
|
||||
FAT16_MAX_CLUSTERS: int = 65525
|
||||
RESERVED_CLUSTERS_COUNT: int = 2
|
||||
@ -174,7 +175,9 @@ def get_args_for_partition_generator(desc: str, wl: bool) -> argparse.Namespace:
|
||||
help='Filename of the generated fatfs image')
|
||||
parser.add_argument('--partition_size',
|
||||
default=FATDefaults.SIZE,
|
||||
help='Size of the partition in bytes')
|
||||
help='Size of the partition in bytes.' +
|
||||
('' if wl else ' Use `--partition_size detect` for detecting the minimal partition size.')
|
||||
)
|
||||
parser.add_argument('--sector_size',
|
||||
default=FATDefaults.SECTOR_SIZE,
|
||||
type=int,
|
||||
@ -207,6 +210,8 @@ def get_args_for_partition_generator(desc: str, wl: bool) -> argparse.Namespace:
|
||||
args = parser.parse_args()
|
||||
if args.fat_type == 0:
|
||||
args.fat_type = None
|
||||
if args.partition_size == 'detect' and not wl:
|
||||
args.partition_size = -1
|
||||
args.partition_size = int(str(args.partition_size), 0)
|
||||
if not os.path.isdir(args.input_directory):
|
||||
raise NotADirectoryError(f'The target directory `{args.input_directory}` does not exist!')
|
||||
|
@ -7,11 +7,15 @@ from datetime import datetime
|
||||
from typing import Any, List, Optional
|
||||
|
||||
from fatfs_utils.boot_sector import BootSector
|
||||
from fatfs_utils.exceptions import NoFreeClusterException
|
||||
from fatfs_utils.fat import FAT
|
||||
from fatfs_utils.fatfs_state import FATFSState
|
||||
from fatfs_utils.fs_object import Directory
|
||||
from fatfs_utils.utils import (BYTES_PER_DIRECTORY_ENTRY, FATFS_INCEPTION, FATDefaults,
|
||||
get_args_for_partition_generator, read_filesystem)
|
||||
from fatfs_utils.long_filename_utils import get_required_lfn_entries_count
|
||||
from fatfs_utils.utils import (BYTES_PER_DIRECTORY_ENTRY, FATFS_INCEPTION, FATFS_MIN_ALLOC_UNIT,
|
||||
RESERVED_CLUSTERS_COUNT, FATDefaults, get_args_for_partition_generator,
|
||||
get_fat_sectors_count, get_non_data_sectors_cnt, read_filesystem,
|
||||
required_clusters_count)
|
||||
|
||||
|
||||
class FATFS:
|
||||
@ -184,8 +188,47 @@ class FATFS:
|
||||
self._generate_partition_from_folder(folder_name, folder_path=path_to_folder, is_dir=True)
|
||||
|
||||
|
||||
def calculate_min_space(path: List[str],
|
||||
fs_entity: str,
|
||||
sector_size: int = 0x1000,
|
||||
long_file_names: bool = False,
|
||||
is_root: bool = False) -> int:
|
||||
if os.path.isfile(os.path.join(*path, fs_entity)):
|
||||
with open(os.path.join(*path, fs_entity), 'rb') as file_:
|
||||
content = file_.read()
|
||||
res: int = required_clusters_count(sector_size, content)
|
||||
return res
|
||||
buff: int = 0
|
||||
dir_size = 2 * FATDefaults.ENTRY_SIZE # record for symlinks "." and ".."
|
||||
for file in sorted(os.listdir(os.path.join(*path, fs_entity))):
|
||||
if long_file_names and True:
|
||||
# LFN entries + one short entry
|
||||
dir_size += (get_required_lfn_entries_count(fs_entity) + 1) * FATDefaults.ENTRY_SIZE
|
||||
else:
|
||||
dir_size += FATDefaults.ENTRY_SIZE
|
||||
buff += calculate_min_space(path + [fs_entity], file, sector_size, long_file_names, is_root=False)
|
||||
if is_root and dir_size // FATDefaults.ENTRY_SIZE > FATDefaults.ROOT_ENTRIES_COUNT:
|
||||
raise NoFreeClusterException('Not enough space in root!')
|
||||
|
||||
# roundup sectors, at least one is required
|
||||
buff += (dir_size + sector_size - 1) // sector_size
|
||||
return buff
|
||||
|
||||
|
||||
def main() -> None:
|
||||
args = get_args_for_partition_generator('Create a FAT filesystem and populate it with directory content', wl=False)
|
||||
|
||||
if args.partition_size == -1:
|
||||
clusters = calculate_min_space([], args.input_directory, args.sector_size, long_file_names=True, is_root=True)
|
||||
fats = get_fat_sectors_count(clusters, args.sector_size)
|
||||
root_dir_sectors = (FATDefaults.ROOT_ENTRIES_COUNT * FATDefaults.ENTRY_SIZE) // args.sector_size
|
||||
args.partition_size = max(FATFS_MIN_ALLOC_UNIT * args.sector_size,
|
||||
(clusters + fats + get_non_data_sectors_cnt(RESERVED_CLUSTERS_COUNT,
|
||||
fats,
|
||||
root_dir_sectors)
|
||||
) * args.sector_size
|
||||
)
|
||||
|
||||
fatfs = FATFS(sector_size=args.sector_size,
|
||||
sectors_per_cluster=args.sectors_per_cluster,
|
||||
size=args.partition_size,
|
||||
|
Loading…
Reference in New Issue
Block a user