1 个不稳定版本

0.1.0 2023年10月23日

#1417硬件支持

MIT 许可证

65KB
1.5K SLoC

ni-fpga-interface

为 Rust 编写的 NI FPGA 接口

这个crate旨在轻松与 LabVIEW FPGA 通信。

要求

  • C接口需要导出,"prefix" 设置为不带空格的名称,我们期望有一个包含 NiFpga C 和 H 文件的单个目录。

入门

  1. 使用可从 https://www.ni.com/en/support/downloads/drivers/download.fpga-interface-c-api.html#477242 下载的生成器生成 FPGA C 接口
  2. ni-fpga-interface-build crate 作为构建依赖项添加,并将 ni-fpga-interface 作为常规依赖项添加。
  3. 为您的项目创建一个构建脚本,并将构建器添加到脚本中。例如
        fn main() {
        let mut fpga_c_interface = ni_fpga_interface_build::FpgaCInterface::from_custom_header(
            "../fpga_c_interface/NiFpga_Main.h",
        );
        fpga_c_interface.build();
    }
    
  4. 将生成的 rust 模块包含在您的应用程序的模块中。
    mod fpga_defs {
        include!(concat!(env!("OUT_DIR"), "/NiFpga_Main.rs"));
    }
    
  5. 使用 ni-fpga-interface API 访问 FPGA。

示例

查看示例文件夹,其中包含一些包括构建支持的完整示例。

支持的功能

以下是支持的功能和计划支持的功能。

原生类型是标准整数类型以及单精度和双精度浮点数。

功能 支持
原生类型的寄存器
FXP数字的寄存器 计划中
集群的寄存器 待定
原生类型的DMA
DMA FIFO控制
中断请求
会话控制
多线程
多FPGA支持的图案 计划中
多FPGA支持的动力接口 计划中

架构

这种方法的原理是尽可能多地使用生成的C代码,而不是预先构建预期的接口。

这应该使我们尽可能与版本无关,并减少NI在生成的C代码中已经解决的问题的复杂性。

这可能需要时间,但它通过3层抽象构建

  1. 由NI生成的C调用。
  2. Rust中对C调用的安全包装。
  3. 为提供的特定FPGA位文件/接口生成的Rust接口。
flowchart 
subgraph LabVIEW
C[FPGA C Interface]
LV[LabVIEW FPGA] --generates--> C
end
subgraph Build Support
C --bindgen--> Types[FPGA Definitions]
C --cc--> Obj[Compiled NI FPGA Interface]
end
Obj --links--> Wrapper[Safe Generic Wrapper]
Types --mod import--> Direct[Your Code with Direct interface]
Wrapper --mod import--> Direct
Types --generator--> Specific[FPGA Interface Module]
Wrapper --generator--> Specific
Specific --> App[Your Code Using Custom Interface]

该图显示了关键组件和目标工作流程。名称可能会更改。

该项目有3个关键组件

  1. 构建支持,使将FPGA生成的C接口构建到您的Rust项目中变得容易。
  2. 安全包装器,让您无需直接调用不安全的函数。
  3. FPGA接口生成器,将在Rust中生成一个结构体,提供对特定FPGA接口的简单访问。

自定义类型支持

我们需要支持固定点和集群,它们作为C中的自定义类型传入。

这需要生成一些代码,作为构建支持的组成部分,以便为这些类型提供安全包装器。

交叉编译

交叉编译应作为首要考虑,以确保它易于与compactRIO目标一起使用。

我已经测试了针对x64和armv7 LinuxRT目标的示例构建。

计划方法

  1. 解决构建支持问题。
  2. 让安全包装器为标准类型工作。
  3. 让安全包装器为自定义类型工作。
  4. 解决单个位文件的API生成问题。
  5. 看看是否有合理的途径来抽象多个位文件之间的接口(类似于LabVIEW中的动态接口)。

我打算先将其作为一个单独的crate开始,但后来分拆它可能是有意义的。

依赖项

~2.5MB
~49K SLoC