ulp: esp32ulp_mapgen: remove the special case for RISC-V, cleanup

There are multiple changes in this commit:

1. Unify the RISC-V and ULP-FSM code paths in esp32ulp_mapgen.py.
   It seems that these were originally introduced because `nm` output
   for the RISC-V case contained symbol sizes, while for the ULP-FSM
   no symbol sizes were reported. This makes sense, because the
   ULP-FSM object files are produced from assembly source, symbol
   sizes have to be added manually using the .size directive.
   In the case of RISC-V, the object files are built from C sources
   and the sizes are automatically added by the compiler.

   Now 'posix' output format is used for both RISC-V and ULP-FSM.

2. Move BASE_ADDR out of esp32ulp_mapgen.py. This now has to be passed
   from CMake, which should make it easier to modify if a new chip
   with a different RTC RAM base address is added.

3. Add C++ guards to the generated header file.

4. Switch from optparse to argparse for similarity with other IDF
   tools.

5. Add type annotations.
This commit is contained in:
Ivan Grokhotkov
2022-08-28 14:11:46 +02:00
parent 4b03e233d0
commit 2916bf9b6c
4 changed files with 54 additions and 61 deletions

View File

@@ -2,77 +2,72 @@
# esp32ulp_mapgen utility converts a symbol list provided by nm into an export script
# for the linker and a header file.
#
# Copyright (c) 2016-2017 Espressif Systems (Shanghai) PTE LTD.
# Distributed under the terms of Apache License v2.0 found in the top-level LICENSE file.
# SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
from __future__ import print_function
from optparse import OptionParser
import argparse
import os
import textwrap
import typing
BASE_ADDR = 0x50000000
UTIL = os.path.basename(__file__)
def gen_ld_h_from_sym(f_sym, f_ld, f_h):
f_ld.write('/* Variable definitions for ESP32ULP linker\n')
f_ld.write(' * This file is generated automatically by esp32ulp_mapgen.py utility.\n')
f_ld.write(' */\n\n')
f_h.write('// Variable definitions for ESP32ULP\n')
f_h.write('// This file is generated automatically by esp32ulp_mapgen.py utility\n\n')
f_h.write('#pragma once\n\n')
def gen_ld_h_from_sym(f_sym: typing.TextIO, f_ld: typing.TextIO, f_h: typing.TextIO, base_addr: int) -> None:
f_ld.write(textwrap.dedent(
f"""
/* ULP variable definitions for the linker.
* This file is generated automatically by {UTIL} utility.
*/
"""
))
f_h.write(textwrap.dedent(
f"""
/* ULP variable definitions for the compiler.
* This file is generated automatically by {UTIL} utility.
*/
#pragma once
#ifdef __cplusplus
extern "C" {{
#endif
"""
))
for line in f_sym:
name, _, addr_str = line.split(' ', 2)
addr = int(addr_str, 16) + BASE_ADDR
# NM "posix" format output has the following structure:
# symbol_name symbol_type addr_hex [size_hex]
parts = line.split()
name = parts[0]
addr = int(parts[2], 16) + base_addr
f_h.write('extern uint32_t ulp_{0};\n'.format(name))
f_ld.write('PROVIDE ( ulp_{0} = 0x{1:08x} );\n'.format(name, addr))
def gen_ld_h_from_sym_riscv(f_sym, f_ld, f_h):
f_ld.write('/* Variable definitions for ESP32ULP linker\n')
f_ld.write(' * This file is generated automatically by esp32ulp_mapgen.py utility.\n')
f_ld.write(' */\n\n')
f_h.write('// Variable definitions for ESP32ULP\n')
f_h.write('// This file is generated automatically by esp32ulp_mapgen.py utility\n\n')
f_h.write('#pragma once\n\n')
for line in f_sym:
addr_str, _, name = line.split()
addr = int(addr_str, 16) + BASE_ADDR
f_h.write('extern uint32_t ulp_{0};\n'.format(name))
f_ld.write('PROVIDE ( ulp_{0} = 0x{1:08x} );\n'.format(name, addr))
f_h.write(textwrap.dedent(
"""
#ifdef __cplusplus
}
#endif
"""
))
def main():
def main() -> None:
description = ('This application generates .h and .ld files for symbols defined in input file. '
'The input symbols file can be generated using nm utility like this: '
'esp32-ulp-nm -g -f posix <elf_file> > <symbols_file>')
'<PREFIX>nm -g -f posix <elf_file> > <symbols_file>')
parser = OptionParser(description=description)
parser.add_option('-s', '--symfile', dest='symfile',
help='symbols file name', metavar='SYMFILE')
parser.add_option('-o', '--outputfile', dest='outputfile',
help='destination .h and .ld files name prefix', metavar='OUTFILE')
parser = argparse.ArgumentParser(description=description)
parser.add_argument('-s', '--symfile', required=True, help='symbols file name', metavar='SYMFILE', type=argparse.FileType('r'))
parser.add_argument('-o', '--outputfile', required=True, help='destination .h and .ld files name prefix', metavar='OUTFILE')
parser.add_argument('--base-addr', required=True, help='base address of the ULP memory, to be added to each symbol')
parser.add_option('--riscv', action='store_true', help='use format for ulp riscv .sym file')
args = parser.parse_args()
(options, args) = parser.parse_args()
if options.symfile is None:
parser.print_help()
return 1
if options.outputfile is None:
parser.print_help()
return 1
if options.riscv:
with open(options.outputfile + '.h', 'w') as f_h, open(options.outputfile + '.ld', 'w') as f_ld, open(options.symfile) as f_sym:
gen_ld_h_from_sym_riscv(f_sym, f_ld, f_h)
return 0
with open(options.outputfile + '.h', 'w') as f_h, open(options.outputfile + '.ld', 'w') as f_ld, open(options.symfile) as f_sym:
gen_ld_h_from_sym(f_sym, f_ld, f_h)
return 0
with open(args.outputfile + '.h', 'w') as f_h, open(args.outputfile + '.ld', 'w') as f_ld:
gen_ld_h_from_sym(args.symfile, f_ld, f_h, int(args.base_addr, 0))
if __name__ == '__main__':
exit(main())
main()