ZHDA191 June   2026 TDA4VE-Q1

 

  1.   1
  2.   摘要
  3.   商标
  4. 1简介
  5. 2运行时代码覆盖后台
    1. 2.1 TDA4x 的存储器架构
    2. 2.2 静态代码分配的挑战
    3. 2.3 为什么选择运行时代码覆盖?
  6. 3运行时代码覆盖方法
    1. 3.1 概述
    2. 3.2 驻留运行时
    3. 3.3 覆盖有效载荷包
    4. 3.4 共享 SRAM 覆盖区域
    5. 3.5 运行时覆盖序列
  7. 4运行时代码覆盖架构
    1. 4.1 软件架构
    2. 4.2 覆盖包格式
    3. 4.3 存储器布局
    4. 4.4 运行时映像加载
    5. 4.5 运行时执行
  8. 5演示实现
    1. 5.1 软件组织
    2. 5.2 覆盖 SRAM 配置
    3. 5.3 有效载荷生成
    4. 5.4 有效载荷加载和执行
    5. 5.5 构建配置
  9. 6运行时代码覆盖验证
    1. 6.1 PayloadA 执行
    2. 6.2 PayloadB 执行
    3. 6.3 PayloadC 执行
    4. 6.4 共享 SRAM 覆盖槽重用
    5. 6.5 完整运行时验证
  10. 7总结
  11. 8参考资料

有效载荷生成

可执行有效载荷作为独立的覆盖包生成。

下面是一个示例“package_overlay.py”脚本,用于从“bin”文件生成覆盖包。

#!/usr/bin/env python3
import struct
import sys
from pathlib import Path

# Must match BootApp_OverlayPkgHeader / boot_app side checks
BOOTAPP_OVERLAY_MAGIC = 0x4F56524C  # 'OVRL'

# Header layout (32 bytes)
#   uint32_t magic;
#   uint32_t totalSize;
#   uint32_t codeSize;
#   uint32_t entryOffset;
#   uint32_t flags;
#   uint32_t reserved[3];
HEADER_FMT = "<8I"
HEADER_SIZE = struct.calcsize(HEADER_FMT)

def make_pkg(bin_path: Path,
             out_path: Path,
             entry_offset: int = 0,
             flags: int = 0,
             prepad: int = 0) -> None:
    code = bin_path.read_bytes()

    if len(code) == 0:
        raise ValueError(f"Empty binary: {bin_path}")
    if entry_offset < 0:
        raise ValueError(f"entry_offset must be >= 0: {entry_offset}")
    if prepad < 0:
        raise ValueError(f"prepad must be >= 0: {prepad}")

    # For XIP packages, TI objcopy emits the binary without preserving the
    # absolute load address. If the linker aligns .text from header_end
    # 0x...20 to 0x...40, the raw binary still starts at file offset 0.
    # Add explicit padding after the OVRL header so the first binary byte is
    # physically placed at the same address used by the linker.
    payload = (b"\x00" * prepad) + code
    code_size = len(payload)
    total_size = HEADER_SIZE + code_size

    header = struct.pack(
        HEADER_FMT,
        BOOTAPP_OVERLAY_MAGIC,  # magic
        total_size,             # totalSize
        code_size,              # codeSize, including any XIP prepad
        entry_offset,           # entryOffset from first byte after header
        flags,                  # flags
        0, 0, 0                 # reserved[3]
    )

    out_path.write_bytes(header + payload)

    print(f"Created {out_path}")
    print(f"  totalSize   : {total_size}")
    print(f"  codeSize    : {code_size}")
    print(f"  entryOffset : {entry_offset}")
    print(f"  flags       : {flags}")
    print(f"  prepad      : {prepad}")

def main() -> int:
    if len(sys.argv) not in (3, 4, 5, 6):
        print("Usage: package_overlay.py <input.bin> <output.pkg> [entry_offset] [flags] [prepad]")
        return 1

    in_path = Path(sys.argv[1])
    out_path = Path(sys.argv[2])

    entry_offset = int(sys.argv[3], 0) if len(sys.argv) >= 4 else 0
    flags = int(sys.argv[4], 0) if len(sys.argv) >= 5 else 0
    prepad = int(sys.argv[5], 0) if len(sys.argv) >= 6 else 0

    make_pkg(in_path, out_path, entry_offset, flags, prepad)
    return 0

if __name__ == "__main__":
    raise SystemExit(main())

下面是一个示例 shell 脚本“build_payloads.sh”,用于生成有效载荷 payloadA.pkg、payloadB.pkg 和 payloadC.pkg。

#!/usr/bin/env bash
set -e

SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
OUT_DIR=${OUT_DIR:-$SCRIPT_DIR/out}
TIARMCLANG=${TIARMCLANG:-tiarmclang}
TIARMLNK=${TIARMLNK:-tiarmlnk}
TIARMOBJCOPY=${TIARMOBJCOPY:-tiarmobjcopy}
SLOT_ADDR=${SLOT_ADDR:-0x41C70000}

mkdir -p "$OUT_DIR"

prepare_linker_cmd() {
    local addr=$1
    local out_cmd=$2
    sed "s/0x41C70000/${addr}/g" "$SCRIPT_DIR/emmc_overlay_payload.cmd" > "$out_cmd"
}

build_one() {
    local tag=$1
    local src=$2
    local obj="$OUT_DIR/${tag}.o"
    local elf="$OUT_DIR/${tag}.elf"
    local bin="$OUT_DIR/${tag}.bin"
    local pkg="$OUT_DIR/payload${tag^^}.pkg"
    local lnk="$OUT_DIR/${tag}.cmd"

    echo "[build] ${tag^^}: slot=${SLOT_ADDR} src=${src}"
    prepare_linker_cmd "$SLOT_ADDR" "$lnk"

    $TIARMCLANG -mcpu=cortex-r5 -mthumb -Oz -ffreestanding -fno-builtin -nostdlib \
        -c -I"$SCRIPT_DIR/../include" "$SCRIPT_DIR/$src" -o "$obj"
    $TIARMLNK -o "$elf" "$obj" -c "$lnk" --cinit_compression=off
    $TIARMOBJCOPY -O binary "$elf" "$bin"
    python3 "$SCRIPT_DIR/package_overlay.py" "$bin" "$pkg" 0x0 0x0 0x0
}

build_one a emmc_overlay_payload_a.c
build_one b emmc_overlay_payload_b.c
build_one c emmc_overlay_payload_c.c

cat <<MSG

Done. Copy these files to the FAT partition root used by boot_app:
  $OUT_DIR/payloadA.pkg -> 0:/payloadA.pkg
  $OUT_DIR/payloadB.pkg -> 0:/payloadB.pkg
  $OUT_DIR/payloadC.pkg -> 0:/payloadC.pkg
MSG

每个包均包含

• 覆盖包标头

• 可执行代码段

• 运行时入口点信息

使用以下命令可生成有效载荷包

SLOT_ADDR=0x41C70000 ./build_payloads.sh

生成的包文件随后被复制到 eMMC FATFS 分区。

 覆盖有效载荷包生成流程图 5-1 覆盖有效载荷包生成流程.

 覆盖包格式图 5-2 覆盖包格式.