diff --git a/scalp_fast_router_firmware_petalinux/.petalinux/metadata b/scalp_fast_router_firmware_petalinux/.petalinux/metadata
index 85613960f0227f7de5aaa795241fcb3c2c15d366..c15beda93bb7bda57b7329a244b6736d1d91b168 100644
--- a/scalp_fast_router_firmware_petalinux/.petalinux/metadata
+++ b/scalp_fast_router_firmware_petalinux/.petalinux/metadata
@@ -2,5 +2,5 @@ PETALINUX_VER=2020.2
 VALIDATE_HW_CHKSUM=1
 HARDWARE_CHECKSUM=f2c3aa42b9c1cc33b3fae6a00a47c742
 YOCTO_SDK=5ff8fc5f85d1566b314bb73eaa378212
-RFSCONFIG_CHKSUM=3f80b80381dcceaf27f1ea1b2d4f4a22
+RFSCONFIG_CHKSUM=875fef99c2cf2a1f1c40d3a7bfaa5b32
 HARDWARE_PATH=/home/jo/Documents/Projets/Hepia/scalp_project/scalp_firmware/designs/vivado/scalp_fast_router_firmware/2020.2/lin64/scalp_fast_router_firmware/scalp_fast_router_firmware.xsa
diff --git a/scalp_fast_router_firmware_petalinux/project-spec/configs/rootfs_config b/scalp_fast_router_firmware_petalinux/project-spec/configs/rootfs_config
index 64de46eb3a138cabd9ec1ec2dd64430a3d228804..5efa805dcbd78a5501e8f3b67d70715569ebeca1 100644
--- a/scalp_fast_router_firmware_petalinux/project-spec/configs/rootfs_config
+++ b/scalp_fast_router_firmware_petalinux/project-spec/configs/rootfs_config
@@ -4025,6 +4025,7 @@ CONFIG_imagefeature-debug-tweaks=y
 CONFIG_bitstream-conf=y
 CONFIG_bitstream-init=y
 CONFIG_dmatest=y
+CONFIG_dmatest-devmem=y
 # CONFIG_gpio-demo is not set
 CONFIG_peekpoke=y
 # CONFIG_sampleapp is not set
diff --git a/scalp_fast_router_firmware_petalinux/project-spec/meta-user/conf/user-rootfsconfig b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/conf/user-rootfsconfig
index e2b7a7204994029926d95997ee62338068794bed..c1ae806a7855a73c5c4589a48ec3073282bf46ff 100644
--- a/scalp_fast_router_firmware_petalinux/project-spec/meta-user/conf/user-rootfsconfig
+++ b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/conf/user-rootfsconfig
@@ -15,3 +15,4 @@ CONFIG_sampleread
 CONFIG_scalp-locaddr
 CONFIG_scalplocaddr
 CONFIG_dmatest
+CONFIG_dmatest-devmem
diff --git a/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/.gdbinit b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/.gdbinit
new file mode 100644
index 0000000000000000000000000000000000000000..d59fb8d90efb393c83d35becbecddcfa493a5e67
--- /dev/null
+++ b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/.gdbinit
@@ -0,0 +1,2 @@
+# Load the PetaLinux SDK main gdbinit script
+source plnx_gdbinit
diff --git a/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/README b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/README
new file mode 100644
index 0000000000000000000000000000000000000000..75747ec34bce94292ef94f880aadcfda9a296200
--- /dev/null
+++ b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/README
@@ -0,0 +1,32 @@
+PetaLinux User Application Template
+===================================
+
+This directory contains a PetaLinux user application created from a template.
+
+If you are developing your application from scratch, simply start editing the
+file dmatest-devmem.c.
+
+You can easily import any existing application code by copying it into this 
+directory, and editing the automatically generated Makefile.
+
+Before building the application, you will need to enable the application
+from PetaLinux menuconfig by running:
+    "petalinux-config -c rootfs"
+You will see your application in the "apps --->" submenu.
+
+To build your application, simply run "petalinux-build -c dmatest-devmem".
+This command will build your application and will install your application
+into the target file system host copy.
+
+You will also need to rebuild PetaLinux bootable images so that the images
+is updated with the updated target filesystem copy, run this command:
+    "petalinux-build -c rootfs"
+
+You can also run one PetaLinux command to install the application to the
+target filesystem host copy and update the bootable images as follows:
+    "petalinux-build"
+
+To add extra source code files (for example, to split a large application into 
+multiple source files), add the relevant .o files to the list in the local 
+Makefile where indicated.  
+
diff --git a/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/dmatest-devmem.bb b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/dmatest-devmem.bb
new file mode 100644
index 0000000000000000000000000000000000000000..0df8759a05f7ae9764c60fe89acb6a946812d21c
--- /dev/null
+++ b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/dmatest-devmem.bb
@@ -0,0 +1,23 @@
+#
+# This file is the dmatest-devmem recipe.
+#
+
+SUMMARY = "Simple dmatest-devmem application"
+SECTION = "PETALINUX/apps"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
+
+SRC_URI = "file://dmatest-devmem.c \
+	   file://Makefile \
+		  "
+
+S = "${WORKDIR}"
+
+do_compile() {
+	     oe_runmake
+}
+
+do_install() {
+	     install -d ${D}${bindir}
+	     install -m 0755 dmatest-devmem ${D}${bindir}
+}
diff --git a/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/files/Makefile b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/files/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..84d398da8fcb8517f057e375b47053f15897ab1a
--- /dev/null
+++ b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/files/Makefile
@@ -0,0 +1,14 @@
+APP = dmatest-devmem
+
+# Add any other object files to this list below
+APP_OBJS = dmatest-devmem.o
+
+all: build
+
+build: $(APP)
+
+$(APP): $(APP_OBJS)
+	$(CC) -o $@ $(APP_OBJS) $(LDFLAGS) $(LDLIBS)
+clean:
+	rm -f $(APP) *.o
+
diff --git a/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/files/dmatest-devmem.c b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/files/dmatest-devmem.c
new file mode 100644
index 0000000000000000000000000000000000000000..e45a8c8007c3ef2e42341973a08714c06315637b
--- /dev/null
+++ b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/files/dmatest-devmem.c
@@ -0,0 +1,423 @@
+/*
+* Copyright (C) 2013 - 2016  Xilinx, Inc.  All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person
+* obtaining a copy of this software and associated documentation
+* files (the "Software"), to deal in the Software without restriction,
+* including without limitation the rights to use, copy, modify, merge,
+* publish, distribute, sublicense, and/or sell copies of the Software,
+* and to permit persons to whom the Software is furnished to do so,
+* subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in this
+* Software without prior written authorization from Xilinx.
+*
+*/
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <termios.h>
+#include <sys/mman.h>
+
+#define MM2S_CONTROL_REGISTER       0x00
+#define MM2S_STATUS_REGISTER        0x04
+#define MM2S_SRC_ADDRESS_REGISTER   0x18
+#define MM2S_TRNSFR_LENGTH_REGISTER 0x28
+
+#define S2MM_CONTROL_REGISTER       0x30
+#define S2MM_STATUS_REGISTER        0x34
+#define S2MM_DST_ADDRESS_REGISTER   0x48
+#define S2MM_BUFF_LENGTH_REGISTER   0x58
+
+#define IOC_IRQ_FLAG                1<<12
+#define IDLE_FLAG                   1<<1
+
+#define STATUS_HALTED               0x00000001
+#define STATUS_IDLE                 0x00000002
+#define STATUS_SG_INCLDED           0x00000008
+#define STATUS_DMA_INTERNAL_ERR     0x00000010
+#define STATUS_DMA_SLAVE_ERR        0x00000020
+#define STATUS_DMA_DECODE_ERR       0x00000040
+#define STATUS_SG_INTERNAL_ERR      0x00000100
+#define STATUS_SG_SLAVE_ERR         0x00000200
+#define STATUS_SG_DECODE_ERR        0x00000400
+#define STATUS_IOC_IRQ              0x00001000
+#define STATUS_DELAY_IRQ            0x00002000
+#define STATUS_ERR_IRQ              0x00004000
+
+#define HALT_DMA                    0x00000000
+#define RUN_DMA                     0x00000001
+#define RESET_DMA                   0x00000004
+#define ENABLE_IOC_IRQ              0x00001000
+#define ENABLE_DELAY_IRQ            0x00002000
+#define ENABLE_ERR_IRQ              0x00004000
+#define ENABLE_ALL_IRQ              0x00007000
+
+#define BUFF_SIZE                   32
+
+#define H0_1 0x01000002
+#define H0_2 0x01000001
+#define H1_1 0x00000001
+#define H1_2 0x00000002
+#define H2   0x00000800
+
+unsigned int write_dma(unsigned int *virtual_addr, int offset, unsigned int value)
+{
+    virtual_addr[offset>>2] = value;
+
+    return 0;
+}
+
+unsigned int read_dma(unsigned int *virtual_addr, int offset)
+{
+    return virtual_addr[offset>>2];
+}
+
+void dma_s2mm_status(unsigned int *virtual_addr)
+{
+    unsigned int status = read_dma(virtual_addr, S2MM_STATUS_REGISTER);
+
+    printf("Stream to memory-mapped status (0x%08x@0x%02x):", status, S2MM_STATUS_REGISTER);
+
+    if (status & STATUS_HALTED) {
+		printf(" Halted.\n");
+	} else {
+		printf(" Running.\n");
+	}
+
+    if (status & STATUS_IDLE) {
+		printf(" Idle.\n");
+	}
+
+    if (status & STATUS_SG_INCLDED) {
+		printf(" SG is included.\n");
+	}
+
+    if (status & STATUS_DMA_INTERNAL_ERR) {
+		printf(" DMA internal error.\n");
+	}
+
+    if (status & STATUS_DMA_SLAVE_ERR) {
+		printf(" DMA slave error.\n");
+	}
+
+    if (status & STATUS_DMA_DECODE_ERR) {
+		printf(" DMA decode error.\n");
+	}
+
+    if (status & STATUS_SG_INTERNAL_ERR) {
+		printf(" SG internal error.\n");
+	}
+
+    if (status & STATUS_SG_SLAVE_ERR) {
+		printf(" SG slave error.\n");
+	}
+
+    if (status & STATUS_SG_DECODE_ERR) {
+		printf(" SG decode error.\n");
+	}
+
+    if (status & STATUS_IOC_IRQ) {
+		printf(" IOC interrupt occurred.\n");
+	}
+
+    if (status & STATUS_DELAY_IRQ) {
+		printf(" Interrupt on delay occurred.\n");
+	}
+
+    if (status & STATUS_ERR_IRQ) {
+		printf(" Error interrupt occurred.\n");
+	}
+}
+
+void dma_mm2s_status(unsigned int *virtual_addr)
+{
+    unsigned int status = read_dma(virtual_addr, MM2S_STATUS_REGISTER);
+
+    printf("Memory-mapped to stream status (0x%08x@0x%02x):", status, MM2S_STATUS_REGISTER);
+
+    if (status & STATUS_HALTED) {
+		printf(" Halted.\n");
+	} else {
+		printf(" Running.\n");
+	}
+
+    if (status & STATUS_IDLE) {
+		printf(" Idle.\n");
+	}
+
+    if (status & STATUS_SG_INCLDED) {
+		printf(" SG is included.\n");
+	}
+
+    if (status & STATUS_DMA_INTERNAL_ERR) {
+		printf(" DMA internal error.\n");
+	}
+
+    if (status & STATUS_DMA_SLAVE_ERR) {
+		printf(" DMA slave error.\n");
+	}
+
+    if (status & STATUS_DMA_DECODE_ERR) {
+		printf(" DMA decode error.\n");
+	}
+
+    if (status & STATUS_SG_INTERNAL_ERR) {
+		printf(" SG internal error.\n");
+	}
+
+    if (status & STATUS_SG_SLAVE_ERR) {
+		printf(" SG slave error.\n");
+	}
+
+    if (status & STATUS_SG_DECODE_ERR) {
+		printf(" SG decode error.\n");
+	}
+
+    if (status & STATUS_IOC_IRQ) {
+		printf(" IOC interrupt occurred.\n");
+	}
+
+    if (status & STATUS_DELAY_IRQ) {
+		printf(" Interrupt on delay occurred.\n");
+	}
+
+    if (status & STATUS_ERR_IRQ) {
+		printf(" Error interrupt occurred.\n");
+	}
+}
+
+int dma_mm2s_sync(unsigned int *virtual_addr)
+{
+    unsigned int mm2s_status =  read_dma(virtual_addr, MM2S_STATUS_REGISTER);
+
+	// sit in this while loop as long as the status does not read back 0x00001002 (4098)
+	// 0x00001002 = IOC interrupt has occured and DMA is idle
+	while(!(mm2s_status & IOC_IRQ_FLAG) || !(mm2s_status & IDLE_FLAG))
+	{
+        dma_s2mm_status(virtual_addr);
+        dma_mm2s_status(virtual_addr);
+
+        mm2s_status =  read_dma(virtual_addr, MM2S_STATUS_REGISTER);
+    }
+
+	return 0;
+}
+
+int dma_s2mm_sync(unsigned int *virtual_addr)
+{
+    unsigned int s2mm_status = read_dma(virtual_addr, S2MM_STATUS_REGISTER);
+
+	// sit in this while loop as long as the status does not read back 0x00001002 (4098)
+	// 0x00001002 = IOC interrupt has occured and DMA is idle
+	while(!(s2mm_status & IOC_IRQ_FLAG) || !(s2mm_status & IDLE_FLAG))
+	{
+        dma_s2mm_status(virtual_addr);
+        dma_mm2s_status(virtual_addr);
+
+        s2mm_status = read_dma(virtual_addr, S2MM_STATUS_REGISTER);
+    }
+
+	return 0;
+}
+
+void print_mem(void *virtual_address, int byte_count)
+{
+	char *data_ptr = virtual_address;
+
+	for(int i=0;i<byte_count;i++){
+		printf("%02X", data_ptr[i]);
+
+		// print a space every 4 bytes (0 indexed)
+		if(i%4==3){
+			printf(" ");
+		}
+	}
+
+	printf("\n");
+}
+
+int main(int argc, char *argv[])
+{
+    printf("Hello World! - Running DMA transfer test application.\n");
+
+	printf("Opening a character device file of the Arty's DDR memeory...\n");
+	int ddr_memory = open("/dev/mem", O_RDWR | O_SYNC);
+
+	printf("Memory map the address of the DMA AXI IP via its AXI lite control interface register block.\n");
+    unsigned int *dma_virtual_addr = mmap(NULL, 65535, PROT_READ | PROT_WRITE, MAP_SHARED, ddr_memory, 0x40400000);
+
+	printf("Memory map the MM2S source address register block.\n");
+    unsigned int *virtual_src_addr  = mmap(NULL, 65535, PROT_READ | PROT_WRITE, MAP_SHARED, ddr_memory, 0x0e000000);
+
+	printf("Memory map the S2MM destination address register block.\n");
+    unsigned int *virtual_dst_addr = mmap(NULL, 65535, PROT_READ | PROT_WRITE, MAP_SHARED, ddr_memory, 0x0f000000);
+
+	printf("Writing random data to source register block...\n");
+
+    if(argc == 2)
+    {
+        if(strcmp(argv[1], "1") == 0)
+        {
+            printf("#> 1\n");
+            virtual_src_addr[0]= H0_1;
+            virtual_src_addr[1]= H1_1;
+            virtual_src_addr[2]= H2;
+        }
+        else if(strcmp(argv[1], "2") == 0)
+        {
+            printf("#> 2\n");
+            virtual_src_addr[0]= H0_2;
+            virtual_src_addr[1]= H1_2;
+            virtual_src_addr[2]= H2;
+        }
+        else
+        {
+            virtual_src_addr[0]= 0xCDCDCDCD;
+            virtual_src_addr[1]= 0x00001111;
+            virtual_src_addr[2]= 0x22223333;
+        }
+    }
+	
+	virtual_src_addr[3]= 0xCDCDCDCD;
+	virtual_src_addr[4]= 0x00001111;
+	virtual_src_addr[5]= 0x22223333;
+	virtual_src_addr[6]= 0x44445555;
+	virtual_src_addr[7]= 0x66667777;
+
+	printf("Clearing the destination register block...\n");
+    memset(virtual_dst_addr, 0, BUFF_SIZE);
+
+    printf("Source memory block data:      ");
+	print_mem(virtual_src_addr, BUFF_SIZE);
+
+    printf("Destination memory block data: ");
+	print_mem(virtual_dst_addr, BUFF_SIZE);
+
+    printf("Reset the DMA.\n");
+    write_dma(dma_virtual_addr, S2MM_CONTROL_REGISTER, RESET_DMA);
+    write_dma(dma_virtual_addr, MM2S_CONTROL_REGISTER, RESET_DMA);
+    dma_s2mm_status(dma_virtual_addr);
+    dma_mm2s_status(dma_virtual_addr);
+
+	printf("Halt the DMA.\n");
+    write_dma(dma_virtual_addr, S2MM_CONTROL_REGISTER, HALT_DMA);
+    write_dma(dma_virtual_addr, MM2S_CONTROL_REGISTER, HALT_DMA);
+    dma_s2mm_status(dma_virtual_addr);
+    dma_mm2s_status(dma_virtual_addr);
+
+	printf("Enable all interrupts.\n");
+    write_dma(dma_virtual_addr, S2MM_CONTROL_REGISTER, ENABLE_ALL_IRQ);
+    write_dma(dma_virtual_addr, MM2S_CONTROL_REGISTER, ENABLE_ALL_IRQ);
+    dma_s2mm_status(dma_virtual_addr);
+    dma_mm2s_status(dma_virtual_addr);
+
+    printf("Writing source address of the data from MM2S in DDR...\n");
+    write_dma(dma_virtual_addr, MM2S_SRC_ADDRESS_REGISTER, 0x0e000000);
+    dma_mm2s_status(dma_virtual_addr);
+
+    printf("Writing the destination address for the data from S2MM in DDR...\n");
+    write_dma(dma_virtual_addr, S2MM_DST_ADDRESS_REGISTER, 0x0f000000);
+    dma_s2mm_status(dma_virtual_addr);
+
+	printf("Run the MM2S channel.\n");
+    write_dma(dma_virtual_addr, MM2S_CONTROL_REGISTER, RUN_DMA);
+    dma_mm2s_status(dma_virtual_addr);
+
+	printf("Run the S2MM channel.\n");
+    write_dma(dma_virtual_addr, S2MM_CONTROL_REGISTER, RUN_DMA);
+    dma_s2mm_status(dma_virtual_addr);
+
+    printf("#> Press any key...\n");
+    getchar();
+
+    if(argc == 2)
+    {
+        if(strcmp(argv[1], "1") == 0)
+        {
+            printf("Writing MM2S transfer length of 32 bytes...\n");
+            write_dma(dma_virtual_addr, MM2S_TRNSFR_LENGTH_REGISTER, BUFF_SIZE);
+            dma_mm2s_status(dma_virtual_addr);
+
+            printf("Writing S2MM transfer length of 32 bytes...\n");
+            write_dma(dma_virtual_addr, S2MM_BUFF_LENGTH_REGISTER, 0);
+            dma_s2mm_status(dma_virtual_addr);
+
+            printf("Waiting for MM2S synchronization...\n");
+            dma_mm2s_sync(dma_virtual_addr);
+
+            //printf("Waiting for S2MM sychronization...\n");
+            //dma_s2mm_sync(dma_virtual_addr);
+        }
+        else if(strcmp(argv[1], "2") == 0)
+        {
+            printf("Writing MM2S transfer length of 32 bytes...\n");
+            write_dma(dma_virtual_addr, MM2S_TRNSFR_LENGTH_REGISTER, 0);
+            dma_mm2s_status(dma_virtual_addr);
+
+            printf("Writing S2MM transfer length of 32 bytes...\n");
+            write_dma(dma_virtual_addr, S2MM_BUFF_LENGTH_REGISTER, BUFF_SIZE);
+            dma_s2mm_status(dma_virtual_addr);
+
+            //printf("Waiting for MM2S synchronization...\n");
+            //dma_mm2s_sync(dma_virtual_addr);
+
+            printf("Waiting for S2MM sychronization...\n");
+            dma_s2mm_sync(dma_virtual_addr);
+        }
+        else
+        {
+            printf("Writing MM2S transfer length of 32 bytes...\n");
+            write_dma(dma_virtual_addr, MM2S_TRNSFR_LENGTH_REGISTER, BUFF_SIZE);
+            dma_mm2s_status(dma_virtual_addr);
+
+            printf("Writing S2MM transfer length of 32 bytes...\n");
+            write_dma(dma_virtual_addr, S2MM_BUFF_LENGTH_REGISTER, BUFF_SIZE);
+            dma_s2mm_status(dma_virtual_addr);
+
+            printf("Waiting for MM2S synchronization...\n");
+            dma_mm2s_sync(dma_virtual_addr);
+
+            printf("Waiting for S2MM sychronization...\n");
+            dma_s2mm_sync(dma_virtual_addr);
+        }
+    }
+
+    
+    /* printf("Writing MM2S transfer length of 32 bytes...\n"); */
+    /* write_dma(dma_virtual_addr, MM2S_TRNSFR_LENGTH_REGISTER, BUFF_SIZE); */
+    /* dma_mm2s_status(dma_virtual_addr); */
+
+    /* printf("Writing S2MM transfer length of 32 bytes...\n"); */
+    /* write_dma(dma_virtual_addr, S2MM_BUFF_LENGTH_REGISTER, BUFF_SIZE); */
+    /* dma_s2mm_status(dma_virtual_addr); */
+
+    /* printf("Waiting for MM2S synchronization...\n"); */
+    /* dma_mm2s_sync(dma_virtual_addr); */
+
+    /* printf("Waiting for S2MM sychronization...\n"); */
+    /* dma_s2mm_sync(dma_virtual_addr); */
+
+    dma_s2mm_status(dma_virtual_addr);
+    dma_mm2s_status(dma_virtual_addr);
+
+    printf("Destination memory block: ");
+	print_mem(virtual_dst_addr, BUFF_SIZE);
+
+	printf("\n");
+
+    return 0;
+}
diff --git a/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/files/dmatest-devmem.c~ b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/files/dmatest-devmem.c~
new file mode 100644
index 0000000000000000000000000000000000000000..f76dae1d432c64ed54c8ae72a2ff09a2f0de0557
--- /dev/null
+++ b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/dmatest-devmem/files/dmatest-devmem.c~
@@ -0,0 +1,343 @@
+/*
+* Copyright (C) 2013 - 2016  Xilinx, Inc.  All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person
+* obtaining a copy of this software and associated documentation
+* files (the "Software"), to deal in the Software without restriction,
+* including without limitation the rights to use, copy, modify, merge,
+* publish, distribute, sublicense, and/or sell copies of the Software,
+* and to permit persons to whom the Software is furnished to do so,
+* subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in this
+* Software without prior written authorization from Xilinx.
+*
+*/
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <termios.h>
+#include <sys/mman.h>
+
+#define MM2S_CONTROL_REGISTER       0x00
+#define MM2S_STATUS_REGISTER        0x04
+#define MM2S_SRC_ADDRESS_REGISTER   0x18
+#define MM2S_TRNSFR_LENGTH_REGISTER 0x28
+
+#define S2MM_CONTROL_REGISTER       0x30
+#define S2MM_STATUS_REGISTER        0x34
+#define S2MM_DST_ADDRESS_REGISTER   0x48
+#define S2MM_BUFF_LENGTH_REGISTER   0x58
+
+#define IOC_IRQ_FLAG                1<<12
+#define IDLE_FLAG                   1<<1
+
+#define STATUS_HALTED               0x00000001
+#define STATUS_IDLE                 0x00000002
+#define STATUS_SG_INCLDED           0x00000008
+#define STATUS_DMA_INTERNAL_ERR     0x00000010
+#define STATUS_DMA_SLAVE_ERR        0x00000020
+#define STATUS_DMA_DECODE_ERR       0x00000040
+#define STATUS_SG_INTERNAL_ERR      0x00000100
+#define STATUS_SG_SLAVE_ERR         0x00000200
+#define STATUS_SG_DECODE_ERR        0x00000400
+#define STATUS_IOC_IRQ              0x00001000
+#define STATUS_DELAY_IRQ            0x00002000
+#define STATUS_ERR_IRQ              0x00004000
+
+#define HALT_DMA                    0x00000000
+#define RUN_DMA                     0x00000001
+#define RESET_DMA                   0x00000004
+#define ENABLE_IOC_IRQ              0x00001000
+#define ENABLE_DELAY_IRQ            0x00002000
+#define ENABLE_ERR_IRQ              0x00004000
+#define ENABLE_ALL_IRQ              0x00007000
+
+#define BUFF_SIZE                   32
+
+#define H0 0x01000002
+#define H1 0x00000001
+#define H1 0x00000800
+
+unsigned int write_dma(unsigned int *virtual_addr, int offset, unsigned int value)
+{
+    virtual_addr[offset>>2] = value;
+
+    return 0;
+}
+
+unsigned int read_dma(unsigned int *virtual_addr, int offset)
+{
+    return virtual_addr[offset>>2];
+}
+
+void dma_s2mm_status(unsigned int *virtual_addr)
+{
+    unsigned int status = read_dma(virtual_addr, S2MM_STATUS_REGISTER);
+
+    printf("Stream to memory-mapped status (0x%08x@0x%02x):", status, S2MM_STATUS_REGISTER);
+
+    if (status & STATUS_HALTED) {
+		printf(" Halted.\n");
+	} else {
+		printf(" Running.\n");
+	}
+
+    if (status & STATUS_IDLE) {
+		printf(" Idle.\n");
+	}
+
+    if (status & STATUS_SG_INCLDED) {
+		printf(" SG is included.\n");
+	}
+
+    if (status & STATUS_DMA_INTERNAL_ERR) {
+		printf(" DMA internal error.\n");
+	}
+
+    if (status & STATUS_DMA_SLAVE_ERR) {
+		printf(" DMA slave error.\n");
+	}
+
+    if (status & STATUS_DMA_DECODE_ERR) {
+		printf(" DMA decode error.\n");
+	}
+
+    if (status & STATUS_SG_INTERNAL_ERR) {
+		printf(" SG internal error.\n");
+	}
+
+    if (status & STATUS_SG_SLAVE_ERR) {
+		printf(" SG slave error.\n");
+	}
+
+    if (status & STATUS_SG_DECODE_ERR) {
+		printf(" SG decode error.\n");
+	}
+
+    if (status & STATUS_IOC_IRQ) {
+		printf(" IOC interrupt occurred.\n");
+	}
+
+    if (status & STATUS_DELAY_IRQ) {
+		printf(" Interrupt on delay occurred.\n");
+	}
+
+    if (status & STATUS_ERR_IRQ) {
+		printf(" Error interrupt occurred.\n");
+	}
+}
+
+void dma_mm2s_status(unsigned int *virtual_addr)
+{
+    unsigned int status = read_dma(virtual_addr, MM2S_STATUS_REGISTER);
+
+    printf("Memory-mapped to stream status (0x%08x@0x%02x):", status, MM2S_STATUS_REGISTER);
+
+    if (status & STATUS_HALTED) {
+		printf(" Halted.\n");
+	} else {
+		printf(" Running.\n");
+	}
+
+    if (status & STATUS_IDLE) {
+		printf(" Idle.\n");
+	}
+
+    if (status & STATUS_SG_INCLDED) {
+		printf(" SG is included.\n");
+	}
+
+    if (status & STATUS_DMA_INTERNAL_ERR) {
+		printf(" DMA internal error.\n");
+	}
+
+    if (status & STATUS_DMA_SLAVE_ERR) {
+		printf(" DMA slave error.\n");
+	}
+
+    if (status & STATUS_DMA_DECODE_ERR) {
+		printf(" DMA decode error.\n");
+	}
+
+    if (status & STATUS_SG_INTERNAL_ERR) {
+		printf(" SG internal error.\n");
+	}
+
+    if (status & STATUS_SG_SLAVE_ERR) {
+		printf(" SG slave error.\n");
+	}
+
+    if (status & STATUS_SG_DECODE_ERR) {
+		printf(" SG decode error.\n");
+	}
+
+    if (status & STATUS_IOC_IRQ) {
+		printf(" IOC interrupt occurred.\n");
+	}
+
+    if (status & STATUS_DELAY_IRQ) {
+		printf(" Interrupt on delay occurred.\n");
+	}
+
+    if (status & STATUS_ERR_IRQ) {
+		printf(" Error interrupt occurred.\n");
+	}
+}
+
+int dma_mm2s_sync(unsigned int *virtual_addr)
+{
+    unsigned int mm2s_status =  read_dma(virtual_addr, MM2S_STATUS_REGISTER);
+
+	// sit in this while loop as long as the status does not read back 0x00001002 (4098)
+	// 0x00001002 = IOC interrupt has occured and DMA is idle
+	while(!(mm2s_status & IOC_IRQ_FLAG) || !(mm2s_status & IDLE_FLAG))
+	{
+        dma_s2mm_status(virtual_addr);
+        dma_mm2s_status(virtual_addr);
+
+        mm2s_status =  read_dma(virtual_addr, MM2S_STATUS_REGISTER);
+    }
+
+	return 0;
+}
+
+int dma_s2mm_sync(unsigned int *virtual_addr)
+{
+    unsigned int s2mm_status = read_dma(virtual_addr, S2MM_STATUS_REGISTER);
+
+	// sit in this while loop as long as the status does not read back 0x00001002 (4098)
+	// 0x00001002 = IOC interrupt has occured and DMA is idle
+	while(!(s2mm_status & IOC_IRQ_FLAG) || !(s2mm_status & IDLE_FLAG))
+	{
+        dma_s2mm_status(virtual_addr);
+        dma_mm2s_status(virtual_addr);
+
+        s2mm_status = read_dma(virtual_addr, S2MM_STATUS_REGISTER);
+    }
+
+	return 0;
+}
+
+void print_mem(void *virtual_address, int byte_count)
+{
+	char *data_ptr = virtual_address;
+
+	for(int i=0;i<byte_count;i++){
+		printf("%02X", data_ptr[i]);
+
+		// print a space every 4 bytes (0 indexed)
+		if(i%4==3){
+			printf(" ");
+		}
+	}
+
+	printf("\n");
+}
+
+int main()
+{
+    printf("Hello World! - Running DMA transfer test application.\n");
+
+	printf("Opening a character device file of the Arty's DDR memeory...\n");
+	int ddr_memory = open("/dev/mem", O_RDWR | O_SYNC);
+
+	printf("Memory map the address of the DMA AXI IP via its AXI lite control interface register block.\n");
+    unsigned int *dma_virtual_addr = mmap(NULL, 65535, PROT_READ | PROT_WRITE, MAP_SHARED, ddr_memory, 0x40400000);
+
+	printf("Memory map the MM2S source address register block.\n");
+    unsigned int *virtual_src_addr  = mmap(NULL, 65535, PROT_READ | PROT_WRITE, MAP_SHARED, ddr_memory, 0x0e000000);
+
+	printf("Memory map the S2MM destination address register block.\n");
+    unsigned int *virtual_dst_addr = mmap(NULL, 65535, PROT_READ | PROT_WRITE, MAP_SHARED, ddr_memory, 0x0f000000);
+
+	printf("Writing random data to source register block...\n");
+	virtual_src_addr[0]= H1;
+	virtual_src_addr[1]= H2;
+	virtual_src_addr[2]= H3;
+	virtual_src_addr[3]= 0xCDCDCDCD;
+	virtual_src_addr[4]= 0x00001111;
+	virtual_src_addr[5]= 0x22223333;
+	virtual_src_addr[6]= 0x44445555;
+	virtual_src_addr[7]= 0x66667777;
+
+	printf("Clearing the destination register block...\n");
+    memset(virtual_dst_addr, 0, BUFF_SIZE);
+
+    printf("Source memory block data:      ");
+	print_mem(virtual_src_addr, BUFF_SIZE);
+
+    printf("Destination memory block data: ");
+	print_mem(virtual_dst_addr, BUFF_SIZE);
+
+    printf("Reset the DMA.\n");
+    write_dma(dma_virtual_addr, S2MM_CONTROL_REGISTER, RESET_DMA);
+    write_dma(dma_virtual_addr, MM2S_CONTROL_REGISTER, RESET_DMA);
+    dma_s2mm_status(dma_virtual_addr);
+    dma_mm2s_status(dma_virtual_addr);
+
+	printf("Halt the DMA.\n");
+    write_dma(dma_virtual_addr, S2MM_CONTROL_REGISTER, HALT_DMA);
+    write_dma(dma_virtual_addr, MM2S_CONTROL_REGISTER, HALT_DMA);
+    dma_s2mm_status(dma_virtual_addr);
+    dma_mm2s_status(dma_virtual_addr);
+
+	printf("Enable all interrupts.\n");
+    write_dma(dma_virtual_addr, S2MM_CONTROL_REGISTER, ENABLE_ALL_IRQ);
+    write_dma(dma_virtual_addr, MM2S_CONTROL_REGISTER, ENABLE_ALL_IRQ);
+    dma_s2mm_status(dma_virtual_addr);
+    dma_mm2s_status(dma_virtual_addr);
+
+    printf("Writing source address of the data from MM2S in DDR...\n");
+    write_dma(dma_virtual_addr, MM2S_SRC_ADDRESS_REGISTER, 0x0e000000);
+    dma_mm2s_status(dma_virtual_addr);
+
+    printf("Writing the destination address for the data from S2MM in DDR...\n");
+    write_dma(dma_virtual_addr, S2MM_DST_ADDRESS_REGISTER, 0x0f000000);
+    dma_s2mm_status(dma_virtual_addr);
+
+	printf("Run the MM2S channel.\n");
+    write_dma(dma_virtual_addr, MM2S_CONTROL_REGISTER, RUN_DMA);
+    dma_mm2s_status(dma_virtual_addr);
+
+	printf("Run the S2MM channel.\n");
+    write_dma(dma_virtual_addr, S2MM_CONTROL_REGISTER, RUN_DMA);
+    dma_s2mm_status(dma_virtual_addr);
+
+    printf("Writing MM2S transfer length of 32 bytes...\n");
+    write_dma(dma_virtual_addr, MM2S_TRNSFR_LENGTH_REGISTER, BUFF_SIZE);
+    dma_mm2s_status(dma_virtual_addr);
+
+    printf("Writing S2MM transfer length of 32 bytes...\n");
+    write_dma(dma_virtual_addr, S2MM_BUFF_LENGTH_REGISTER, BUFF_SIZE);
+    dma_s2mm_status(dma_virtual_addr);
+
+    printf("Waiting for MM2S synchronization...\n");
+    dma_mm2s_sync(dma_virtual_addr);
+
+    printf("Waiting for S2MM sychronization...\n");
+    dma_s2mm_sync(dma_virtual_addr);
+
+    dma_s2mm_status(dma_virtual_addr);
+    dma_mm2s_status(dma_virtual_addr);
+
+    printf("Destination memory block: ");
+	print_mem(virtual_dst_addr, BUFF_SIZE);
+
+	printf("\n");
+
+    return 0;
+}
diff --git a/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/libscalp/files/scalp.cc b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/libscalp/files/scalp.cc
index 296123f84992d1a76d6b513eeefdc51a1055e6e8..321a0967b7ef22c840886cb2dcdfbc3f37da0f66 100644
--- a/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/libscalp/files/scalp.cc
+++ b/scalp_fast_router_firmware_petalinux/project-spec/meta-user/recipes-apps/libscalp/files/scalp.cc
@@ -21,7 +21,7 @@ using namespace std;
 
 libscalp::uio::uio(const char *dev)
 {
-    if((_uiofd = open(dev, O_RDWR)) < 0)
+    if((_uiofd = open(dev, O_RDWR | O_SYNC)) < 0)
     {
         throw std::runtime_error("failed to open UIO device");
     }