#!/usr/bin/env python # # esp-idf NVS partition generation tool. Tool helps in generating NVS-compatible # partition binary, with key-value pair entries provided via a CSV file. # # Copyright 2018 Espressif Systems (Shanghai) PTE LTD # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # import sys import argparse import binascii import getopt import struct import os import array import csv import zlib from os import path """ Class for standard NVS page structure """ class Page(object): PAGE_PARAMS = { "max_size": 4096, "max_blob_size": 1984, "max_entries": 126 } # Item type codes U8 = 0x01 I8 = 0x11 U16 = 0x02 I16 = 0x12 U32 = 0x04 I32 = 0x14 SZ = 0x21 BLOB = 0x41 # Few Page constants HEADER_SIZE = 32 BITMAPARRAY_OFFSET = 32 BITMAPARRAY_SIZE_IN_BYTES = 32 FIRST_ENTRY_OFFSET = 64 SINGLE_ENTRY_SIZE = 32 def __init__(self, page_num): self.entry_num = 0 self.bitmap_array = array.array('B') self.page_buf = bytearray(b'\xff')*Page.PAGE_PARAMS["max_size"] self.bitmap_array = self.create_bitmap_array() self.set_header(page_num) def set_header(self, page_num): # set page state to active page_header= bytearray(b'\xff')*32 page_state_active_seq = 0xFFFFFFFE page_header[0:4] = struct.pack(' Page.PAGE_PARAMS["max_blob_size"]: raise InputError("%s: Size exceeds max allowed length." % key) # Calculate no. of entries data will require rounded_size = (datalen + 31) & ~31 data_entry_count = rounded_size / 32 total_entry_count = data_entry_count + 1 # +1 for the entry header # Check if page is already full and new page is needed to be created right away if (self.entry_num + total_entry_count) >= Page.PAGE_PARAMS["max_entries"]: raise PageFullError() # Entry header entry_struct = bytearray('\xff')*32 entry_struct[0] = ns_index # namespace index entry_struct[2] = data_entry_count + 1 # Span # set key key_array = bytearray('\x00')*16 entry_struct[8:24] = key_array entry_struct[8:8 + len(key)] = key # set Type if encoding == "string": entry_struct[1] = Page.SZ elif encoding == "hex2bin" or encoding == "binary": entry_struct[1] = Page.BLOB # compute CRC of data entry_struct[24:26] = struct.pack('= Page.PAGE_PARAMS["max_entries"]: raise PageFullError() entry_struct = bytearray('\xff')*32 entry_struct[0] = ns_index # namespace index entry_struct[2] = 0x01 # Span # write key key_array = bytearray('\x00')*16 entry_struct[8:24] = key_array entry_struct[8:8 + len(key)] = key if encoding == "u8": entry_struct[1] = Page.U8 entry_struct[24] = struct.pack('