EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: EPICS driver for Xilinx ZYNQ ultrascale FPGA firmware PL register read write
From: Michael Davidsaver via Tech-talk <tech-talk at aps.anl.gov>
To: "Kunjir, Shriraj" <kunjir at frib.msu.edu>
Cc: "tech-talk at aps.anl.gov" <tech-talk at aps.anl.gov>
Date: Mon, 7 Dec 2020 11:19:25 -0800
On 12/7/20 10:48 AM, Kunjir, Shriraj wrote:
> Hi Michael,
> 
> Thank you for your response. Could you please suggest what changes we need to do in order to do that ? The registers we are trying to access are in the user space. Thank you

This won't be a simple change.

First, I would strongly recommend you look beyond /dev/mem as an interface,
since it is easy to cause chaos, and lacks support for interrupts or DMA.
Any non-trivial project is likely to involve one or both of these features.

I think the logical starting point is the general UIO (Userspace I/O) driver
for platform devices "uio_pdrv_genirq".

A quick search find a couple of references to doing this with the xilinx tools.

The starting point is to add an entry to the (generated?) device tree file
which Linux reads.  eg. quoting from the first link:

> / {
>     counters@70000000 {
>         compatible = "generic-uio";
>         reg = < 0x70000000 0x1000 >;
>         interrupts = < 0 57 0 >;
>         interrupt-parent = <&gic>;
>     };
> };

Associates a platform device name "counters" with a register range
and interrupt line.  Importantly, it also mentions "generic-uio",
which is the key to associate with the "uio_pdrv_genirq" driver.

If all goes well, you should see /dev/uio0 (or similar) appearing.

http://fpga.org/2013/05/28/how-to-design-and-access-a-memory-mapped-device-part-two/

https://forum.digilentinc.com/topic/2719-how-to-register-my-device-as-uio-on-petalinux/


> Raj
> 
>  
> 
>  
> 
> *From: *Michael Davidsaver <mailto:mdavidsaver at gmail.com>
> *Sent: *Monday, December 7, 2020 1:45 PM
> *To: *Kunjir, Shriraj <mailto:kunjir at frib.msu.edu>; tech-talk at aps.anl.gov <mailto:tech-talk at aps.anl.gov>
> *Subject: *Re: EPICS driver for Xilinx ZYNQ ultrascale FPGA firmware PL register read write
> 
>  
> 
> [EXTERNAL] This email originated from outside of FRIB
> 
> 
> On 12/7/20 8:24 AM, Kunjir, Shriraj via Tech-talk wrote:
> 
>> Hello,
> 
>> 
> 
>> We have a design based on Xilinx ZYNQ Ultrascale plus FPGA. We have compiled EPICS base on the PS Linux side of the FPGA by following the tips mentioned here https://epics.anl.gov/tech-talk/2016/msg00632.php <https://epics.anl.gov/tech-talk/2016/msg00632.php> <https://epics.anl.gov/tech-talk/2016/msg00632.php <https://epics.anl.gov/tech-talk/2016/msg00632.php>>. We can read/write firmware PL side registers using busybox devmem from PS Linux and we are developing an application to read/write firmware PL registers from EPICS. Essentially, we are looking to run IOC on the Linux side of the FPGA. Are there any EPICS drivers that can do this ?
> 
> 
> 
>> Can devlib2 do this ?
> 
> 
> 
> At present, only if your FPGA logic appears to Linux as a PCI device.
> 
> Adding support for platform devices (or other non-discoverable)
> 
> device should be possible, but hasn't yet been done.
> 
> 
> 
> 
> 
>> Below is C code to read and write firmware registers (if not using busybox devmem)
> 
>> 
> 
>>  
> 
>> 
> 
>> *C code to read firmware registers from Linux – *
> 
>> 
> 
>>  
> 
>> 
> 
>>  
> 
>> 
> 
>> /#include <stdio.h>/
> 
>> 
> 
>> /#include <stdlib.h>/
> 
>> 
> 
>> /#include <unistd.h>/
> 
>> 
> 
>> /#include <sys/mman.h>/
> 
>> 
> 
>> /#include <fcntl.h>/
> 
>> 
> 
>> / /
> 
>> 
> 
>> /void usage(char *prog)/
> 
>> 
> 
>> /{/
> 
>> 
> 
>> /                printf("usage: %s ADDR\n",prog);/
> 
>> 
> 
>> /                printf("\n");/
> 
>> 
> 
>> /                printf("ADDR may be specified as hex values\n");/
> 
>> 
> 
>> /}/
> 
>> 
> 
>> / /
> 
>> 
> 
>> / /
> 
>> 
> 
>> /int main(int argc, char *argv[])/
> 
>> 
> 
>> /{/
> 
>> 
> 
>> /                int fd;/
> 
>> 
> 
>> /                void *ptr;/
> 
>> 
> 
>> /                unsigned addr, page_addr, page_offset;/
> 
>> 
> 
>> /                unsigned page_size=sysconf(_SC_PAGESIZE);/
> 
>> 
> 
>> / /
> 
>> 
> 
>> /                if(argc!=2) {/
> 
>> 
> 
>> /                                usage(argv[0]);/
> 
>> 
> 
>> /                                exit(-1);/
> 
>> 
> 
>> /                }/
> 
>> 
> 
>> / /
> 
>> 
> 
>> /                fd=open("/dev/mem",O_RDONLY);/
> 
>> 
> 
>> /                if(fd<1) {/
> 
>> 
> 
>> /                                perror(argv[0]);/
> 
>> 
> 
>> /                                exit(-1);/
> 
>> 
> 
>> /                }/
> 
>> 
> 
>> / /
> 
>> 
> 
>> /                addr=strtoul(argv[1],NULL,0);/
> 
>> 
> 
>> /                page_addr=(addr & ~(page_size-1));/
> 
>> 
> 
>> /                page_offset=addr-page_addr;/
> 
>> 
> 
>> / /
> 
>> 
> 
>> /                ptr=mmap(NULL,page_size,PROT_READ,MAP_SHARED,fd,(addr & ~(page_size-1)));/
> 
>> 
> 
>> /                if((int)ptr==-1) {/
> 
>> 
> 
>> /                                perror(argv[0]);/
> 
>> 
> 
>> /                                exit(-1);/
> 
>> 
> 
>> /                }/
> 
>> 
> 
>> / /
> 
>> 
> 
>> /                printf("0x%08x\n",*((unsigned *)(ptr+page_offset)));/
> 
>> 
> 
>> /                return 0;/
> 
>> 
> 
>> /}/
> 
>> 
> 
>>  
> 
>> 
> 
>> *C code to write firmware registers from Linux  - *
> 
>> 
> 
>>  
> 
>> 
> 
>> / /
> 
>> 
> 
>> /#include <stdio.h>/
> 
>> 
> 
>> /#include <stdlib.h>/
> 
>> 
> 
>> /#include <unistd.h>/
> 
>> 
> 
>> /#include <sys/mman.h>/
> 
>> 
> 
>> /#include <fcntl.h>/
> 
>> 
> 
>> / /
> 
>> 
> 
>> /void usage(char *prog)/
> 
>> 
> 
>> /{/
> 
>> 
> 
>> /                printf("usage: %s ADDR VAL\n",prog);/
> 
>> 
> 
>> /                printf("\n");/
> 
>> 
> 
>> /                printf("ADDR and VAL may be specified as hex values\n");/
> 
>> 
> 
>> /}/
> 
>> 
> 
>> / /
> 
>> 
> 
>> /int main(int argc, char *argv[])/
> 
>> 
> 
>> /{/
> 
>> 
> 
>> /                int fd;/
> 
>> 
> 
>> /                void *ptr;/
> 
>> 
> 
>> /                unsigned val;/
> 
>> 
> 
>> /                unsigned addr, page_addr, page_offset;/
> 
>> 
> 
>> /                unsigned page_size=sysconf(_SC_PAGESIZE);/
> 
>> 
> 
>> / /
> 
>> 
> 
>> /                fd=open("/dev/mem",O_RDWR);/
> 
>> 
> 
>> /                if(fd<1) {/
> 
>> 
> 
>> /                                perror(argv[0]);/
> 
>> 
> 
>> /                                exit(-1);/
> 
>> 
> 
>> /                }/
> 
>> 
> 
>> / /
> 
>> 
> 
>> /                if(argc!=3) {/
> 
>> 
> 
>> /                                usage(argv[0]);/
> 
>> 
> 
>> /                                exit(-1);/
> 
>> 
> 
>> /                }/
> 
>> 
> 
>> / /
> 
>> 
> 
>> /                addr=strtoul(argv[1],NULL,0);/
> 
>> 
> 
>> /                val=strtoul(argv[2],NULL,0);/
> 
>> 
> 
>> / /
> 
>> 
> 
>> /                page_addr=(addr & ~(page_size-1));/
> 
>> 
> 
>> /                page_offset=addr-page_addr;/
> 
>> 
> 
>> / /
> 
>> 
> 
>> /                ptr=mmap(NULL,page_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,(addr & ~(page_size-1)));/
> 
>> 
> 
>> / /
> 
>> 
> 
>> /                if((int)ptr==-1) {/
> 
>> 
> 
>> /                                perror(argv[0]);/
> 
>> 
> 
>> /                                exit(-1);/
> 
>> 
> 
>> /                }/
> 
>> 
> 
>> / /
> 
>> 
> 
>> /                *((unsigned *)(ptr+page_offset))=val;/
> 
>> 
> 
>> /                return 0;/
> 
>> 
> 
>> /}/
> 
>> 
> 
>>  
> 
>> 
> 
>>  
> 
>> 
> 
>> *Raj K*
> 
>> 
> 
>> Facility for Rare Isotope Beams
> 
>> 
> 
>>  
> 
>> 
> 
>> * *
> 
>> 
> 
>>  
> 
>> 
> 
>>  
> 
>> 
> 
> 
> 


References:
EPICS driver for Xilinx ZYNQ ultrascale FPGA firmware PL register read write Kunjir, Shriraj via Tech-talk
Re: EPICS driver for Xilinx ZYNQ ultrascale FPGA firmware PL register read write Michael Davidsaver via Tech-talk
RE: EPICS driver for Xilinx ZYNQ ultrascale FPGA firmware PL register read write Kunjir, Shriraj via Tech-talk

Navigate by Date:
Prev: Re: How do I pass a macro to a CSS Phoebus screen at startup from the command line D Willimoto via Tech-talk
Next: Re: [EXTERNAL] Re: How do I pass a macro to a CSS Phoebus screen at startup from the command line Kasemir, Kay via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024 
Navigate by Thread:
Prev: RE: EPICS driver for Xilinx ZYNQ ultrascale FPGA firmware PL register read write Kunjir, Shriraj via Tech-talk
Next: multiple USB devices in Asyn Siddons, David via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024 
ANJ, 08 Dec 2020 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·