UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Visitor marcoliveras
Visitor
741 Views
Registered: ‎02-01-2017

Failed to open Xillybus device file(s)

Hello,

 

I used Xillybus on Xillinux 2.0a on Zybo Zynq-7000 and could successfully acces to PL through /dev/xillybus_read_32 and /dev/xillybus_write_32 in previous codes.

 

Now I'm trying to implement a code based on a Sobel Operator, where the PS do all the data management, and the PS run the calculations. I synthesized the PL code with Vivado HLS 2016.4 and exported the RTL file, and I added it to the Vivado 2016.4 project 'xillinux-eval-zybo-2.0a' and generated the bitstream.

 

When I try to execute my host program on Xillinux it generates the following error: "Failed to open Xillybus device file(s): Device or resource busy".

 

I have searched for this error on the Internet and I have only found a reference in the 'Xillybus host application programming guide for Linux'. I understand what this error means, but I can not see what might be generating it. I have tried to limit the opening and closing of these device files, but it persists.

The device files remain busy because I tried to use "cat /dev/xillybus_read_32" on the terminal (when I'm not running the program) and it also says it is busy.

 

To introduce my code, I try to apply the Sobel filter on a 100x100 image in bmp format. Due to the memory limitations of the PL, I only send and save the first two rows of pixels on the image and the three first pixels of the third row; so I can make the first convolution, and then I shift all the array to the left and save the next pixel send from the PS in the last position of the array.

The host program is based on the example given in 'FPGA coprocessing for C/C++ programmers' tutorial -A practical host program-, but I have modified it to fit my application.

 

HOST PROGRAM:

 

 

#include <stdio.h>
#include <unistd.h>

#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>

#define N 203
#define BUFFER_SIZE 10000
#define ncols 100
#define header 1078

int main(int argc, char *argv[]) {

   FILE *source;
   FILE *destination;
   unsigned char set[header];
   int imfrompl[BUFFER_SIZE] = {0};
   unsigned char buffer[BUFFER_SIZE];
   unsigned char imgout[BUFFER_SIZE];

   //Reading the original image
   source = fopen("/root/Desktop/img100.bmp", "r");
   //Reading the header and saving it in the output image
   destination = fopen("hostsobelfork.bmp", "w");
   fread(set, 1, header, source);
   fwrite(set, 1, header, destination);

 

   int fdr, fdw, rc, donebytes, i;
   unsigned char *buf2pl;
   int *buf2ps;
   pid_t pid;

 

   //Trying to limit the opening and closing
   if (fdr == 0)
      fdr = open("/dev/xillybus_read_32", O_RDONLY);


   if (fdw == 0)
      fdw = open("/dev/xillybus_write_32", O_WRONLY);

 

   if ((fdr < 0) || (fdw < 0)) {
      perror("Failed to open Xillybus device file(s)");
      exit(1);
   }

   pid = fork();

   if (pid < 0) {
      perror("Failed to fork()");
      exit(1);
   }

   //Sending data to PL
   if (pid) {
      close(fdr);

      buf2pl = &buffer[0];
      donebytes = 0;

 

      while (donebytes < (BUFFER_SIZE) * sizeof(int)) {
         rc = write(fdw, buf2pl + donebytes, (BUFFER_SIZE) * sizeof(int) - donebytes);

 

         if ((rc < 0) && (errno == EINTR))
            continue;

 

         if (rc <= 0) {
            perror("write() failed");
            exit(1);
         }

         donebytes += rc;
      }

      close(fdw);
      return 0;
   }

   //Receiving data from PL
   else {
      close(fdw);

      buf2ps = &imfrompl[ncols+1];
      donebytes = 0;

 

      while (donebytes < (BUFFER_SIZE - N) * sizeof(int)) {
         rc = read(fdr, buf2ps + donebytes, (BUFFER_SIZE - N) * sizeof(int) - donebytes);

 

         if ((rc < 0) && (errno == EINTR))
             continue;

 

         if (rc < 0) {
            perror("read() failed");
            exit(1);
         }

         if (rc == 0) {
            fprintf(stderr, "Reached read EOF!? Should never happen.\n");
            exit(0);
         }

         donebytes += rc;
      }

      for (i=0; i<BUFFER_SIZE; i++) //Saving the results and cast data to unsigned char
         imgout[i] = (unsigned char)imfrompl[i];

      if (!fseek(destination, header, SEEK_SET)) //Filling out the output image
         fwrite(imgout, 1, BUFFER_SIZE, destination);

      fclose(source);
      fclose(destination);
      fclose(destination2);

      close(fdr);

      return 0;
   }
}

 

**************************************************************************************************************

 

PROGRAM RUNNING ON THE PL:

 

 

#include <math.h>
#include <stdint.h>
#include "xilly_debug.h"

 

static int c1=0; //number of runs counter

 

void xillybus_wrapper(int *in, int *out) {
#pragma AP interface ap_fifo port=in
#pragma AP interface ap_fifo port=out
#pragma AP interface ap_ctrl_none port=return

 

   int imin[203];
   int k[9] = {1,0,-1,2,0,-2,1,0,-1};
   int x, y, c, ncols, scale, pos, threshold;

 

   ncols = 100;
   scale = 8;
   threshold=10;
   pos=ncols+1;

   c1 += 1;

   // Receiving input data from PS
   imin[202] = *in++;


   if (c1 > 202){

      // Carrying out the calculations of the Sobel kernel convolution
      c = k[0]*imin[pos-ncols-1]+k[1]*imin[pos-ncols]+k[2]*imin[pos-ncols+1]+k[3]*imin[pos-1]+k[4]*imin[pos]+k[5]*imin[pos+1]+k[6]*imin[pos+ncols-1]+k[7]*imin[pos+ncols]+k[8]*imin[pos+ncols+1];

      // Sending output data to PS
      if (c/scale < threshold)
         *out++ = 0;
      else
         *out++ = c/scale;
     }

   // Reset counter when finished
   if (c1 > 9999)
      c1 = 0;
      
   for (y=0; y<202; y++) {
      // Shifting the array to left to sort the data
      imin[y] = imin[y+1];

   }     

   //*out++ = 1; //I tried it, to ensure an output in each run, and the error still the same

   // Debug output
   xilly_puts("count=");
   xilly_decprint(count, 1);
   xilly_puts("\n");

}

 

***************************************************************************************************************

 

Any guess of where this problem could come from?

 

Thanks in advance.

 

Best regards,

 

   Marc

0 Kudos
1 Reply
Adventurer
Adventurer
704 Views
Registered: ‎06-10-2014

Re: Failed to open Xillybus device file(s)

Hello,

 

The first thing that comes to mind is that you use check if fdr and fdw are zero even though you haven't initialized them. I suggest compiling with the -Wall flag (I believe it would have told you that you're using an uninitialized variable). Not that I understand the logic behind that check. But this is probably not the issue anyhow.

 

As for the error itself -- does it occur on a freshly booted system? It's the easiest way to see if it's a matter of some process really holding the file.

 

Have you tried using "lsof" to find the process that may hold the file? Maybe you have some child process remaining alive, holding the file? Keep in mind that you'll get a shell prompt when the father process finishes, but the child can go on. In fact, the proper way to finish up the father process is to wait() or waitpid() for the child.

 

Regards,

   Eli

0 Kudos