1 个稳定版本

1.0.0 2022年6月13日

#21 in #fpga


用于 libarc2

自定义许可协议

32KB
582

beastlink-rs

Rust 对 CESYS Beastlink 库的绑定。需要 Rust ≥ 1.40。

此库提供了用于与EFM03板进行接口的CESYS beastlink FPGA库的Rust绑定。

免责声明

请注意:此库链接到beastlink库的免费版本,这意味着它只能与EFM03板一起使用。如果您想使用相同FPGA芯片的自定义设计进行接口,您需要从CESYS获得明确的许可协议。beastlink-rs的作者不对此库的不当使用负责。

先决条件

要构建此库,您需要有适用于Windows (x86或x86_64) 或 Linux (仅x86_64) 的beastlink共享库。这些库可以在这些发行版的runtime文件夹中找到。如果您在Windows上构建,您还需要为编译器找到导出符号的存根lib文件。这些文件可以在Windows中的api/c++/lib下找到。所有这些都必须可以从编译器访问(因此它们必须在Windows上的%PATH%或Linux上的$LIBRARY_PATH中)。

连接到EFM03板

仅使用Beastlink无法将您连接到EFM03板。您还需要安装UDK USB驱动程序。这些驱动程序可以在driver文件夹中找到。在Windows上,安装udk3usb-drivers-windows应该足够。在Linux上,需要安装UDK库(libudk3libudk3mod-*-libusb)、固件(在data下)以及固件烧录工具cuudfdl,这些都可以在udk3-service-linux存档中找到。固件烧录工具必须放置在与data文件夹相同的目录下才能正常工作。如果您想在连接板时自动上传设备固件,还需要一些udev规则来执行此操作。例如...

ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="10f8", ATTRS{idProduct}=="c4??", MODE="660", GROUP="plugdev", RUN+="/bin/bash /path/to/cuudfdl.sh"
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="10f8", ATTRS{idProduct}=="c5??", MODE="660", GROUP="plugdev", RUN+="/bin/bash /path/to/cuudfdl.sh"

cuudfdl.sh是一个包装脚本,它使用适当的参数运行cuudfdl可执行文件,必须放置在与主要cuudfdl可执行文件和包含固件的data文件夹相同的目录中,如上所述。内容很简单

#!/bin/bash
cd /path/to/data_and_cuudfld && ./cuudfdl $@

如果您使用archlinux,可以在该仓库的contrib/archlinux文件夹下找到PKGBUILD。如果您使用基于debian的发行版,可以使用提供的脚本来为您的发行版构建软件包,这些脚本位于contrib/debian。对于与RedHat兼容的发行版,在contrib/redhat下也有spec文件。

示例

您可以检查此库简单用例的测试。通常,beastlink只为与EFM03接口提供少量操作,即从/到块内存的读写、从/到寄存器的读写、在板上加载位流以及一些固件信息。

设备枚举

use beastlink;

const VID: u16 = 0x10f8;
const PID: u16 = 0xc583;

fn main() {
        match beastlink::enumerate(VID, PID) {
            Ok(count) => {
                println!("Enumeration result: {}", count);
            },
            Err(err) => {
                panic!("Enumeration failed with {}", err)
            }
        }
}

打开设备

use beastlink;

const VID: u16 = 0x10f8;
const PID: u16 = 0xc583;

fn main() {
    let count = match beastlink::enumerate(VID, PID) {
        Ok(count) => {
            println!("Enumerated {} devices", count);
            count
        },
        Err(err) => {
            panic!("Enumeration failed with {}", err)
        }
    };

    // Try to open a device
    for enum_id in 0..count {
        println!("Trying device {}", enum_id);
        let dev = match beastlink::Device::open(enum_id) {
            Ok(dev) => dev,
            Err(err) => {
                panic!("Error while opening device: {}", err)
            }
        };

        println!("Opened device {:?}", dev);

        match dev.close() {
            Err(err) => {
                panic!("Error while closing device {:?}: {}", dev, err)
            },
            _ => {}
        }
    }

}

依赖关系

~1.5MB
~39K SLoC