Tcl 文件格式规范 - 2023.2 简体中文

Vitis 统一软件平台文档 嵌入式软件开发 (UG1400)

Document ID
UG1400
Release Date
2023-12-13
Version
2023.2 简体中文

每个 OS 和库都有一个与 MLD 文件关联的 Tcl 文件。此 Tcl 文件包含以下几个部分:

DRC
此 DRC 部分包含 Tcl 例程,用于确认操作系统和库参数,以确保一致性。
Generation
此“生成”部分包含 Tcl 例程,用于根据库参数生成配置头文件和 C 语言文件。

MLD 设计规则检查部分

proc mydrc { handle } { }

DRC 函数可以采用任意 Tcl 代码,用于检查参数是否正确。DRC 过程可以访问(只读)平台规范格式 (Platform Specification Format) 数据库,以读取您设置的参数值,此数据库是由该工具使用硬件 (XSA) 和软件 (MSS) 数据库文件构建的。句柄与数据库中的当前库相关联。DRC 过程可通过此句柄获取操作系统和库参数。它还可以通过首先请求句柄,然后使用句柄来获取参数的方式,从该数据库中获取任何其他参数。

如果出现错误,DRC 过程会调用 Tcl 错误命令“error msg”错误,并显示在错误页面中。

如果出现警告,DRC 过程会返回字符串值并打印在控制台上。

如果操作成功,那么 DRC 过程返回内容不含任何值。

MLD 格式示例

本节通过一个 MLD 文件示例及其对应的 Tcl 文件来详解 MLD 格式。

示例:适用于库的 MLD 文件

以下是 xilmfs 库的 MLD 文件示例。

option psf_version = 2.1.0 ;

option 是该工具识别的关键字。option 关键字后的选项名称是发送给工具的一条指令,以指示工具执行特定操作。

在此示例中,MLD 文件的 psf_version 定义为 2.1。当前,这是唯一可在 BEGIN LIBRARY 构造之前发生的选项。

BEGIN LIBRARY xilmfs

BEGIN LIBRARY 构造用于定义名为 xilmfs 的库的起始位置。

option DESC = "Xilinx Memory File System" ;
option drc = mfs_drc ;
option copyfiles = all;
option REQUIRES_OS = (standalone xilkernel freertos_zynq);
option VERSION = 2.0;
option NAME = xilmfs;

NAME 选项用于指示驱动程序的名称。VERSION 选项用于指示驱动程序的版本。

COPYFILES 选项用于指示要为该库复制的文件。DRC 选项用于指定 Tcl 过程的名称,工具会在处理此库期间调用该过程。mfs_drc 是 Tcl 过程,在 xilmfs.tcl 文件中,处理 xilmfs 库时将调用该过程。

PARAM name = numbytes, desc = "Number of Bytes", type = int, default =
100000, drc = drc_numbytes ;
PARAM name = base_address, desc = "Base Address", type = int, default =
0x10000, drc = drc_base_address ;
PARAM name = init_type, desc = "Init Type", type = enum, values = ("New
file system"=MFSINIT_NEW,
"MFS Image"=MFSINIT_IMAGE, "ROM Image"=MFSINIT_ROM_IMAGE), default =
MFSINIT_NEW ;
PARAM name = need_utils, desc = "Need additional Utilities?", type =
bool, default = false ;

PARAM 用于定义可配置的库参数。每个 PARAM 都有以下属性,这些属性与之关联,且含义不言自明:NAMEDESCTYPEDEFAULTRANGEDRCVALUES 属性用于定义与 ENUM 类型相关联的可能值的列表。

BEGIN INTERFACE file
PROPERTY HEADER="xilmfs.h" ;
FUNCTION NAME=open, VALUE=mfs_file_open ;
FUNCTION NAME=close, VALUE=mfs_file_close ;
FUNCTION NAME=read, VALUE=mfs_file_read ;
FUNCTION NAME=write, VALUE=mfs_file_write ;
FUNCTION NAME=lseek, VALUE=mfs_file_lseek ;
END INTERFACE

每个接口都包含一份标准函数列表。定义接口的库应包含标准函数列表的对应值。它还必须指定头文件以供在其中定义所有函数原型。

PROPERTY 用于定义与 BEGIN 构造中定义的构造相关联的属性。此处,HEADER 属性的值为 xilmfs.h,由文件接口定义。FUNCTION 用于定义接口所支持的函数。

文件接口的 openclosereadwritelseek 函数的值分别为 mfs_file_openmfs_file_closemfs_file_readmfs_file_writemfs_file_lseek。这些函数在头文件 xilmfs.h 中进行定义。

BEGIN INTERFACE filesystem

BEGIN INTERFACE 用于定义此库支持的接口。此处,file 是接口名称。

PROPERTY HEADER="xilmfs.h" ;
FUNCTION NAME=cd, VALUE=mfs_change_dir ;
FUNCTION NAME=opendir, VALUE=mfs_dir_open ;
FUNCTION NAME=closedir, VALUE=mfs_dir_close ;
FUNCTION NAME=readdir, VALUE=mfs_dir_read ;
FUNCTION NAME=deletedir, VALUE=mfs_delete_dir ;
FUNCTION NAME=pwd, VALUE=mfs_get_current_dir_name ;
FUNCTION NAME=rename, VALUE=mfs_rename_file ;
FUNCTION NAME=exists, VALUE=mfs_exists_file ;
FUNCTION NAME=delete, VALUE=mfs_delete_file ;
END INTERFACE
END LIBRARY

END 搭配 BEGIN 语句中所使用的构造名称一起使用。此处,END 搭配 INTERFACELIBRARY 构造一起用于指示每个 INTERFACELIBRARY 构造的结束位置。

示例:适用于库的 Tcl 文件

以下 xilmfs.tcl 文件对应于上一节中所描述的 xilmfs.mld 文件。为各库运行 DRC 期间,xilmfs 库将调用 mfs_drc 过程。generate 例程会根据 MSS 文件中的库定义段,在头文件和 c 语言文件中为 xilmfs 库生成常量。

proc mfs_drc {lib_handle} {
puts "MFS DRC ..."
}
proc mfs_open_include_file {file_name} {
set filename [file join "../../include/" $file_name]
if {[file exists $filename]} {
set config_inc [open $filename a]
} else {
set config_inc [open $filename a]
::hsi::utils::write_c_header $config_inc "MFS Parameters"
}
return $config_inc
}
proc generate {lib_handle} {
puts "MFS generate ..."
file copy "src/xilmfs.h" "../../include/xilmfs.h"
set conffile [mfs_open_include_file "mfs_config.h"]
puts $conffile "#ifndef _MFS_CONFIG_H"
puts $conffile "#define _MFS_CONFIG_H"
set need_utils [common::get_property CONFIG.need_utils $lib_handle]
if {$need_utils} {
# tell libgen or xps that the hardware platform needs to provide
stdio functions
# inbyte and outbyte to support utils
puts $conffile "#include <stdio.h>"
}
puts $conffile "#include <xilmfs.h>"
set value [common::get_property CONFIG.numbytes $lib_handle]
puts $conffile "#define MFS_NUMBYTES $value"
set value [common::get_property CONFIG.base_address $lib_handle]
puts $conffile "#define MFS_BASE_ADDRESS $value"
set value [common::get_property CONFIG.init_type $lib_handle]
puts $conffile "#define MFS_INIT_TYPE $value"
puts $conffile "#endif"
close $conffile
}
示例:适用于操作系统的 MLD 文件

以下提供了适用于独立操作系统的 MLD 文件示例:

option psf_version = 2.1.0 ;

option 是该工具识别的关键字。option 关键字后的选项名称是发送给工具的一条指令,以指示工具执行特定操作。此处 MLD 文件的 psf_version 定义为 2.1。当前,这是唯一可在 BEGIN 操作系统构造之前发生的选项。

BEGIN OS standalone

BEGIN 操作系统构造用于定义名为 standalone 的操作系统的开始位置。

option DESC = "Generate standalone BSP";
option COPYFILES = all;

DESC 选项则用于提供 MLD 的描述。COPYFILES 选项用于指示要为操作系统复制的文件。

PARAM NAME = stdin, DESC = "stdin peripheral ", TYPE =
peripheral_instance, REQUIRES_INTERFACE = stdin, DEFAULT = none; PARAM
NAME = stdout, DESC = "stdout peripheral ", TYPE = peripheral_instance,
REQUIRES_INTERFACE = stdout, DEFAULT = none ; PARAM NAME = need_xilmalloc,
DESC = "Need xil_malloc?", TYPE = bool, DEFAULT = false ;

PARAM 用于定义可配置的操作系统参数。每个 PARAM 都具有下列关联属性:NAMEDESCTYPEDEFAULTRANGEDRCVALUES 属性用于定义与 ENUM 类型相关联的可能值的列表。

END OS

END 搭配 BEGIN 语句中所使用的构造名称一起使用。此处 END 搭配操作系统用于指示操作系统构造的结束位置。

示例:适用于操作系统的 Tcl 文件

以下 standalone.tcl 文件对应于上一节中所描述的 standalone.mld 文件。generate 例程会根据 MSS 文件中的库定义段,在头文件和 c 语言文件中为 xilmfs 库生成常量。

proc generate {os_handle} {
	global env
	set need_config_file "false"
	# Copy over the right set of files as src based on processor type
	set sw_proc_handle [get_sw_processor]
	set hw_proc_handle [get_cells [get_property HW_INSTANCE
$sw_proc_handle] ]
	set proctype [get_property IP_NAME $hw_proc_handle]
	set procname [get_property NAME $hw_proc_handle]
	set enable_sw_profile [get_property
CONFIG.enable_sw_intrusive_profiling $os_handle]
	set mb_exceptions false
	switch $proctype {
		"microblaze" {
		foreach entry [glob -nocomplain [file join $mbsrcdir *]] {
# Copy over only files that are not related to exception
handling.
# All such files have exception in their names.
file copy -force $entry "./src/"
}
	set need_config_file "true"
	set mb_exceptions [mb_has_exceptions $hw_proc_handle]
}
	"ps7_cortexa9" {
	set procdrv [get_sw_processor]
	set compiler [get_property CONFIG.compiler $procdrv]
	if {[string compare -nocase $compiler "armcc"] == 0} {
	set ccdir "./src/cortexa9/armcc"
	} else {
	set ccdir "./src/cortexa9/gcc"
	}
	foreach entry [glob -nocomplain [file join
	$cortexa9srcdir *]] {
	file copy -force $entry "./src/"
	}
	foreach entry [glob -nocomplain [file join $ccdir *]] {
	file copy -force $entry "./src/"
	}
	file delete -force "./src/armcc"
	file delete -force "./src/gcc"
	if {[string compare -nocase $compiler "armcc"] == 0} {
	file delete -force "./src/profile"
	set enable_sw_profile "false"
	}
	set file_handle [xopen_include_file "xparameters.h"]
	puts $file_handle "#include \"xparameters_ps.h\""
	puts $file_handle ""
	close $file_handle
	}
	"default" {puts "unknown processor type $proctype\n"}
}