Segmentation Fault - mmap() with C++

Ive been trying to use the mmap() function as I used to do in C but I cant manage to make it work.

The code below was implemented in C, but when I transfer it to C++ it simply gives me a segmentation error when I try to write something to the lw_pio_ptr like ~*lw_pio_ptr=0xFFFF~

printf("DE0-SoC Demo - FPGA + SoC \n");	

void *virtual_base;
int fd;
void *lw_pio_ptr;

if((fd = open( "/dev/mem", ( O_RDWR | O_SYNC ))) == -1 ){
	printf(" Error: couldn't open dev/mem \n");
	return 1;
}

printf("/dev/mem opened. \n");

virtual_base = mmap( NULL, HW_REGS_SPAN, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, HW_REGS_BASE );

if( virtual_base == MAP_FAILED ){
	printf(" Error: mmap() has failed... \n");
	close(fd);
	return 1;
}

lw_pio_ptr = virtual_base + ((unsigned long)(ALT_LWFPGASLVS_OFST + PIO_FPGA2HPS_LW_BASE) & (unsigned long)( HW_REGS_MASK ));

Also, the code in C++ I can`t just do this expression as in C. In C++ I have to cast the virtual_base pointer to a (unsigned long *).

"`lw_pio_ptr = virtual_base + ((unsigned long)(ALT_LWFPGASLVS_OFST + PIO_FPGA2HPS_LW_BASE) & (unsigned long)( HW_REGS_MASK ));"`

Does someone know how to fix it?
Thank you!

Don’t cast lw_pio_ptr to unsigned long .
Adding to a ptr increases the ptr by the size of the thing pointed to.
So adding 1 to a ulong
will (typically) bump the address pointed to by 4 so itnow points to the next ulong.
Adding 1 to an object ptr, will bump the address pointed to by the size of the object, NOT BY ONE!

In your case, cast it to a byte ptr first BEFORE doing any arithmatic on it.
AFTER you’ve added ALT_LWFPGASLVS_OFST etc to this byte ptr, then you can cast it to the ulong * you wanted.

Strictly speaking, arithmetic on void pointers is illegal, but GCC implements an extension to the standard. So your original C code was non-portable. MSVC disallows void * arithmetic, and it can be disabled in GCC with the -pedantic-errors compiler switch.

1 Like

Wow. Now it works. Thank you very much =D

Now it looks like:

lw_pio_ptr = (unsigned int *)(((uint8_t* )virtual_base) + ( LED_PIO_BASE & HW_REGS_MASK ));