每个 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 格式。
以下是 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
都有以下属性,这些属性与之关联,且含义不言自明:NAME
、DESC
、TYPE
、DEFAULT
、RANGE
和 DRC
。VALUES
属性用于定义与 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
用于定义接口所支持的函数。
文件接口的 open
、close
、read
、write
和 lseek
函数的值分别为 mfs_file_open
、mfs_file_close
、mfs_file_read
、mfs_file_write
和 mfs_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
搭配 INTERFACE
和 LIBRARY
构造一起用于指示每个 INTERFACE
和 LIBRARY
构造的结束位置。
以下 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 文件示例:
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
都具有下列关联属性:NAME
、DESC
、TYPE
、DEFAULT
、RANGE
和 DRC
。VALUES
属性用于定义与 ENUM
类型相关联的可能值的列表。
END OS
END
搭配 BEGIN
语句中所使用的构造名称一起使用。此处 END
搭配操作系统用于指示操作系统构造的结束位置。
以下 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"}
}