Tools: Fix memory calculations of idf_size.py

This commit is contained in:
simon.chupin
2021-07-28 00:24:05 +02:00
parent cf457bce0d
commit 8de953e7b9
7 changed files with 8145 additions and 14542 deletions

View File

@@ -1,8 +1,6 @@
/* Default entry point: */ /* Default entry point: */
ENTRY(call_start_cpu0); ENTRY(call_start_cpu0);
_diram_i_start = 0x40378000;
SECTIONS SECTIONS
{ {
/* RTC fast memory holds RTC wake stub code, /* RTC fast memory holds RTC wake stub code,
@@ -165,15 +163,6 @@ SECTIONS
} > iram0_0_seg } > iram0_0_seg
/**
* This section is required to skip .iram0.text area because iram0_0_seg and
* dram0_0_seg reflect the same address space on different buses.
*/
.dram0.dummy (NOLOAD):
{
. = ORIGIN(dram0_0_seg) + MAX(_iram_end - _diram_i_start, 0);
} > dram0_0_seg
.dram0.data : .dram0.data :
{ {
_data_start = ABSOLUTE(.); _data_start = ABSOLUTE(.);

View File

@@ -1,288 +0,0 @@
components/app_update/otatool.py
components/efuse/efuse_table_gen.py
components/efuse/test_efuse_host/efuse_tests.py
components/esp32s2/test/gen_digital_signature_tests.py
components/esp_local_ctrl/python/esp_local_ctrl_pb2.py
components/esp_netif/test_apps/component_ut_test.py
components/espcoredump/corefile/gdb.py
components/espcoredump/test/test_espcoredump.py
components/lwip/weekend_test/net_suite_test.py
components/mbedtls/esp_crt_bundle/gen_crt_bundle.py
components/mbedtls/esp_crt_bundle/test_gen_crt_bundle/test_gen_crt_bundle.py
components/mqtt/weekend_test/mqtt_publish_test.py
components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py
components/partition_table/gen_empty_partition.py
components/partition_table/gen_esp32part.py
components/partition_table/parttool.py
components/partition_table/test_gen_esp32part_host/gen_esp32part_tests.py
components/protocomm/python/constants_pb2.py
components/protocomm/python/sec0_pb2.py
components/protocomm/python/sec1_pb2.py
components/protocomm/python/session_pb2.py
components/ulp/esp32ulp_mapgen.py
components/wifi_provisioning/python/wifi_config_pb2.py
components/wifi_provisioning/python/wifi_constants_pb2.py
components/wifi_provisioning/python/wifi_scan_pb2.py
components/xtensa/trax/traceparse.py
docs/build_docs.py
docs/conf_common.py
docs/en/conf.py
docs/extensions/google_analytics.py
docs/extensions/html_redirects.py
docs/extensions/list_filter.py
docs/extensions/toctree_filter.py
docs/generate_chart.py
docs/get_github_rev.py
docs/idf_extensions/build_system/__init__.py
docs/idf_extensions/esp_err_definitions.py
docs/idf_extensions/exclude_docs.py
docs/idf_extensions/format_idf_target.py
docs/idf_extensions/gen_defines.py
docs/idf_extensions/gen_idf_tools_links.py
docs/idf_extensions/gen_toolchain_links.py
docs/idf_extensions/gen_version_specific_includes.py
docs/idf_extensions/include_build_file.py
docs/idf_extensions/kconfig_reference.py
docs/idf_extensions/latex_builder.py
docs/idf_extensions/link_roles.py
docs/idf_extensions/run_doxygen.py
docs/idf_extensions/util.py
docs/sanitize_version.py
docs/test/en/conf.py
docs/test/test_docs.py
docs/test/test_sphinx_idf_extensions.py
docs/zh_CN/conf.py
examples/bluetooth/nimble/blecent/blecent_test.py
examples/bluetooth/nimble/blehr/blehr_test.py
examples/bluetooth/nimble/bleprph/bleprph_test.py
examples/cxx/exceptions/example_test.py
examples/cxx/pthread/example_test.py
examples/cxx/rtti/example_test.py
examples/get-started/blink/example_test.py
examples/get-started/hello_world/example_test.py
examples/peripherals/gpio/generic_gpio/example_test.py
examples/peripherals/i2c/i2c_tools/example_test.py
examples/peripherals/rmt/ir_protocols/example_test.py
examples/peripherals/sdio/sdio_test.py
examples/peripherals/twai/twai_alert_and_recovery/example_test.py
examples/peripherals/twai/twai_network/example_test.py
examples/peripherals/twai/twai_self_test/example_test.py
examples/protocols/asio/chat_client/asio_chat_client_test.py
examples/protocols/asio/chat_server/asio_chat_server_test.py
examples/protocols/asio/ssl_client_server/example_test.py
examples/protocols/asio/tcp_echo_server/asio_tcp_server_test.py
examples/protocols/asio/udp_echo_server/asio_udp_server_test.py
examples/protocols/cbor/example_test.py
examples/protocols/esp_http_client/esp_http_client_test.py
examples/protocols/esp_local_ctrl/example_test.py
examples/protocols/esp_local_ctrl/scripts/esp_local_ctrl.py
examples/protocols/esp_local_ctrl/scripts/proto.py
examples/protocols/http_server/advanced_tests/http_server_advanced_test.py
examples/protocols/http_server/advanced_tests/scripts/test.py
examples/protocols/http_server/persistent_sockets/http_server_persistence_test.py
examples/protocols/http_server/simple/http_server_simple_test.py
examples/protocols/http_server/ws_echo_server/ws_server_example_test.py
examples/protocols/https_request/example_test.py
examples/protocols/https_x509_bundle/example_test.py
examples/protocols/icmp_echo/example_test.py
examples/protocols/mdns/mdns_example_test.py
examples/protocols/modbus/serial/example_test.py
examples/protocols/modbus/tcp/example_test.py
examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py
examples/protocols/mqtt/ssl_ds/configure_ds.py
examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py
examples/protocols/mqtt/ws/mqtt_ws_example_test.py
examples/protocols/mqtt/wss/mqtt_wss_example_test.py
examples/protocols/openssl_client/example_test.py
examples/protocols/openssl_server/example_test.py
examples/protocols/pppos_client/example_test.py
examples/protocols/sntp/example_test.py
examples/protocols/sockets/non_blocking/example_test.py
examples/protocols/sockets/tcp_client/example_test.py
examples/protocols/sockets/tcp_server/example_test.py
examples/protocols/sockets/udp_client/example_test.py
examples/protocols/sockets/udp_server/example_test.py
examples/protocols/websocket/example_test.py
examples/provisioning/legacy/ble_prov/ble_prov_test.py
examples/provisioning/legacy/custom_config/components/custom_provisioning/python/custom_config_pb2.py
examples/provisioning/legacy/softap_prov/softap_prov_test.py
examples/provisioning/wifi_prov_mgr/wifi_prov_mgr_test.py
examples/security/flash_encryption/example_test.py
examples/storage/ext_flash_fatfs/example_test.py
examples/storage/nvs_rw_blob/nvs_rw_blob_example_test.py
examples/storage/nvs_rw_value/nvs_rw_value_example_test.py
examples/storage/nvs_rw_value_cxx/nvs_rw_value_cxx_example_test.py
examples/storage/partition_api/partition_find/partition_find_example_test.py
examples/storage/partition_api/partition_mmap/partition_mmap_example_test.py
examples/storage/partition_api/partition_ops/partition_ops_example_test.py
examples/storage/parttool/example_test.py
examples/storage/parttool/parttool_example.py
examples/storage/sd_card/sd_card_example_test.py
examples/storage/semihost_vfs/semihost_vfs_example_test.py
examples/storage/spiffs/spiffs_example_test.py
examples/storage/spiffsgen/example_test.py
examples/storage/wear_levelling/wear_levelling_example_test.py
examples/system/app_trace_to_host/example_test.py
examples/system/base_mac_address/example_test.py
examples/system/console/example_test.py
examples/system/deep_sleep/example_test.py
examples/system/esp_event/default_event_loop/example_test.py
examples/system/esp_event/user_event_loops/example_test.py
examples/system/esp_timer/example_test.py
examples/system/freertos/real_time_stats/example_test.py
examples/system/gcov/example_test.py
examples/system/himem/example_test.py
examples/system/light_sleep/example_test.py
examples/system/ota/advanced_https_ota/example_test.py
examples/system/ota/native_ota_example/example_test.py
examples/system/ota/otatool/example_test.py
examples/system/ota/otatool/get_running_partition.py
examples/system/ota/otatool/otatool_example.py
examples/system/ota/simple_ota_example/example_test.py
examples/system/perfmon/example_test.py
examples/system/select/example_test.py
examples/system/sysview_tracing/example_test.py
examples/system/sysview_tracing_heap_log/example_test.py
examples/system/task_watchdog/example_test.py
examples/system/ulp/example_test.py
examples/system/ulp_adc/example_test.py
examples/system/unit_test/example_test.py
examples/wifi/iperf/iperf_test.py
tools/ble/lib_ble_client.py
tools/ble/lib_gap.py
tools/ble/lib_gatt.py
tools/check_python_dependencies.py
tools/check_term.py
tools/ci/check_artifacts_expire_time.py
tools/ci/check_callgraph.py
tools/ci/check_codeowners.py
tools/ci/check_deprecated_kconfigs.py
tools/ci/check_examples_cmake_make.py
tools/ci/check_executables.py
tools/ci/check_kconfigs.py
tools/ci/check_public_headers.py
tools/ci/check_readme_links.py
tools/ci/check_rules_yml.py
tools/ci/check_tools_files_patterns.py
tools/ci/checkout_project_ref.py
tools/ci/ci_fetch_submodule.py
tools/ci/deploy_docs.py
tools/ci/envsubst.py
tools/ci/normalize_clangtidy_path.py
tools/ci/python_packages/gitlab_api.py
tools/ci/python_packages/idf_http_server_test/adder.py
tools/ci/python_packages/idf_http_server_test/client.py
tools/ci/python_packages/idf_http_server_test/test.py
tools/ci/python_packages/idf_iperf_test_util/Attenuator.py
tools/ci/python_packages/idf_iperf_test_util/LineChart.py
tools/ci/python_packages/idf_iperf_test_util/PowerControl.py
tools/ci/python_packages/idf_iperf_test_util/TestReport.py
tools/ci/python_packages/tiny_test_fw/App.py
tools/ci/python_packages/tiny_test_fw/DUT.py
tools/ci/python_packages/tiny_test_fw/Env.py
tools/ci/python_packages/tiny_test_fw/EnvConfig.py
tools/ci/python_packages/tiny_test_fw/TinyFW.py
tools/ci/python_packages/tiny_test_fw/Utility/CIAssignTest.py
tools/ci/python_packages/tiny_test_fw/Utility/CaseConfig.py
tools/ci/python_packages/tiny_test_fw/Utility/GitlabCIJob.py
tools/ci/python_packages/tiny_test_fw/Utility/SearchCases.py
tools/ci/python_packages/tiny_test_fw/Utility/TestCase.py
tools/ci/python_packages/tiny_test_fw/bin/Runner.py
tools/ci/python_packages/tiny_test_fw/bin/example.py
tools/ci/python_packages/tiny_test_fw/docs/conf.py
<<<<<<< HEAD
=======
tools/ci/python_packages/ttfw_idf/CIScanTests.py
>>>>>>> idf_size.py: fixed diram counted twice issue, and improve display
tools/ci/python_packages/ttfw_idf/DebugUtils.py
tools/ci/python_packages/ttfw_idf/IDFAssignTest.py
tools/ci/python_packages/ttfw_idf/IDFDUT.py
tools/ci/python_packages/ttfw_idf/__init__.py
tools/ci/python_packages/ttfw_idf/unity_test_parser.py
tools/ci/python_packages/wifi_tools.py
tools/ci/test_autocomplete.py
tools/ci/test_check_kconfigs.py
tools/cmake/convert_to_cmake.py
tools/esp_app_trace/espytrace/apptrace.py
tools/esp_app_trace/espytrace/sysview.py
tools/esp_app_trace/logtrace_proc.py
tools/esp_app_trace/sysviewtrace_proc.py
tools/esp_prov/esp_prov.py
tools/esp_prov/prov/custom_prov.py
tools/esp_prov/prov/wifi_prov.py
tools/esp_prov/prov/wifi_scan.py
tools/esp_prov/security/security.py
tools/esp_prov/security/security0.py
tools/esp_prov/security/security1.py
tools/esp_prov/transport/ble_cli.py
tools/esp_prov/transport/transport.py
tools/esp_prov/transport/transport_ble.py
tools/esp_prov/transport/transport_console.py
tools/esp_prov/transport/transport_http.py
tools/esp_prov/utils/convenience.py
tools/find_apps.py
tools/find_build_apps/common.py
tools/find_build_apps/make.py
tools/gen_esp_err_to_name.py
tools/idf.py
tools/idf_monitor.py
tools/idf_py_actions/constants.py
tools/idf_py_actions/core_ext.py
tools/idf_py_actions/create_ext.py
tools/idf_py_actions/debug_ext.py
tools/idf_py_actions/dfu_ext.py
tools/idf_py_actions/errors.py
tools/idf_py_actions/global_options.py
tools/idf_py_actions/serial_ext.py
tools/idf_py_actions/tools.py
tools/idf_py_actions/uf2_ext.py
tools/idf_size.py
tools/kconfig_new/confgen.py
tools/kconfig_new/confserver.py
tools/kconfig_new/esp-windows-curses/setup.py
tools/kconfig_new/gen_kconfig_doc.py
tools/kconfig_new/prepare_kconfig_files.py
tools/kconfig_new/test/confgen/test_confgen.py
tools/kconfig_new/test/confserver/test_confserver.py
tools/kconfig_new/test/gen_kconfig_doc/test_kconfig_out.py
tools/kconfig_new/test/gen_kconfig_doc/test_target_visibility.py
tools/ldgen/fragments.py
tools/ldgen/generation.py
tools/ldgen/ldgen.py
tools/ldgen/ldgen_common.py
tools/ldgen/linker_script.py
tools/ldgen/output_commands.py
tools/ldgen/sdkconfig.py
tools/ldgen/test/test_entity.py
tools/ldgen/test/test_fragments.py
tools/ldgen/test/test_generation.py
tools/ldgen/test/test_output_commands.py
tools/mass_mfg/mfg_gen.py
tools/mkuf2.py
tools/test_apps/build_system/ldgen_test/check_placements.py
tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py
tools/test_apps/protocols/openssl/app_test.py
tools/test_apps/protocols/pppos/app_test.py
tools/test_apps/system/gdb_loadable_elf/app_test.py
tools/test_apps/system/longjmp_test/app_test.py
tools/test_apps/system/memprot/app_test.py
tools/test_apps/system/monitor_ide_integration/app_test.py
tools/test_apps/system/panic/app_test.py
tools/test_apps/system/panic/panic_tests.py
tools/test_apps/system/panic/test_panic_util/test_panic_util.py
tools/test_apps/system/startup/app_test.py
tools/test_idf_monitor/idf_monitor_wrapper.py
tools/test_idf_monitor/run_test_idf_monitor.py
tools/test_idf_py/extra_path/some_ext.py
tools/test_idf_py/idf_ext.py
tools/test_idf_py/test_idf_extensions/test_ext/test_extension.py
tools/test_idf_py/test_idf_py.py
tools/test_idf_size/test_idf_size.py
tools/test_idf_tools/test_idf_tools.py
tools/test_mkdfu/test_mkdfu.py
tools/test_mkuf2/test_mkuf2.py
tools/unit-test-app/idf_ext.py
tools/unit-test-app/tools/CreateSectionTable.py
tools/unit-test-app/tools/UnitTestParser.py
tools/unit-test-app/unit_test.py
tools/windows/eclipse_make.py

View File

@@ -20,10 +20,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
from __future__ import print_function from __future__ import division, print_function, unicode_literals
from __future__ import unicode_literals
from __future__ import division
from future.utils import iteritems
import argparse import argparse
import collections import collections
import json import json
@@ -31,8 +29,6 @@ import os.path
import re import re
import sys import sys
<<<<<<< HEAD
=======
from future.utils import iteritems from future.utils import iteritems
try: try:
@@ -48,7 +44,6 @@ except NameError:
basestring = str basestring = str
>>>>>>> idf_size.py: fixed diram counted twice issue, and improve display
GLOBAL_JSON_INDENT = 4 GLOBAL_JSON_INDENT = 4
GLOBAL_JSON_SEPARATORS = (',', ': ') GLOBAL_JSON_SEPARATORS = (',', ': ')
@@ -98,37 +93,6 @@ class MemRegions(object):
MemRegDef(0x40070000, 0x2000, MemRegions.RTC_FAST_D_ID, 0x3FF9E000), MemRegDef(0x40070000, 0x2000, MemRegions.RTC_FAST_D_ID, 0x3FF9E000),
MemRegDef(0x50000000, 0x2000, MemRegions.RTC_SLOW_D_ID, 0), MemRegDef(0x50000000, 0x2000, MemRegions.RTC_SLOW_D_ID, 0),
]) ])
<<<<<<< HEAD
=======
elif target == 'esp32s3':
return sorted([
# IRAM, usually used by Icache.
#
# The segment from the ld file lies across the boundary of the line below: it is
# partly IRAM and partly D/IRAM. Here's a workaround for this kind of segment: we
# only list the DIRAM part. If a segment from the ld file falls in any part of a
# DIRAM def region, we treat the whole segment D/IRAM.
#
# Uncomment the following line if sections of the same segment can be
# distinguished, or the ld file can give separated segment for the region.
#
MemRegDef(0x40370000, 0x8000, MemRegions.IRAM_ID, 0),
MemRegDef(0x3FC88000, 0x8000 + 6 * 0x10000, MemRegions.DRAM_ID, 0x40378000),
MemRegDef(0x3FCF0000, 0x10000, MemRegions.DRAM_ID, 0),
MemRegDef(0x42000000, 0x2000000, MemRegions.CACHE_I_ID, 0),
MemRegDef(0x3C000000, 0x2000000, MemRegions.CACHE_D_ID, 0),
MemRegDef(0x3ff80000, 0x2000, MemRegions.RTC_FAST_D_ID, 0x600FE000),
MemRegDef(0x50000000, 0x2000, MemRegions.RTC_SLOW_D_ID, 0),
])
elif target == 'esp32c3':
return sorted([
MemRegDef(0x3FC80000, 0x60000, MemRegions.DRAM_ID, 0x40380000),
MemRegDef(0x4037C000, 0x4000, MemRegions.IRAM_ID, 0),
MemRegDef(0x42000000, 0x800000, MemRegions.CACHE_I_ID, 0),
MemRegDef(0x3C000000, 0x800000, MemRegions.CACHE_D_ID, 0),
MemRegDef(0x50000000, 0x2000, MemRegions.RTC_SLOW_D_ID, 0),
])
>>>>>>> idf_size.py: fixed diram counted twice issue, and improve display
else: else:
raise RuntimeError('Target not detected.') raise RuntimeError('Target not detected.')
@@ -231,12 +195,13 @@ class LinkingSections(object):
score_list = [get_name_score(section) for section in section_name_list] score_list = [get_name_score(section) for section in section_name_list]
ordered_name_list = sorted(section_name_list, key=lambda x: score_list[section_name_list.index(x)], reverse=True) ordered_name_list = sorted(section_name_list, key=lambda x: score_list[section_name_list.index(x)], reverse=True)
display_name_list = ordered_name_list.copy() display_name_list = ordered_name_list[:]
memory_name = '' memory_name = ''
for i in range(len(section_name_list)): display_name_list = sorted(display_name_list)
section = ordered_name_list[i] ordered_name_list = sorted(ordered_name_list)
ordered_name_list = check_is_dict_sort(ordered_name_list)
for i, section in enumerate(ordered_name_list):
if memory_name and section.startswith(memory_name): if memory_name and section.startswith(memory_name):
# If the section has same memory type with the previous one, use shorter name # If the section has same memory type with the previous one, use shorter name
display_name_list[i] = section.replace(memory_name, '& ') display_name_list[i] = section.replace(memory_name, '& ')
@@ -247,9 +212,12 @@ class LinkingSections(object):
if len(split_name) > 1: if len(split_name) > 1:
# If the section has a memory type, update the type and try to display the type properly # If the section has a memory type, update the type and try to display the type properly
assert len(split_name) == 3 and split_name[0] == '', 'Unexpected section name' assert len(split_name) == 3 and split_name[0] == '', 'Unexpected section name'
memory_name = '.' + split_name[1] memory_name = '.iram' if 'iram' in split_name[1] else\
'.dram' if 'dram' in split_name[1] else\
'.flash' if 'flash' in split_name[1] else\
'.' + split_name[1]
display_name_list[i] = 'DRAM .' + split_name[2] if 'dram' in split_name[1] else\ display_name_list[i] = 'DRAM .' + split_name[2] if 'dram' in split_name[1] else\
'IRAM .' + split_name[2] if 'iram' in split_name[1] else\ 'IRAM' + split_name[1].replace('iram', '') + ' .' + split_name[2] if 'iram' in split_name[1] else\
'Flash .' + split_name[2] if 'flash' in split_name[1] else\ 'Flash .' + split_name[2] if 'flash' in split_name[1] else\
section section
continue continue
@@ -285,13 +253,6 @@ def load_map_data(map_file): # type: (TextIO) -> Tuple[str, Dict, Dict]
if dummy_keys: if dummy_keys:
sections.pop(*dummy_keys) sections.pop(*dummy_keys)
<<<<<<< HEAD
def load_memory_config(map_file):
""" Memory Configuration section is the total size of each output section """
result = {}
scan_to_header(map_file, "Memory Configuration")
RE_MEMORY_SECTION = re.compile(r"(?P<name>[^ ]+) +0x(?P<origin>[\da-f]+) +0x(?P<length>[\da-f]+)")
=======
return detected_chip, segments, sections return detected_chip, segments, sections
@@ -300,7 +261,6 @@ def load_segments(map_file): # type: (TextIO) -> Dict
result = {} # type: Dict[Any, Dict] result = {} # type: Dict[Any, Dict]
scan_to_header(map_file, 'Memory Configuration') scan_to_header(map_file, 'Memory Configuration')
RE_MEMORY_SECTION = re.compile(r'(?P<name>[^ ]+) +0x(?P<origin>[\da-f]+) +0x(?P<length>[\da-f]+)') RE_MEMORY_SECTION = re.compile(r'(?P<name>[^ ]+) +0x(?P<origin>[\da-f]+) +0x(?P<length>[\da-f]+)')
>>>>>>> idf_size.py: fixed diram counted twice issue, and improve display
for line in map_file: for line in map_file:
m = RE_MEMORY_SECTION.match(line) m = RE_MEMORY_SECTION.match(line)
@@ -309,20 +269,6 @@ def load_segments(map_file): # type: (TextIO) -> Dict
continue # whitespace or a header, before the content we want continue # whitespace or a header, before the content we want
else: else:
return result # we're at the end of the Memory Configuration return result # we're at the end of the Memory Configuration
<<<<<<< HEAD
section = {
"name": m.group("name"),
"origin": int(m.group("origin"), 16),
"length": int(m.group("length"), 16),
}
if section["name"] != "*default*":
result[section["name"]] = section
raise RuntimeError("End of file while scanning memory configuration?")
def detect_target_chip(map_file):
''' Detect target chip based on the xtensa toolchain name in in the linker script part of the MAP file '''
=======
segment = { segment = {
'name': m.group('name'), 'name': m.group('name'),
'origin': int(m.group('origin'), 16), 'origin': int(m.group('origin'), 16),
@@ -335,28 +281,30 @@ def detect_target_chip(map_file):
def detect_target_chip(map_file): # type: (Iterable) -> str def detect_target_chip(map_file): # type: (Iterable) -> str
''' Detect target chip based on the target archive name in the linker script part of the MAP file ''' ''' Detect target chip based on the target archive name in the linker script part of the MAP file '''
>>>>>>> idf_size.py: fixed diram counted twice issue, and improve display
scan_to_header(map_file, 'Linker script and memory map') scan_to_header(map_file, 'Linker script and memory map')
RE_TARGET = re.compile(r'^LOAD .*?/xtensa-([^-]+)-elf/') RE_TARGET = re.compile(r'project_elf_src_(.*)\.c.obj')
# For back-compatible with make
RE_TARGET_MAKE = re.compile(r'^LOAD .*?/xtensa-([^-]+)-elf/')
for line in map_file: for line in map_file:
m = RE_TARGET.search(line) m = RE_TARGET.search(line)
if m: if m:
return m.group(1) return m.group(1)
m = RE_TARGET_MAKE.search(line)
if m:
return m.group(1)
line = line.strip() line = line.strip()
# There could be empty line(s) between the "Linker script and memory map" header and "LOAD lines". Therefore, # There could be empty line(s) between the "Linker script and memory map" header and "LOAD lines". Therefore,
# line stripping and length is checked as well. The "LOAD lines" are between START GROUP and END GROUP for # line stripping and length is checked as well. The "LOAD lines" are between START GROUP and END GROUP for
# older MAP files. # older MAP files.
if not line.startswith(('LOAD', 'START GROUP')) and len(line) > 0: if not line.startswith(('LOAD', 'START GROUP', 'END GROUP')) and len(line) > 0:
# This break is a failsafe to not process anything load_sections() might want to analyze. # This break is a failsafe to not process anything load_sections() might want to analyze.
break break
<<<<<<< HEAD
return None
=======
raise RuntimeError('Target not detected') raise RuntimeError('Target not detected')
>>>>>>> idf_size.py: fixed diram counted twice issue, and improve display
def load_sections(map_file): # type: (TextIO) -> Dict def load_sections(map_file): # type: (TextIO) -> Dict
@@ -374,31 +322,17 @@ def load_sections(map_file): # type: (TextIO) -> Dict
line, the <file> must exist, or the <sym_name> should be is no *fill*. This rule is used to tell sections from line, the <file> must exist, or the <sym_name> should be is no *fill*. This rule is used to tell sections from
source lines. source lines.
""" """
<<<<<<< HEAD
# output section header, ie '.iram0.text 0x0000000040080400 0x129a5'
RE_SECTION_HEADER = re.compile(r"(?P<name>[^ ]+) +0x(?P<address>[\da-f]+) +0x(?P<size>[\da-f]+)$")
=======
# Check for lines which only contain the sym name (and rest is on following lines) # Check for lines which only contain the sym name (and rest is on following lines)
RE_SYMBOL_ONLY_LINE = re.compile(r'^\s*(?P<sym_name>\S*)$') RE_SYMBOL_ONLY_LINE = re.compile(r'^\s*(?P<sym_name>\S*)$')
# Fast check to see if line is a potential source line before running the slower full regex against it # Fast check to see if line is a potential source line before running the slower full regex against it
RE_PRE_FILTER = re.compile(r'.*0x[\da-f]+\s*0x[\da-f]+.*') RE_PRE_FILTER = re.compile(r'.*0x[\da-f]+\s*0x[\da-f]+.*')
>>>>>>> idf_size.py: fixed diram counted twice issue, and improve display
# source file line, ie # source file line, ie
# 0x0000000040080400 0xa4 /home/gus/esp/32/idf/examples/get-started/hello_world/build/esp32/libesp32.a(cpu_start.o) # 0x0000000040080400 0xa4 /home/gus/esp/32/idf/examples/get-started/hello_world/build/esp32/libesp32.a(cpu_start.o)
# cmake build system links some object files directly, not part of any archive, so make that part optional # cmake build system links some object files directly, not part of any archive, so make that part optional
# .xtensa.info 0x0000000000000000 0x38 CMakeFiles/hello-world.elf.dir/project_elf_src.c.obj # .xtensa.info 0x0000000000000000 0x38 CMakeFiles/hello-world.elf.dir/project_elf_src.c.obj
<<<<<<< HEAD
RE_SOURCE_LINE = re.compile(r"\s*(?P<sym_name>\S*) +0x(?P<address>[\da-f]+) +0x(?P<size>[\da-f]+) (?P<archive>.+\.a)?\(?(?P<object_file>.+\.(o|obj))\)?")
# Fast check to see if line is a potential source line before running the slower full regex against it
RE_PRE_FILTER = re.compile(r".*\.(o|obj)\)?")
# Check for lines which only contain the sym name (and rest is on following lines)
RE_SYMBOL_ONLY_LINE = re.compile(r"^ (?P<sym_name>\S*)$")
=======
# *fill* 0x00000000400e2967 0x1 # *fill* 0x00000000400e2967 0x1
RE_FULL_LINE = re.compile(r'\s*(?P<sym_name>\S*) +0x(?P<address>[\da-f]+) +0x(?P<size>[\da-f]+)\s*(?P<file>.*)$') RE_FULL_LINE = re.compile(r'\s*(?P<sym_name>\S*) +0x(?P<address>[\da-f]+) +0x(?P<size>[\da-f]+)\s*(?P<file>.*)$')
@@ -407,18 +341,12 @@ def load_sections(map_file): # type: (TextIO) -> Dict
def dump_src_line(src): # type: (Dict) -> str def dump_src_line(src): # type: (Dict) -> str
return '%s(%s) addr: 0x%08x, size: 0x%x+%d' % (src['sym_name'], src['file'], src['address'], src['size'], src['fill']) return '%s(%s) addr: 0x%08x, size: 0x%x+%d' % (src['sym_name'], src['file'], src['address'], src['size'], src['fill'])
>>>>>>> idf_size.py: fixed diram counted twice issue, and improve display
sections = {} # type: Dict[Any, Dict] sections = {} # type: Dict[Any, Dict]
section = {} # type: Dict[str, Any] section = {} # type: Dict[str, Any]
sym_backup = '' sym_backup = ''
for line in map_file: for line in map_file:
<<<<<<< HEAD
if line.strip() == "Cross Reference Table":
=======
if line.strip() == 'Cross Reference Table': if line.strip() == 'Cross Reference Table':
>>>>>>> idf_size.py: fixed diram counted twice issue, and improve display
# stop processing lines because we are at the next section in the map file # stop processing lines because we are at the next section in the map file
break break
@@ -445,21 +373,6 @@ def load_sections(map_file): # type: (TextIO) -> Dict
# section # section
section = { section = {
<<<<<<< HEAD
"name": m.group("name"),
"address": int(m.group("address"), 16),
"size": int(m.group("size"), 16),
"sources": [],
}
sections[section["name"]] = section
continue
if section is not None:
m = RE_SYMBOL_ONLY_LINE.match(line)
if m is not None:
# In some cases the section name appears on the previous line, back it up in here
sym_backup = m.group("sym_name")
=======
'name': name, 'name': name,
'address': int(m.group('address'), 16), 'address': int(m.group('address'), 16),
'size': int(m.group('size'), 16), 'size': int(m.group('size'), 16),
@@ -470,7 +383,6 @@ def load_sections(map_file): # type: (TextIO) -> Dict
else: else:
# symbol # symbol
if not section: if not section:
>>>>>>> idf_size.py: fixed diram counted twice issue, and improve display
continue continue
# There are some source lines in rodata section doesn't actually take any space, but have size # There are some source lines in rodata section doesn't actually take any space, but have size
@@ -494,25 +406,6 @@ def load_sections(map_file): # type: (TextIO) -> Dict
break break
continue continue
<<<<<<< HEAD
m = RE_SOURCE_LINE.match(line)
if m is not None: # input source file details=ma,e
sym_name = m.group("sym_name") if len(m.group("sym_name")) > 0 else sym_backup
archive = m.group("archive")
if archive is None:
# optional named group "archive" was not matched, so assign a value to it
archive = "(exe)"
source = {
"size": int(m.group("size"), 16),
"address": int(m.group("address"), 16),
"archive": os.path.basename(archive),
"object_file": os.path.basename(m.group("object_file")),
"sym_name": sym_name,
}
source["file"] = "%s:%s" % (source["archive"], source["object_file"])
section["sources"] += [source]
=======
# Extract archive and file information # Extract archive and file information
n = RE_FILE.match(m.group('file')) n = RE_FILE.match(m.group('file'))
assert n assert n
@@ -551,7 +444,6 @@ def load_sections(map_file): # type: (TextIO) -> Dict
print(' ' + dump_src_line(src)) print(' ' + dump_src_line(src))
src_curr = src src_curr = src
>>>>>>> idf_size.py: fixed diram counted twice issue, and improve display
return sections return sections
@@ -561,31 +453,14 @@ def check_target(target, map_file): # type: (str, TextIO) -> None
raise RuntimeError('The target chip cannot be detected for {}. ' raise RuntimeError('The target chip cannot be detected for {}. '
'Please report the issue.'.format(map_file.name)) 'Please report the issue.'.format(map_file.name))
<<<<<<< HEAD
@staticmethod
def get(mem_regions, memory_config, sections):
mreg = MemRegNames()
mreg.iram_names = mem_regions.get_names(memory_config, MemRegions.IRAM_ID)
mreg.dram_names = mem_regions.get_names(memory_config, MemRegions.DRAM_ID)
mreg.diram_names = mem_regions.get_names(memory_config, MemRegions.DIRAM_ID)
mreg.used_iram_names = mem_regions.get_names(sections, MemRegions.IRAM_ID)
mreg.used_dram_names = mem_regions.get_names(sections, MemRegions.DRAM_ID)
mreg.used_diram_names = mem_regions.get_names(sections, MemRegions.DIRAM_ID)
return mreg
def main():
parser = argparse.ArgumentParser(description="idf_size - a tool to print size information from an IDF MAP file")
=======
def main(): # type: () -> None def main(): # type: () -> None
parser = argparse.ArgumentParser(description='idf_size - a tool to print size information from an IDF MAP file') parser = argparse.ArgumentParser(description='idf_size - a tool to print size information from an IDF MAP file')
>>>>>>> idf_size.py: fixed diram counted twice issue, and improve display
parser.add_argument( parser.add_argument(
'--json', '--json',
help="Output results as JSON", help='Output results as JSON',
action="store_true") action='store_true')
parser.add_argument( parser.add_argument(
'map_file', help='MAP file produced by linker', 'map_file', help='MAP file produced by linker',
@@ -614,7 +489,7 @@ def main(): # type: () -> None
'--output-file', '--output-file',
type=argparse.FileType('w'), type=argparse.FileType('w'),
default=sys.stdout, default=sys.stdout,
help="Print output to the specified file instead of stdout") help='Print output to the specified file instead of stdout')
args = parser.parse_args() args = parser.parse_args()
@@ -647,15 +522,9 @@ def main(): # type: () -> None
args.another_map_file, segments_diff, sections_diff, detected_target_diff) args.another_map_file, segments_diff, sections_diff, detected_target_diff)
if args.archives: if args.archives:
<<<<<<< HEAD
output += get_detailed_sizes(mem_reg, sections, "archive", "Archive File", args.json, sections_diff)
if args.files:
output += get_detailed_sizes(mem_reg, sections, "file", "Object File", args.json, sections_diff)
=======
output += get_detailed_sizes(sections, 'archive', 'Archive File', args.json, sections_diff) output += get_detailed_sizes(sections, 'archive', 'Archive File', args.json, sections_diff)
if args.files: if args.files:
output += get_detailed_sizes(sections, 'file', 'Object File', args.json, sections_diff) output += get_detailed_sizes(sections, 'file', 'Object File', args.json, sections_diff)
>>>>>>> idf_size.py: fixed diram counted twice issue, and improve display
if args.archive_details: if args.archive_details:
output += get_archive_symbols(sections, args.archive_details, args.json, sections_diff) output += get_archive_symbols(sections, args.archive_details, args.json, sections_diff)
@@ -712,9 +581,10 @@ class StructureForSummary(object):
dram_filter = filter(in_dram, segments) dram_filter = filter(in_dram, segments)
r.dram_total = get_size(dram_filter) r.dram_total = get_size(dram_filter)
iram_filter = filter(in_iram, segments) iram_filter = filter(in_iram, segments)
r.iram_total = get_size(iram_filter) r.iram_total = get_size(iram_filter)
if r.diram_total == 0:
r.diram_total = r.dram_total + r.iram_total
def filter_in_section(sections, section_to_check): # type: (Iterable[MemRegions.Region], str) -> List[MemRegions.Region] def filter_in_section(sections, section_to_check): # type: (Iterable[MemRegions.Region], str) -> List[MemRegions.Region]
return list(filter(lambda x: LinkingSections.in_section(x.section, section_to_check), sections)) # type: ignore return list(filter(lambda x: LinkingSections.in_section(x.section, section_to_check), sections)) # type: ignore
@@ -722,6 +592,8 @@ class StructureForSummary(object):
dram_sections = list(filter(in_dram, sections)) dram_sections = list(filter(in_dram, sections))
iram_sections = list(filter(in_iram, sections)) iram_sections = list(filter(in_iram, sections))
diram_sections = list(filter(in_diram, sections)) diram_sections = list(filter(in_diram, sections))
if not diram_sections:
diram_sections = dram_sections + iram_sections
flash_sections = filter_in_section(sections, 'flash') flash_sections = filter_in_section(sections, 'flash')
dram_data_list = filter_in_section(dram_sections, 'data') dram_data_list = filter_in_section(dram_sections, 'data')
@@ -786,7 +658,6 @@ class StructureForSummary(object):
# The used DRAM BSS is counted into the "Used static DRAM" but not into the "Total image size" # The used DRAM BSS is counted into the "Used static DRAM" but not into the "Total image size"
r.total_size = r.used_dram - r.used_dram_bss + r.used_iram + r.used_diram - r.used_diram_bss + r.used_flash r.total_size = r.used_dram - r.used_dram_bss + r.used_iram + r.used_diram - r.used_diram_bss + r.used_flash
return r return r
def get_json_dic(self): # type: (StructureForSummary) -> collections.OrderedDict def get_json_dic(self): # type: (StructureForSummary) -> collections.OrderedDict
@@ -974,6 +845,23 @@ def get_summary(path, segments, sections, target,
return output return output
def check_is_dict_sort(non_sort_list): # type: (List) -> List
# keeping the order data, bss, other, iram, diram, ram_st_total, flash_text, flash_rodata, flash_total
start_of_other = 0
props_sort = [] # type: List
props_elem = ['.data', '.bss', 'other', 'iram', 'diram', 'ram_st_total', 'flash.text', 'flash.rodata', 'flash', 'flash_total']
for i in props_elem:
for j in non_sort_list:
if i == 'other':
start_of_other = len(props_sort)
elif i in (j[0] if len(j[0]) > 1 else j) and (j[0] if len(j[0]) > 1 else j) not in props_sort:
props_sort.append(j)
for j in non_sort_list:
if j not in props_sort:
props_sort.insert(start_of_other, j)
return props_sort
class StructureForDetailedSizes(object): class StructureForDetailedSizes(object):
@staticmethod @staticmethod
@@ -985,21 +873,15 @@ class StructureForDetailedSizes(object):
""" """
result = {} # type: Dict[str, Dict[str, int]] result = {} # type: Dict[str, Dict[str, int]]
for _, section in iteritems(sections): for _, section in iteritems(sections):
for s in section["sources"]: for s in section['sources']:
if not s[key] in result: if not s[key] in result:
result[s[key]] = {} result[s[key]] = {}
archive = result[s[key]] archive = result[s[key]]
<<<<<<< HEAD
if not section["name"] in archive:
archive[section["name"]] = 0
archive[section["name"]] += s["size"]
=======
if not section['name'] in archive: if not section['name'] in archive:
archive[section['name']] = 0 archive[section['name']] = 0
archive[section['name']] += s['size'] archive[section['name']] += s['size']
if include_padding: if include_padding:
archive[section['name']] += s['fill'] archive[section['name']] += s['fill']
>>>>>>> idf_size.py: fixed diram counted twice issue, and improve display
return result return result
@staticmethod @staticmethod
@@ -1018,8 +900,10 @@ class StructureForDetailedSizes(object):
section_dict['ram_st_total'] = ram_st_total section_dict['ram_st_total'] = ram_st_total
section_dict['flash_total'] = flash_total section_dict['flash_total'] = flash_total
# TODO: keep the order data, bss, other, iram, diram, ram_st_total, flash_text, flash_rodata, flash_total sorted_dict = sorted(section_dict.items(), key=lambda elem: elem[0])
s.append((key, collections.OrderedDict(section_dict))) sorted_dict = check_is_dict_sort(sorted_dict)
s.append((key, collections.OrderedDict(sorted_dict)))
s = sorted(s, key=lambda elem: elem[0]) s = sorted(s, key=lambda elem: elem[0])
# do a secondary sort in order to have consistent order (for diff-ing the output) # do a secondary sort in order to have consistent order (for diff-ing the output)

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,32 @@
{ {
"dram_data": 9324, "dram_data": 9324,
"dram_bss": 8296, "dram_bss": 8296,
"dram_rodata": 0,
"dram_other": 0, "dram_other": 0,
"used_dram": 17620, "used_dram": 17620,
"available_dram": 163116, "dram_total": 180736,
"used_dram_ratio": 0.09749026203966006, "used_dram_ratio": 0.09749026203966006,
"dram_remain": 163116,
"iram_vectors": 1024,
"iram_text": 37908,
"iram_other": 0,
"used_iram": 38932, "used_iram": 38932,
"available_iram": 92140, "iram_total": 131072,
"used_iram_ratio": 0.297027587890625, "used_iram_ratio": 0.297027587890625,
"used_diram": 0, "iram_remain": 92140,
"available_diram": 0, "diram_data": 9324,
"used_diram_ratio": 0, "diram_bss": 8296,
"diram_text": 37908,
"diram_vectors": 1024,
"diram_rodata": 0,
"diram_other": 0,
"diram_total": 311808,
"used_diram": 56552,
"used_diram_ratio": 0.18136802134646962,
"diram_remain": 255256,
"flash_code": 146944, "flash_code": 146944,
"flash_rodata": 39580, "flash_rodata": 39580,
"total_size": 234780 "flash_other": 0,
"used_flash_non_ram": 186524,
"total_size": 283036
} }

View File

@@ -1,8 +1,16 @@
Total sizes: Total sizes:
DRAM .data size: 9324 bytes Used static DRAM: 17620 bytes ( 163116 remain, 9.7% used)
DRAM .bss size: 8296 bytes .data size: 9324 bytes
Used static DRAM: 17620 bytes ( 163116 available, 9.7% used) .bss size: 8296 bytes
Used static IRAM: 38932 bytes ( 92140 available, 29.7% used) Used static IRAM: 38932 bytes ( 92140 remain, 29.7% used)
Flash code: 146944 bytes .text size: 37908 bytes
Flash rodata: 39580 bytes .vectors size: 1024 bytes
Total image size:~ 234780 bytes (.bin may be padded larger) Used stat D/IRAM: 56552 bytes ( 255256 remain, 18.1% used)
.data size: 9324 bytes
.bss size: 8296 bytes
.text size: 37908 bytes
.vectors size: 1024 bytes
Used Flash size : 186524 bytes
.text : 146944 bytes
.rodata : 39580 bytes
Total image size: 283036 bytes (.bin may be padded larger)

View File

@@ -16,7 +16,7 @@
from __future__ import print_function from __future__ import print_function
import sys import sys
import collections from typing import Dict
try: try:
import idf_size import idf_size
@@ -41,6 +41,6 @@ if __name__ == "__main__":
segments = {'iram0_0_seg': {'origin': 0, 'length': 0}, segments = {'iram0_0_seg': {'origin': 0, 'length': 0},
'dram0_0_seg': {'origin': 0, 'length': 0}} 'dram0_0_seg': {'origin': 0, 'length': 0}}
sections = {} sections = {} # type: Dict
print(idf_size.get_summary('a.map', segments, sections, 'esp32'), end='') print(idf_size.get_summary('a.map', segments, sections, 'esp32'), end='')