Zynq, Yocto Linux and Custom FPGA IP Block Workflow - linux

I'm new to the Zynq devices and also to linux and the Yocto project.
I now have a project where I need to implement a custom FPGA IP block and use it from a yocto generated linux distribution.
Obviously I will have to write the linux drivers for that custom IP. But I'm not able to find a clear explanation how the workflow for such a project may look like.
I found some old tutorials but I'm not sure if they are still the way to go, so an up-to-date best practice workflow would be great.
What I did so far:
I created a test project in Vivado and created a small led example by passing through the FPGA block in a Microzed + carrier board.
Then I exported the HW from Vivado to get a BSP package I tested in a bare metal project with Vitis.
I installed Yocto and I build a reference distro for my microzed board with just a serial interface by following a tutorial online.All this comes more or less pre-backed from Xilinx.
But now I need to use a Yocto generated linux distro and enable it to use my custom (LED) IP.
My questions:
How does a detailed workflow in this case look like (at the end I
need a bootable SD card)?
More in detail:
How can I bring the mydevice_bsp generated from Vivado into the Yocto distro?
In which environment(how to write them i'll find out my self) do I write the
drivers for the yocto Linux and bring them into the distro?
How do I load the bitstream into the FPGA fabric when the Linux image has booted up?
Unfortunately I do not have to much time to get all this working, so it would be really cool to find a step by step tutorial from the start to the end.
Thanks in advance for your help.
Regards
Martin

I´m not sure if someone has written down a workflow for this, but I can tell you how I would handle it.
Create your IP code as hardware and use the IP packager to pack the code. You can also add some driver code too, so the SDK can use this to automatic generate the drivers. So you can use the regular workflow in Vitis to write your software.
Or you skip this part and use the hardware direct in your Linux. So you will create an IP core and add him to your system in Vivado. Export the hardware to get your BSP file. Then you need the Xilinx Device Tree Generator to generate your device tree. This tool uses some basic definitions (like the base adress) of your IP core to generate the device tree part for your hardware.
Then you create a normal bitstream and a bunch of tools to create your bootloader, kernel, device tree, bitstream file, etc. (all without Yocto). Copy all files to a SD card and boot up your device. You can take a look at my Linux project and the Wiki when you need some help. Now you can begin to write the driver for your device and test him on your real hardware. At last you can create a Yocto recipe to automatic include your driver to the kernel with KConfig.
After booting Linux you find a device /dev/devcfg which can be used to reprogram the FPGA. Please note that changing the FPGA with impact on the processing system (i. e. you add some interfaces to your PS) will cause in some errors (maybe that bug is gone over the last years, but I have to issue this problem a few years ago).
So according to your LED example you have to do the following steps:
Create the IP core
Create a basic processing system and add the IP core
Generate the bitstream
Export the hardware to Vitis
Open Vitis and create a new FSBL project
Add the Device Tree Generator to the Vitis repositories
Create a new device tree project
Build BOOT.bin, uImage, devicetree.dtb and copy them to your SD card
Boot your device
Check /proc/device-tree/ for your device
Begin with the driver development
Export your driver to Kconfig and Yocto (or use him as a loadable module)
You can find all the steps in my Wiki. Feel free to ask me.
But please note: The tutorial isn´t that new and unfortunately I don´t add a custom IP integration to that tutorial (maybe I will add it soon) but it should show you the way how you can do it.

Related

To build custom BSP layer using Yocto for a bare metal board [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 4 years ago.
Improve this question
I am developing an Embedded application based on Yocto Krogoth release to run on Nitrogen6x board. I have followed the steps mentioned in this link. I have successfully created the Linux distribution and Yocto SDK to develop and run my application on the nitrogen board. The target machine I used to setup the environment for building was:
MACHINE=nitrogen6x
Now, we reached a phase that we are going to create a custom board (based on same i.Mx.6). The real processor chip is not decided yet, but it will be based on iMx6.
Suppose we assume that the final custom board also uses the same processor chip as that of the Nitrogen6x board that am using for my development so far. Do I need to add any other CUSTOM BSP layer to my existing Yocto Repos to support the new custom board that I receive, or the existing Yocto layers and build environment I created for Nitrogen6x evaluation board will work fine for my custom board as well ?
Do i need to ask any specific information from the board vendor regarding the custom hardware changes he made in order to support any peripherals and GPIO lines so on.
What are the main things I have to consider if I receive a bare metal
custom board from a hardware vendor who is not planning to give any
minimal BSP package other than the schematics and pin mappings etc.
I read about creating a Custom BSP Layer in the Yocto documentation. But there are many other things in my mind that are not clear when I start thinking about a custom board (which is not like a Nitrogen6x, wandboard, Raspberry Pi etc., which has got a wide support in the Yocto, BSP communities).
EDIT 1
For example, I have built a Linux distribution for the Nitrogen6x board by specifying a machine name to the Yocto Build Setup Environment for which the Yocto Framework creates the Distro. I run the below instructions:
$ MACHINE=nitrogen6x source ./setup-environment build
$ bitbake core-image-sato
The machine I mentioned in the above step is nitrogen6x which is just a configuration file that looks like this. This file, mainly mentions these things:
Machine Type for which we are building the image for
Kernel Device trees required for the board
Preferred Uboot provider (u-boot-boundary)
Preferred Kernel provider (linux-boundary)
Preferred BSP (linux-fslc)
Boot Script (6x_bootscript)
Basic peripheral support like (serial, Bluetooth, wifi or network
chips)
My understanding so far was that, In the above list everything else remains the same except the highlighted ones for the custom board. Am I right with the below points ?
Kernel Device Trees: I may have to create a custom device tree file for my custom board based on the schematics and other hardware info. Is there any reference or document that I can refer to create my own .dts file.
BSP: I am expecting that the BSP layer I am currently using for the Nitrogen board may probably be compatible and work for the custom board too since it is going to be made based on the iMx6 platform. And this is the section where I have to work to get a prompt ? Will hardware providers give us a minimal set of software to check the boards boots and gets us a prompt or do I need to get it working on a bare metal board.
Thanks for any help you can provide.
I strongly recommend you to create a new fresh layer in order to handle your new custom device. It will allow you to properly dissociate devices and machine configuration from remote repositories. I do not know how to plan to manager deliveries/versions but I suggest you to use repo. You will find many information on NXP documentation.
My understanding so far was that, In the above list everything else remains the same except the highlighted ones for the custom board. Am I right with the below points ?
We do not know what do you really expect from your custom device. So thus, this machine configuration could satisfy your requirements, but could also need adjustments. Because the new machine override new machine override has been introduced last year, I am actually not familiarized with it yet. But it allows you to configure your BSP layer by adding a simple line in your local.conf. Depending on your local.conf, you will compile kernel from linux-boundary or linux-fslc recipes.
Kernel Device Trees: I may have to create a custom device tree file for my custom board based on the schematics and other hardware info. Is there any reference or document that I can refer to create my own .dts file.
You are able to append as many dts you want in KERNEL_DEVICETREE = you will have to had your own one. It exists lot of information about dts. Follow this link for a first introduction.
You will habe to create your own device tree (for instance, customboard-imx6.dts) under /arch/arm/boot/dts/ directory. You can also include it in your sources during your development process.
BSP: I am expecting that the BSP layer I am currently using for the Nitrogen board may probably be compatible and work for the custom board too since it is going to be made based on the iMx6 platform. And this is the section where I have to work to get a prompt ?
If yes, how do you plan to manage sources ?

Custom Linux Kernel

I'm complety new to this but I finally got around to building a Linux kernel so far so good. I am following a guide here:
A10-OLinuXino-LIME
My problem/concern is now I am in a .config menu and I've been searching online to no avail to determine what does it mean by a modularizes features verse includes, like should I switch to if I want those features to be there?
Any help or advice would be greatly appreciated it! I'm primarily doing this to include WiFi usb drivers I will be needing.
It depends on what system you run this kernel. If it's an embedded system, then you will probably be more concerned about memory benefits. In RAM you can win about several Kbytes per module. For the devices are not represented in the system/hardware, it then has a sense to put some drivers on Modules. Some modules can be taking more time when the kernel starts, and it is probably better to load them later, when the system is running.
You will probably be concerned about disk space, if you put some stuff Compiled-in so you can have a benefit because you don't need to have a module loading utility.
Have a look at this thread as well
I'm primarily doing this to include WiFi usb drivers I will be needing.
Its not necessary to build the complete kernel unless to build a USB WiFi driver. All you need is the kernel headers installed. From make menuconfig select the module you want to build, choose M, save the .config. This will build a module which can be loaded, instead of getting compiled as a part of the vmlinux image.

Automatically enabling all ethernet, ATA, SATA, and SCSI drivers in the Linux .config file

I am compiling my own Linux kernel and userland tools for a PXE environment meant for cloning and reimaging. Right now, I'm sticking to a specific kernel version and using preconfigured .config's for building the Linux kernel.
I need to change from using preconfigured .config's to automatically generating the default configuration for the specified architecture, and then enabling all ethernet, ATA, SATA, and SCSI drivers.
The reason I want to do this is:
Updating the kernel means updating the preconfigured .config's, which takes too much time to manually do. The way I'm doing it now is using menuconfig, enabling the options I need, and saving the resulting .config to my repository.
I know the kernel I'm building is missing some drivers because I've encountered some PC's that were not able to mount the NFS share because Linux could not find an ethernet device (which I've verified by booting an Ubuntu CD, which did find the ethernet device). I want an automated way of building any Linux kernel version that will guarantee that ALL drivers I need are pulled in.
Using a distribution's configuration pulls in too many unnecessary drivers and features for my purposes. It lengthens the kernel build time from 10-15 mintues to an hour or more, and the resulting image is too big.
Does anyone know how to write a Bash script to accomplish this?
Have you considered using a text editor to modify the .config file.
Then you can modify it using search and replace.
Plus, there are other choices for configuring the kernel than the menu-driven "menuconfig".

Devicetree in embedded linux

How can I convert platform specific file to device tree?.
I know theoretically about device tree.
Please explain how its works in raspberry pi board or any other boards.
A device-tree is simply a data structure for describing the hardware present on a system. In the absence of device-tree, systems rely on "board-files". These are C files with plenty of structures, each describing every individual hardware present on the system and also how they are connected.
Porting of code from legacy "board-files" to device-tree dts files is currently an ongoing process across several platforms/devices based on the ARM architecture.
To do this one requires proper understanding of the
platform/device hardware.
structure of the board-file.
structure of the dts file.
This answer should help you get started in preparing a device-tree dts.
Also there is an ongoing effort to migrate the raspberry-pi Linux-kernel to use device-tree. Take a look at the source and booting instructions.

How to compile and install a Linux kernel into an ARM kit

I have an ARM kit beside me and a Linux kernel source code patched with Xenomai on my machine. I understand I can send data to the kit through an USB cable and a (windows-based, of course) software, but I'm stumped as to exactly what I should be sending that would make the kit run Linux.
(clarifications from comments: It is an Atmel AT91SAM9260-EK kit. It uses SAM-BA and SAM-PROG for the loading and unloading of data through either a serial or USB cable.)
I'd start with the ATM91SAM9 Linux software package from Atmel and follow the instructions.
Linky:
http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4335
Otherwise, you need to get GCC setup with an ARM back end on a Linux box, build a Linux binary and then figure out how to load it on the devt board.
You might want to check out some cross compiler like OpenEmbedded which will help you compile the kernel for the ARM architecture.
i would suggest jtag and openOCD, then you just use the JTAG to place your filesystem and kernal image in the flash memory, in a place wear our bootloader can find it. you might have to change your bootloader.
another option is you might start up your micro, then insert a bootloading program into the RAM of the program then change the program counter to point at it.
that bootloading program can init the UART/USB then you have a host side program that transers the files. this method is very complicated and generally only good if you don't want to spend 100$ on a jtag (hint, buy a jtag they are useful)

Resources