libdfx - Linux User Space Solution for FPGA Programming

 

Introduction

The library is a lightweight user-space library built on top of the Linux driver stack to support the FPGA device programming. This 'C' library can be built statically and needs to be integrated with user application. It provides different APIs that can address multiple use cases for DFX or PL configuration data programming. It also provides faster programming capability by avoiding multiple buffer copies that are involved in other methods.

Source Code

https://github.com/Xilinx/libdfx.git

 

Kernel Configuration

The following config options have to be enabled in order to use libdfx library, Please note that these options are enabled by default through xilinx_defconfig.

CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_HEAPS_SYSTEM=y CONFIG_DMABUF_HEAPS_CMA=y

API Details

 Pre-fetch

  • dfx_cfg_init (const char *dfx_package_path, const char *devpathu32 flags);

/* Provide a generic interface to the user to specify the required parameters for PR programming.  * The calling process must call this API before it performs -load/remove.  *  * char *dfx_package_path: The contents of the package folder should look something as below:  *                                -package: //-package1   *                                                                |--> Bit_file  *                                                                |--> DT_Overlayfile  *  *  char *devpath: Unused for now. The dev interface for now is always exposed at /dev/fpga0  *  * unsigned long flags: Flags to specify any special instructions for library to perform.  *                      Unused for now.  *  * Return: returns unique package_Id or Error code on failure.  */     Usage example: #include "libdfx.h"    package_id1, package_id2;   /* More code */ /* -store /Pre-fetch data */ package_id1 = dfx_cfg_init ("/path/package1/", "/dev/fpga0", flags);   /* More code */   /* -store /Pre-fetch data */ package_id2 = dfx_cfg_init ("/path/package2/", "/dev/fpga0", flags);   /* More code */



fpga-load

  • int dfx_cfg_load ( struct dfx_package_Id *package_Id)

/* This API is Responsible for the following things.  *      -->Load  into the PL  *      -->Probe the Drivers which are relevant to the Bitstream as per DT overlay mentioned in dfx_package folder)  *  *  package_id: Unique package_id value which was returned by dfx_cfg_init.  *  * Return: returns zero on success or Error code on failure.  */     Usage example: #include "libfpga.h"   /* More code */   ret = dfx_cfg_load (package_id); if (ret)     return -1   /* More code */



Deferred-drivers-load

  • int dfx_cfg_drivers_load(struct dfx_package_Id *package_Id)

Remove

  • dfx_cfg_remove (package_Id)





Destroy package

  • dfx_cfg_destroy (package_Id)

 

To Get PDI image Active UID info list

  • dfx_get_active_uid_list(int *buffer)

 

To Get PDI Image Meta-header info

  • dfx_get_meta_header(char *binfile, int *buffer, int buf_size)


Example Application flow



Build procedure

Build procedure for  compiling library from source

  1.  clone :  https://github.com/Xilinx/libdfx.git

  2. mkdir build

  3. cd build

  4. Ensure required tool chain added to your path

  5. cmake -DCMAKE_TOOLCHAIN_FILE="cmake tool chain file(complete path)" ../

    • Example: cmake -DCMAKE_TOOLCHAIN_FILE="/libdfx/cmake/toolchain.cmake" ../

  6. make

    • Once the build is successfully completed the library static, shared object files and app elf file are available in the below paths.
      -->build/src/libdfx.a
      -->build/src/libdfx.so.1.0
      -->build/apps/dfx_app

Build User Application and link with library source

  1. clone :  https://github.com/Xilinx/libdfx.git

  2. Replace the existing apps/libdfx_app.c contents with the user-required application.

  3. mkdir build

  4. cd build

  5. Ensure required tool chain added to your path

  6. cmake  -DCMAKE_TOOLCHAIN_FILE="cmake tool chain file(complete path)" ../

    • Example:  cmake -DCMAKE_TOOLCHAIN_FILE="../libdfx/cmake/toolchain.cmake" ../

  7. make

  8. The final elf will be available at apps/dfx_app

Reference DTBO file format

The Device Tree Overlay (DTO) is used to reprogram an FPGA while Linux is running. The DTO overlay will add the child node and the fragments from the .dtbo file to the base device tree,

The newly added device node/drivers will be probed after PDI /BIN/BIT programming.

Devicetree Overlay file contents example: For Only PDI/BIN/BIT configuration



PL drivers probing ( For Deferred Probe)



Devicetree Overlay file contents example: For PDI configuration + PL drivers probing

Create Device Tree Overlay Blob (.dtbo) file from .dts file

  •   # dtc -O dtb -o partial.dtbo -b 0 -@ partial.dtsi

                     Ex: ./scripts/dtc/dtc -O dtb -o partial.dtbo -b 0 -@ partial.dts

Copy the generated PDI and dtbo files into the target package folder 

Limitations

  • Libdfx is currently limited to supporting Zynq UltraScale+ MPSoC and Versal platforms.

  • The drivers dtbo file extension should be _d.dtbo (Ex: design_drivers_d.dtbo)

  • The current version supports only static builds and does not support dynamic linking

  • Input package/folder should contain only one bitstream/PDI image file and its relevant overlay file.

  • To use the deferred probe functionality both Image DTBO and relevant Drivers DTBO files are mandatory

Known issues

  • Upstream Linux kernel changes from v5.0 and above versions will affect the use of Device Tree (DT) overlays. These changes introduce restrictions that may require users to adjust their device tree overlays.   Fortunately the adjustments required are small. However, even with adjustments users will experience new warnings with no functional impact. With continued upstream improvements, the new warnings are expected to subside in the future. We can ignore these warnings for now.

  • Upstream overlay framework incorrectly updates the configfs ‘status’  to ‘applied’ when there is an error in create_overlay() and libdfx checks the content of the status file to decide if the overlay was a success or not. Hence libdfx dfx_cfg_load() API doesn’t return a proper status in certain use cases.

References

https://github.com/Xilinx/libdfx/tree/xlnx_rel_v2023.2/doc

https://rocketboards.org/foswiki/Documentation/UpstreamV50KernelDeviceTreeChanges



 

 

© Copyright 2019 - 2022 Xilinx Inc. Privacy Policy