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. 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 ?
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
|