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 *devpath, u32 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
mkdir build
cd build
Ensure required tool chain added to your path
cmake -DCMAKE_TOOLCHAIN_FILE="cmake tool chain file(complete path)" ../
Example: cmake -DCMAKE_TOOLCHAIN_FILE="/libdfx/cmake/toolchain.cmake" ../
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
Replace the existing apps/libdfx_app.c contents with the user-required application.
mkdir build
cd build
Ensure required tool chain added to your path
cmake -DCMAKE_TOOLCHAIN_FILE="cmake tool chain file(complete path)" ../
Example: cmake -DCMAKE_TOOLCHAIN_FILE="../libdfx/cmake/toolchain.cmake" ../
make
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