diff options
Diffstat (limited to 'apps')
| -rw-r--r-- | apps/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | apps/lorenzo_ipedma_test.c | 658 | 
2 files changed, 0 insertions, 662 deletions
| diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index aa9f8bb..4524db4 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -10,10 +10,6 @@ link_directories(  add_executable(xilinx xilinx.c)  target_link_libraries(xilinx pcilib rt) -add_executable(lorenzo_ipedma_test lorenzo_ipedma_test.c) -target_link_libraries(lorenzo_ipedma_test pcilib rt) -set_target_properties(lorenzo_ipedma_test PROPERTIES COMPILE_FLAGS -Wno-array-bounds) -  add_executable(pio_test pio_test.c)  target_link_libraries(pio_test pcilib rt) diff --git a/apps/lorenzo_ipedma_test.c b/apps/lorenzo_ipedma_test.c deleted file mode 100644 index 2b97057..0000000 --- a/apps/lorenzo_ipedma_test.c +++ /dev/null @@ -1,658 +0,0 @@ -#define _POSIX_C_SOURCE 200809L -#define _BSD_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <stdarg.h> -#include <time.h> -#include <sched.h> -#include <sys/time.h> -#include <sys/types.h> -#include <arpa/inet.h> -#include <sched.h> -#include <errno.h> - -#include <pcilib.h> -#include <pcilib/irq.h> -#include <pcilib/kmem.h> - -//#include <sys/ipc.h> -//#include <sys/shm.h> - - -#define DEVICE "/dev/fpga0" - -#define BAR PCILIB_BAR0 -#define USE_RING PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER, 1) -#define USE PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER, 2) -//#define STATIC_REGION 0x80000000 //  to reserve 512 MB at the specified address, add "memmap=512M$2G" to kernel parameters - -#define BUFFERS         128 -#define ITERATIONS      1000 -#define DESC_THRESHOLD  BUFFERS/8   // Lorenzo: after how many desc the FPGA must update the "written descriptor counter" in PC mem -                                    // if set to 0, the update only happens when INT is received - -#define HUGE_PAGE       1           // number of pages per huge page -#define TLP_SIZE        32          // TLP SIZE = 64 for 256B payload, 32 for 128B payload -#define PAGE_SIZE       4096        // other values are not supported in the kernel - -#define USE_64                      // Lorenzo: use 64bit addressing - -//#define DUAL_CORE                 // Lorenzo: DUAL Core - -//#define SHARED_MEMORY               // Lorenzo: Test for fast GUI - -#define CHECK_READY                   // Lorenzo: Check if PCI-Express is ready by reading 0x0 -#define MEM_COPY                      // Lorenzo: CPY data -//#define CHECK_RESULTS                 // Lorenzo: Check if data received is ok (only for counter!)    -//#define CHECK_RESULTS_LOG           // Lorenzo: Check if data received is ok (only for counter!)    -#define PRINT_RESULTS                 // Lorenzo: Save the received data in "data.out" -//#define EXIT_ON_EMPTY               // Lorenzo: Exit if an "empty_detected" signal is received - -#define TIMEOUT         1000000 - - - -/* IRQs are slow for some reason. REALTIME mode is slower. Adding delays does not really help, -   otherall we have only 3 checks in average. Check ready seems to be not needed and adds quite  -   much extra time */ - -//#define USE_IRQ -//#define REALTIME -//#define ADD_DELAYS - - -#define FPGA_CLOCK 250 // Lorenzo: in MHz ! - -//#define WR(addr, value) { val = value; pcilib_write(pci, BAR, addr, sizeof(val), &val); } -//#define RD(addr, value) { pcilib_read(pci, BAR, addr, sizeof(val), &val); value = val; } -#define WR(addr, value) { *(uint32_t*)(bar + addr + offset) = value; } -#define RD(addr, value) { value = *(uint32_t*)(bar + addr + offset); } - -// ************************************************************************************** -// Progress BAR -// Process has done x out of n rounds, -// and we want a bar of width w and resolution r. -   static inline void loadBar(int x, int n, int r, int w) -   { -    // Only update r times. -    if ( x % (n/r +1) != 0 ) return; - -    // Calculuate the ratio of complete-to-incomplete. -    float ratio = x/(float)n; -    int   c     = ratio * w; - -    // Show the percentage complete. -    printf("%3d%% [", (int)(ratio*100) ); - -    // Show the load bar. -        for (x=0; x<c; x++) -           printf("="); - -       for (x=c; x<w; x++) -           printf(" "); - -    // ANSI Control codes to go back to the -    // previous line and clear it. -       printf("]\n\033[F\033[J"); -   } -// ************************************************************************************** - - -   static void fail(const char *msg, ...) { -    va_list va; - -    va_start(va, msg); -    vprintf(msg, va); -    va_end(va); -    printf("\n"); - -    exit(-1); -} - -void hpsleep(size_t ns) { -    struct timespec wait, tv; - -    clock_gettime(CLOCK_REALTIME, &wait); - -    wait.tv_nsec += ns; -    if (wait.tv_nsec > 999999999) { -        wait.tv_sec += 1; -        wait.tv_nsec = 1000000000 - wait.tv_nsec; -    } - -    do { -        clock_gettime(CLOCK_REALTIME, &tv); -    } while ((wait.tv_sec > tv.tv_sec)||((wait.tv_sec == tv.tv_sec)&&(wait.tv_nsec > tv.tv_nsec))); -} - - -// ************************************************************************************** -int main() { - - - -    int err; -    long i, j; -    pcilib_t *pci; -    pcilib_kmem_handle_t *kdesc; -    pcilib_kmem_handle_t *kbuf; -    struct timeval start, end; -    size_t run_time; -    long long int size_mb; -    void* volatile bar; -    uintptr_t bus_addr[BUFFERS]; -    uintptr_t kdesc_bus; -    volatile uint32_t *desc; -    typedef volatile uint32_t *Tbuf; -    Tbuf ptr[BUFFERS]; - -#ifdef SWITCH_GENERATOR -    int switch_generator = 0; -#endif /* SWITCH_GENERATOR */ -#if defined(CHECK_RESULTS)||defined(CHECK_RESULTS_LOG) -    long k; -    int mem_diff; -#endif /* CHECK_RESULTS */ - -    -    float performance, perf_counter;  -    pcilib_bar_t bar_tmp = BAR;  -    uintptr_t offset = 0; - -    unsigned int temp; -    int iterations_completed, buffers_filled; - - -//    int shmid; -     - -    printf("\n\n**** **** **** KIT-DMA TEST **** **** ****\n\n"); - -    //size = ITERATIONS * BUFFERS * HUGE_PAGE * PAGE_SIZE; -    size_mb = ITERATIONS * BUFFERS * HUGE_PAGE * 4 / 1024; -    printf("Total size of memory buffer: \t %.3lf GBytes\n", (float)size_mb/1024 ); -    printf("Using %d Buffers with %d iterations\n\n", BUFFERS, ITERATIONS ); - -#ifdef ADD_DELAYS -    long rpt = 0, rpt2 = 0; -    size_t best_time; -    best_time = 1000000000L * HUGE_PAGE * PAGE_SIZE / (4L * 1024 * 1024 * 1024); -#endif /* ADD_DELAYS */ - - -    pcilib_kmem_flags_t flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE/*|PCILIB_KMEM_FLAG_REUSE*/; // Lorenzo: if REUSE = 1, the re-allocation fails! -    pcilib_kmem_flags_t free_flags = PCILIB_KMEM_FLAG_HARDWARE/*|PCILIB_KMEM_FLAG_EXCLUSIVE|PCILIB_KMEM_FLAG_REUSE*/; -    pcilib_kmem_flags_t clean_flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE; - -    pci = pcilib_open(DEVICE, "pci"); -    if (!pci) fail("pcilib_open"); - -    bar = pcilib_map_bar(pci, BAR); -    if (!bar) { -        pcilib_close(pci); -        fail("map bar"); -    } - -    pcilib_detect_address(pci, &bar_tmp, &offset, 1); - -    pcilib_enable_irq(pci, PCILIB_IRQ_TYPE_ALL, 0); -    pcilib_clear_irq(pci, PCILIB_IRQ_SOURCE_DEFAULT); - -    pcilib_clean_kernel_memory(pci, USE, clean_flags); -    pcilib_clean_kernel_memory(pci, USE_RING, clean_flags); - -    kdesc = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_CONSISTENT, 1, 128, 4096, USE_RING, flags); -    kdesc_bus = pcilib_kmem_get_block_ba(pci, kdesc, 0); -    desc = (uint32_t*)pcilib_kmem_get_block_ua(pci, kdesc, 0); -    memset((void*)desc, 0, 5*sizeof(uint32_t)); - -#ifdef REALTIME -    pid_t pid; -    struct sched_param sched = {0}; - -    pid = getpid(); -    sched.sched_priority = sched_get_priority_min(SCHED_FIFO); -    if (sched_setscheduler(pid, SCHED_FIFO, &sched)) -        printf("Warning: not able to get real-time priority\n"); -#endif /* REALTIME */ - -    // ****************************************************************** -    // ****      MEM: check 4k boundary                             *****  -    // ****************************************************************** - -    do  { -        printf("* Allocating KMem, "); -#ifdef STATIC_REGION -        kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_REGION_C2S, BUFFERS, HUGE_PAGE * PAGE_SIZE, STATIC_REGION, USE, flags); -#else -        kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, BUFFERS, HUGE_PAGE * PAGE_SIZE, 4096, USE, flags); -#endif - -        if (!kbuf) { -            printf("KMem allocation failed\n"); -            exit(0); -        } - -        // Pointers for Virtualized Mem -        for (j = 0; j < BUFFERS; j++) { -            ptr[j] = (volatile uint32_t*)pcilib_kmem_get_block_ua(pci, kbuf, j); -            memset((void*)(ptr[j]), 0, HUGE_PAGE * PAGE_SIZE); -        } - -        err = 0; - -        // Check if HW addresses satisfy 4k boundary condition, if not -> free (!!) and reallocate memory -        printf("4k boundary test: "); -        for (j = 0; j < BUFFERS; j++) { -            temp = (((unsigned int)pcilib_kmem_get_block_ba(pci, kbuf, j)) % 4096); -            //printf("%u", temp); -            if (temp  != 0) { -                err = 1; -            } -        } -        if (err == 1) { -            pcilib_clean_kernel_memory(pci, USE, clean_flags); -            pcilib_clean_kernel_memory(pci, USE_RING, clean_flags); -            pcilib_free_kernel_memory(pci, kbuf,  free_flags); -            printf("failed \xE2\x9C\x98\n"); -        } -        else printf("passed \xE2\x9C\x93\n"); - -    } while (err == 1); - - -    // ****************************************************************** -    // ****      Allocate RAM buffer Memory                         *****  -    // ****************************************************************** -     -    FILE * Output; -    FILE * error_log; - -#ifdef MEM_COPY - -    uint32_t *temp_data[ITERATIONS][BUFFERS]; - -    for (j=0; j < ITERATIONS; j++) { -        for (i=0; i < BUFFERS; i++) { -            temp_data[j][i] = (uint32_t *)malloc(HUGE_PAGE*PAGE_SIZE); -            if (temp_data[j][i] == 0) { -                printf("******* Error: could not allocate memory! ********\n"); -                exit(0); -            } -            memset((void*)(temp_data[j][i]), 0, HUGE_PAGE * PAGE_SIZE); -        } -    } -#endif - -#ifdef SHARED_MEMORY -    // give your shared memory an id, anything will do -    key_t key = 123456; -    char *shared_memory; - -    // Setup shared memory, 11 is the size -/*    if ((shmid = shmget(key, HUGE_PAGE*PAGE_SIZE, IPC_CREAT | 0666)) < 0) -    { -      printf("Error getting shared memory id"); -      exit(1); -    } - -    // Attached shared memory -    if ((shared_memory = shmat(shmid, NULL, 0)) == (char *) -1) -    { -      printf("Error attaching shared memory id"); -      exit(1); -    } -    printf("* Shared memory created... Id:\t %d\n", key); -    //////////////// SHARED MEMORY TEST */ -#endif - -    Output = fopen ("data.out", "w"); -    fclose(Output); - -    error_log = fopen ("error_log.txt", "w"); -    fclose(error_log); -    -    // ****************************************************************** -    // ****      PCIe TEST                                          *****  -    // ****************************************************************** - -    // Reset DMA -    printf("* DMA: Reset...\n"); -    WR(0x00, 0x1); -    usleep(100000); -    WR(0x00, 0x0); -    usleep(100000); -  -#ifdef CHECK_READY        -    printf("* PCIe: Testing..."); -    RD(0x0, err); -    if (err == 335746816 || err == 335681280) { -        printf("\xE2\x9C\x93 \n"); -    } else { -        printf("\xE2\x9C\x98\n PCIe not ready!\n"); -        exit(0); -    } -#endif -     - -    // ****************************************************************** -    // ****      DMA CONFIGURATION                                  *****  -    // ****************************************************************** - -    printf("* DMA: Send Data Amount\n"); -#ifdef DUAL_CORE -    WR(0x10, (HUGE_PAGE * (PAGE_SIZE / (4 * TLP_SIZE)))/2); -#else   -    WR(0x10, (HUGE_PAGE * (PAGE_SIZE / (4 * TLP_SIZE)))); -#endif    - -    printf("* DMA: Running mode: "); - -#ifdef USE_64    -    if (TLP_SIZE == 64)  -    { -        WR(0x0C, 0x80040); -        printf ("64bit - 256B Payload\n"); -    } -    else if (TLP_SIZE == 32)  -    { -        WR(0x0C, 0x80020); -        printf ("64bit - 128B Payload\n"); -    } -#else   -    if (TLP_SIZE == 64)  -    { -        WR(0x0C, 0x0040); -        printf ("32bit - 256B Payload\n"); -    } -    else if (TLP_SIZE == 32)  -    { -        WR(0x0C, 0x0020); -        printf ("32bit - 128B Payload\n"); -    } -#endif - -    printf("* DMA: Reset Desc Memory...\n"); -    WR(0x5C, 0x00); // RST Desc Memory - -    printf("Writing SW Read Descriptor\n"); -    WR(0x58, BUFFERS-1); -    //WR(0x58, 0x01); - -    printf("Writing the Descriptor Threshold\n"); -    WR(0x60, DESC_THRESHOLD); - -    printf("Writing HW write Descriptor Address: %lx\n", kdesc_bus); -    WR(0x54, kdesc_bus); -    usleep(100000); - -    printf("* DMA: Writing Descriptors\n"); -    for (j = 0; j < BUFFERS; j++ ) { -        bus_addr[j] = pcilib_kmem_get_block_ba(pci, kbuf, j); -        // LEAVE THIS DELAY???!?!?!?! -        usleep(1000); -        //printf("Writing descriptor num. %ld: \t %08lx \n", j, bus_addr[j]); -        WR(0x50, bus_addr[j]); -    } - -    // ****************************************************************** -    // ****     START DMA                                           ***** -    // ****************************************************************** - -    //printf ("\n ---- Press ENTER to start DMA ---- \n"); -    //getchar(); - -    printf("* DMA: Start \n"); -    WR(0x04, 0x1); -    gettimeofday(&start, NULL); - -    // ****************************************************************** -    // ****     Handshaking DMA                                     ***** -    // ****************************************************************** - -    uint32_t curptr = 0, hwptr; -    uint32_t curbuf = 0; -    int empty = 0; -    i = 0; - - -    while (i < ITERATIONS) { -        j = 0; -        //printf("\ndesc0: %lx", desc[0]);  -        //printf("\ndesc1: %lx", desc[1]);  -        //printf("\ndesc2: %lx", desc[2]);  -        //printf("\ndesc3: %lx", desc[3]);  -        //printf("\ndesc4: %lx", desc[4]); -        // printf("\ndesc5: %lx", htonl(desc[5])); -        //printf("Iteration: %li of %li \r", i+1, ITERATIONS);  -        //getchar(); -        //loadBar(i+1, ITERATIONS, ITERATIONS, 30); -        // printf("\nhwptr: %zu", hwptr);   -        // printf("\ncurptr: %zu", curptr);  - -        do { -#ifdef USE_64    -                hwptr = desc[3]; -#else // 32-bit -                hwptr = desc[4]; -#endif -        j++;     -        //printf("\rcurptr: %lx \t \t hwptr: %lx", curptr, hwptr); -        } while (hwptr == curptr); - -        do {     -            pcilib_kmem_sync_block(pci, kbuf, PCILIB_KMEM_SYNC_FROMDEVICE, curbuf); -#ifdef MEM_COPY    -            memcpy(temp_data[i][curbuf], (void*)ptr[curbuf], 4096); -#endif -#ifdef CHECK_RESULTS -for (k = 0; k < 1024 ; k++)  -            { -                mem_diff = (ptr[curbuf][k] - ptr[curbuf][k]); -                //if ((mem_diff == 1) || (mem_diff == (-7)) || (k == 1023) )  -                if (mem_diff == -1) -                    {;} -                else { -                    //fprintf(error_log, "Error in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", i, j, k, temp_data[i][j][k], temp_data[i][j][k+1], mem_diff); -                    err++; -                } -            } -#endif -#ifdef SHARED_MEMORY -            memcpy(shared_memory, ptr[curbuf], 4096);  -#endif             -            //printf("\ncurbuf: %08x", curbuf);  -            //printf("\nbus_addr[curbuf]\n: %08x",bus_addr[curbuf]); -            // for (k = 0; k < 63; k++){ -            // if (k%16 == 0) printf("\n# %d # :", k); -            // printf(" %08x", ptr[curbuf][k]); -            // } -            //pcilib_kmem_sync_block(pci, kbuf, PCILIB_KMEM_SYNC_TODEVICE, curbuf); -            curbuf++; -            if (curbuf == BUFFERS) { -                i++; -                curbuf = 0; -#ifdef SWITCH_GENERATOR                  -                if (switch_generator == 1) { -                    switch_generator = 0; -                    WR(0x9040, 0x100007F0); -                } else { -                    WR(0x9040, 0x180007F0); -                    switch_generator = 1; -                } -#endif -                if (i >= ITERATIONS) break; -                //if (i >= (ITERATIONS - 4) ) WR(0x04, 0x0f);  -            } -        } while (bus_addr[curbuf] != hwptr); - -#ifdef EXIT_ON_EMPTY -#ifdef USE_64                  -        if (desc[1] != 0)  -#else // 32bit   -        if (desc[2] != 0)   -#endif                                  -        { -            if (bus_addr[curbuf] == hwptr) { -                empty = 1; -                break; -            } -        } -#endif   - -        WR(0x58, curbuf + 1);  -        //printf("WR %d\n", curbuf + 1);  -        //printf("%u (%lu)\n", curbuf, j); -        curptr = hwptr; -    } - - -    // ****************************************************************** -    // **** Read performance and stop DMA                         ******* -    // ****************************************************************** - -    gettimeofday(&end, NULL); -    WR(0x04, 0x00); -    usleep(100); -    RD(0x28, perf_counter); -    usleep(100); -    WR(0x00, 0x01); - - - - -    iterations_completed   = i; -    buffers_filled      = curbuf; -    if (empty) printf("* DMA: Empty FIFO! Last iteration: %li of %i\n", i+1, ITERATIONS); -    printf ("* DMA: Stop\n\n"); - -#ifdef MEM_COPY -    printf ("First value:\t %08x\n", temp_data[0][0][0]); -    printf ("Last value:\t %08x\n\n", temp_data[ITERATIONS-1][BUFFERS-1][(PAGE_SIZE/4)-4]); -#endif -     -    // ****************************************************************** -    // **** Performance                                           ******* -    // ****************************************************************** -    printf("Iterations done: %d\n", iterations_completed); -    printf("Buffers filled on last iteration: %d\n", buffers_filled); - - -    run_time = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec); -    //size = (long long int) (( BUFFERS * (iterations_completed)  + buffers_filled) * HUGE_PAGE * PAGE_SIZE); -    size_mb = (long long int) (( BUFFERS * (iterations_completed)  + buffers_filled) * HUGE_PAGE * 4 / 1024); -    printf("Performance: transfered %llu Mbytes in %zu us using %d buffers\n", (size_mb), run_time, BUFFERS); -    //printf("Buffers: \t %d \n", BUFFERS); -    //printf("Buf_Size: \t %d \n", PAGE_SIZE); -    //printf("Perf_counter: \t %f \n", perf_counter); -    performance = ((size_mb * FPGA_CLOCK * 1000000)/(perf_counter*256)); -    printf("DMA perf counter:\t%d\n", (int)perf_counter);  -    printf("DMA side:\t\t%.3lf MB/s\n", performance);   -    printf("PC side:\t\t%.3lf MB/s\n\n", 1000000. * size_mb / run_time ); - -    // ****************************************************************** -    // **** Read Data                                             ******* -    // ****************************************************************** - - -    #ifdef PRINT_RESULTS -    printf("Writing Data to HDD... \n"); -    for (i=0; i < iterations_completed; i++) { -        for (j=0; j < BUFFERS; j++) -        { -            Output = fopen("data.out", "a"); -            fwrite(temp_data[i][j], 4096, 1, Output); -            fclose(Output); -        }    -        loadBar(i+1, ITERATIONS, ITERATIONS, 30); -    } -    // Save last partially filled iteration -    for (j=0; j < buffers_filled; j++) -    { -        Output = fopen("data.out", "a"); -        fwrite(temp_data[iterations_completed][j], 4096, 1, Output); -        fclose(Output); -    }    -    printf("Data saved in data.out. \n"); -    #endif - -   #ifdef CHECK_RESULTS_LOG -    err = 0; -    error_log = fopen ("error_log.txt", "a"); -    printf("\nChecking data ...\n"); -    for (i=0; i < iterations_completed; i++) { -        for (j = 0; j < BUFFERS; j++) { -            for (k = 0; k < 1024 ; k++)  -            { -                mem_diff = ((uint32_t)temp_data[i][j][k] - (uint32_t)temp_data[i][j][k+1]); -                //if ((mem_diff == 1) || (mem_diff == (-7)) || (k == 1023) )  -                if ((mem_diff == -1) || (k == 1023) )  -                    {;} -                else { -                    fprintf(error_log, "Error in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", i, j, k, temp_data[i][j][k], temp_data[i][j][k+1], mem_diff); -                    err++; -                } -            } -            if (j != BUFFERS-1) { -            // Check first and Last -                mem_diff = (uint32_t)(temp_data[i][j+1][0] - temp_data[i][j][1023]); -                if (mem_diff == (1))  -                    {;} -                else { -                    fprintf(error_log, "Error_2 in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", i, j, k, temp_data[i][j+1][0], temp_data[i][j][1023], mem_diff); -                    err++; -                } -            } - -        } -        loadBar(i+1, ITERATIONS, ITERATIONS, 30); -    } -    for (j = 0; j < buffers_filled; j++) { -        for (k = 0; k < 1024 ; k++)  -        { -            mem_diff = ((uint32_t)temp_data[iterations_completed][j][k] - (uint32_t)temp_data[iterations_completed][j][k+1]); -                if ((mem_diff == -1) || (k == 1023) )  -                {;} -            else { -                fprintf(error_log, "Error in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", iterations_completed, j, k, temp_data[iterations_completed][j][k], temp_data[iterations_completed][j][k+1], mem_diff); -                err++; -            } -        } -        if (j != buffers_filled-1) { -        // Check first and Last -            mem_diff = (uint32_t)(temp_data[i][j+1][0] - temp_data[i][j][1023]); -            if (mem_diff == (1))  -                {;} -            else { -                fprintf(error_log, "Error_2 in: \t IT %li \t BUF : %li \t OFFSET: %li \t | %08x --> %08x - DIFF: %d \n", iterations_completed, j, k, temp_data[iterations_completed][j+1][0], temp_data[iterations_completed][j][1023], mem_diff); -                err++; -            } -        } -    } -    if (err != 0) printf("\rChecking data: \xE2\x9C\x98 %d errors found  \n See \"error_log.txt\" for details \n\n", err); -    else printf("\rChecking data: \xE2\x9C\x93 no errors found  \n\n"); -    fclose(error_log); -    #endif - -    // *********** Free Memory -#ifdef MEM_COPY -    for (i=0; i < ITERATIONS; i++) { -        for (j=0; j < BUFFERS; j++) -        { -            free(temp_data[i][j]); -        } -    } -#endif - -    pcilib_free_kernel_memory(pci, kbuf,  free_flags); -    pcilib_free_kernel_memory(pci, kdesc,  free_flags); -    pcilib_disable_irq(pci, 0); -    pcilib_unmap_bar(pci, BAR, bar); -    pcilib_close(pci); - -//    shmdt(shmid); -//    shmctl(shmid, IPC_RMID, NULL); - -} | 
