sw_app 目录中的程序由 Vitis/XSCT 工具进行构建和管理,包含适用于 Xilinx SoC 平台的裸核和 RTOS 示例。

通用目录结构如下

1
2
3
4
5
6
7
8
9
10
11
<app_name>/
data/
<app_name>.tcl # HSI/Vitis metadata: supported processors, OS, hw requirements
<app_name>.yaml # Machine-readable metadata: dependencies, supported targets
<app_name>.mss # (some apps) Software stack description
src/
CMakeLists.txt # Build definition (CMake-based, driven by XSCT)
*.c / *.h / *.S # Source code
lscript.ld # Linker script (most apps)
UserConfig.cmake # User build customization hooks
platform_config.h.in # (some apps) Template for platform-specific config

Memory Tests

这一部分程序的作用是测试硬件设计中所有可读写内存区域。

1
2
3
4
5
6
7
8
9
10
11
12
.
├── data
│   ├── memory_tests.tcl
│   └── memory_tests.yaml # 本程序运行的最低内存要求: OCM >= 64KB 或 BRAM >= 8KB
└── src
├── CMakeLists.txt
├── memory_config.h
├── memory_config_g.c.in
├── memorytest.c
├── platform.c
├── platform.h
└── platform_config.h
  • memory_config.h 程序中定义了结构体,与 lscripts.ld 中的 Available Memory Regions 表头对应。
1
2
3
4
5
6
struct memory_range_s {
char8 *name; // 内存区域的名称
char8 *ip; // 内存控制 IP 名称
UINTPTR base; // 基地址
u64 size; // 区域大小(字节)
};
  • memory_config_g.c 文件根据模板文件 memory_config_g.c.in 构建,具体作用是替换占位符 @MEMNODES@ 为具体可读写的内存区域,作为数组 memory_ranges 的逐个元素;替换占位符 @NUM_MEM_RANGES@ 为内存区域的数量。

  • platform.c 程序中包含平台初始化与清理函数,初始化时仅启用 I-Cache,针对 ARM 处理器会禁用 D-Cache 数据缓存,因为内存测试必须让数据写到外部存储器。

  • memorytest.c 程序中包含 main() 函数和测试逻辑:遍历所有 n_memory_ranges 逐个调用测试函数 test_memory_range

    1. 打印本次测试的内存区域名称、控制器 IP 名、基地址和区域大小

    2. 将内存按照 \(4KB\) 分块,Xil_TestMem32 逐块做 32 位读写测试(可选:16 位或 8 位压力测试)

注:测试程序中使用 print 打印,而不是 printf,因为 printf 会在堆上动态分配内存,而此时 heap = 0.


  • memory_tests.tcl 脚本
函数 作用
swapp_get_name 返回应用名称 Memory Tests
swapp_get_description 返回描述信息
swapp_is_supported_hw 检查硬件兼容性:必须有 UART 外设,必须有足够大的 BRAM/OCM
swapp_is_supported_sw 检查软件兼容性:必须是 standalone OS,必须设置 stdout
swapp_generate 生成 platform_config.h(UART 配置)和 memory_config_g.c(内存范围表)
swapp_get_linker_constraints 返回链接约束:代码/数据存放位置,堆大小为 0
swapp_get_supported_processors 返回支持的处理器列表
swapp_get_supported_os 返回 standalone

另外,generate_memory_config 函数的作用包括

  • 遍历所有数据内存范围,排除以下区域:
    • 只读内存
    • 与安全状态不匹配的内存
    • 程序代码/数据所在的内存(避免测试时覆盖自身)
    • Flash 存储器(通过 EMC IP 类型检测)
    • DDR 控制器本身(ps7_ddrc)、QSPI、NAND、NOR 等非易失性存储
    • TCM(紧耦合内存)、OCM、PMU RAM 等片上特殊内存
    • AArch32 模式下地址超过 32 位的区域
  • MicroBlaze 特殊处理:基地址为 0 的内存跳过前 0x50 字节(向量表区域)。

最终生成合法的内存范围数组。,

Xil_TestMem32 测试

函数根据 Subtest 参数最多可以执行 5 种测试,分别为

  • 向内存连续写入累加数然后从头读取,检查读出的值与预期递增的值是否一致,用于检测基本的读写功能;
  • 写入的数据只有 1 个 bit 是 1, 其余是 0,例如 0x0000_0001, 0x0000_0002,...,一直左移循环 32 次,用于检测数据线之间是否存在邻位干扰、短路或断路;
  • 写入的数据只有 1 个 bit 是 0, 其余是 1,同样用于检测数据线,确保高低电平转换没有故障;
  • 将当前内存的地址取反后的值写入该地址,读取时,再次计算地址的取反值进行对比,用于检测地址线与地址译码逻辑;
  • 将整个内存块填满 0xDEADBEEF,然后回读校验,快速完成大面积的完整性校验,用于验证内存控制器配置;

参考资料

GitHub | Xilinx/embeddedsw

DeepWiki | Xilinx/embeddedsw