Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions datasheets/near_point/block_seperation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"reg": [
{
"bits": 10,
"name": "inter-block offset",
"type": 6
},
{
"bits": 22,
"name": "block index",
"type": 5
}
],
"config": {
"fontsize": 14,
"bits": 32,
"hflip": true,
"lanes": 1,
"compact": true
}
}
21 changes: 21 additions & 0 deletions datasheets/near_point/linear_near_point_entry.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"reg": [
{
"bits": 24,
"name": "entry number offset",
"type": 5
},
{
"bits": 8,
"name": "average function size",
"type": 6
}
],
"config": {
"fontsize": 14,
"bits": 32,
"hflip": true,
"lanes": 1,
"compact": true
}
}
39 changes: 39 additions & 0 deletions scripts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Scripts

The scripts for testing and playing around with libhal exceptions.

## Near Point Script?

```plaintext
usage: nearpoint.py [-h] [-b BLOCK_POWER] [-s SMALL_BLOCK_POWER] [-n] file

positional arguments:
file text file with a list of function addresses in your code starting from 0 to N where N is the last function
address, or output from the command: nm app.elf --size-sort --radix=d | grep " [Tt] " | awk '{print $1}'

options:
-h, --help show this help message and exit
-b BLOCK_POWER, --block_power BLOCK_POWER
Set the block size based on a power of 2.
-s SMALL_BLOCK_POWER, --small_block_power SMALL_BLOCK_POWER
Set the small block size based on a power of 2.
-n, --nm The input file is actually output from an NM command: nm app.elf --size-sort --radix=d | grep " [Tt] " | awk
'{print $1}'
```

The script works with output from nm following this:

```bash
python3 nearpoint.py --tool-prefix="/path/to/arm-none-eabi/bin/" --map="app.elf.map" app.elf
```

After

What this will do is create a size sorted list of each function in the program
and output its starting address. This easy to execute script enable 3rd parties
to send us this information in a mostly erased fashion to compare against our
application. Even if the application does not use exceptions.

```bash
python3 scripts/nearpoint.py demos/multi_levels.elf.nm -n -b 10
```
152 changes: 152 additions & 0 deletions scripts/archived/gen_sorted_linkscript.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#!/usr/bin/env python3
import subprocess
import re
import argparse
import csv
from typing import NamedTuple, List


class Function(NamedTuple):
name: str
size: int
orig_addr: int
new_addr: int
index: int


def get_sorted_functions(binary_path: str) -> List[Function]:
"""Get size-sorted functions using nm and calculate new addresses."""
try:
cmd = ['nm', '--size-sort', '--print-size', binary_path]
nm_output = subprocess.check_output(
cmd, universal_newlines=True, stderr=subprocess.PIPE)

# First pass to get functions and find lowest address
temp_functions = []
lowest_addr = float('inf')
for line in nm_output.splitlines():
if ' t ' in line or ' T ' in line:
parts = line.strip().split()
if len(parts) >= 4:
addr = int(parts[0], 16)
size = int(parts[1], 16)
name = parts[3]
lowest_addr = min(lowest_addr, addr)
temp_functions.append((name, size, addr))

# Sort by size in descending order
temp_functions.sort(key=lambda x: x[1], reverse=True)

# Calculate new sequential addresses
current_addr = lowest_addr
functions = []
for idx, (name, size, orig_addr) in enumerate(temp_functions):
functions.append(
Function(name, size, orig_addr, current_addr, idx))
# Align next address to 4-byte boundary
current_addr = (current_addr + size + 3) & ~3

return functions

except subprocess.CalledProcessError as e:
print(f"Error running nm: {e}")
print(f"stderr: {e.stderr}")
return []


def generate_linker_section(functions: List[Function]) -> str:
"""Generate linker script section with sorted functions."""
script = []
script.append("SECTIONS")
script.append("{")
script.append(" .text :")
script.append(" {")

# Add functions in size order
for func in functions:
script.append(f" KEEP(*(.text.{func.name}))")

# Add any remaining text sections
script.append(" *(.text*)")
script.append(" *(.rodata*)")
script.append(" } > FLASH")
script.append("}")

return "\n".join(script)


def write_csv(functions: List[Function], filepath: str):
"""Write function information to CSV file."""
with open(filepath, 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['Index Entry', 'Function Name', 'Address'])
for func in functions:
writer.writerow([func.index, func.name, hex(func.new_addr)])


def format_size(size: int) -> str:
"""Format size in bytes to human-readable format."""
if size < 1024:
return f"{size:>8} B"
elif size < 1024 * 1024:
return f"{size/1024:>7.1f} KB"
else:
return f"{size/1024/1024:>7.1f} MB"


def main():
parser = argparse.ArgumentParser(
description='Generate size-sorted linker script section and CSV from ELF file'
)
parser.add_argument('binary', help='Path to the ELF binary')
parser.add_argument('-o', '--output', help='Output linker script file')
parser.add_argument('-c', '--csv', help='Output CSV file')
parser.add_argument('--summary', action='store_true',
help='Show size summary of functions')
args = parser.parse_args()

# Get sorted functions
functions = get_sorted_functions(args.binary)

if not functions:
print("No functions found in binary")
return

# Generate linker script
linker_script = generate_linker_section(functions)

# Output handling for linker script
if args.output:
with open(args.output, 'w') as f:
f.write(linker_script)
print(f"Linker script written to: {args.output}")
else:
print("\nLinker Script Section:")
print("=" * 80)
print(linker_script)
print("=" * 80)

# Output CSV if requested
if args.csv:
write_csv(functions, args.csv)
print(f"CSV file written to: {args.csv}")

# Print summary if requested
if args.summary:
total_size = sum(f.size for f in functions)
print("\nFunction Size Summary:")
print("-" * 90)
print(f"{'Index':>5} {'Size':>10} {'New Addr':>12} {'Function Name':<50}")
print("-" * 90)

for func in functions:
print(
f"{func.index:>5} {format_size(func.size)} {func.new_addr:>#12x} {func.name:<50}")

print("-" * 90)
print(f"Total Functions: {len(functions)}")
print(f"Total Size: {format_size(total_size)}")


if __name__ == '__main__':
main()
Loading
Loading