Skip to content
Snippets Groups Projects
Commit 18f10c31 authored by Patrick Robbe's avatar Patrick Robbe
Browse files

Improve CRC checking in DMA test software

parent 1e2b9ecd
No related branches found
No related tags found
No related merge requests found
......@@ -41,13 +41,13 @@ PCIE40_B2LRESET_LDFLAGS = -L../Pcie40Libraries/lib -lpcie40 -L../Pcie40DriverLib
PCIE40_DMA :=pcie40_dma
PCIE40_DMA_OBJS =main_pcie40_dma.o
PCIE40_DMA_CXXFLAGS =$(CFLAGS) -I$(TOP) -I$(TOP)/../Pcie40Driver -I$(TOP)/../Pcie40Libraries
PCIE40_DMA_CXXFLAGS =$(CFLAGS) -I$(TOP) -I$(TOP)/../Pcie40Driver -I$(TOP)/../Pcie40Libraries
PCIE40_DMA_INSTALL =$(PREFIX)/bin
PCIE40_DMA_LDFLAGS = -L../Pcie40Libraries/lib -lpcie40 -L../Pcie40DriverLibraries/ -lpcie40driver_ecs
PCIE40_DMAHIGHRATE :=pcie40_dmahighrate
PCIE40_DMAHIGHRATE_OBJS =main_pcie40_dmahighrate.o
PCIE40_DMAHIGHRATE_CXXFLAGS =$(CFLAGS) -I$(TOP) -I$(TOP)/../Pcie40Driver -I$(TOP)/../Pcie40Libraries
PCIE40_DMAHIGHRATE_CXXFLAGS =$(CFLAGS) -I$(TOP) -I$(TOP)/../Pcie40Driver -I$(TOP)/../Pcie40Libraries -I/home/usr/yamadas/basf2/externals/v01-09-00/include
PCIE40_DMAHIGHRATE_INSTALL =$(PREFIX)/bin
PCIE40_DMAHIGHRATE_LDFLAGS = -L../Pcie40Libraries/lib -lpcie40 -L../Pcie40DriverLibraries/ -lpcie40driver_ecs
......
bool exit_on_error = false ;
int nTot = 1000000 ;
int nTot = 100000 ;
int max_number_of_messages = 10 ;
#define NUMBER_OF_PROCESSES 7
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
......@@ -13,6 +15,13 @@ int max_number_of_messages = 10 ;
#include <set>
#include <map>
#include <cstring>
#include <omp.h>
#include <thread>
#include <mqueue.h>
#include<sys/wait.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>
std::map< int , int > n_messages = {
{ 0 , 0 } , // no data
......@@ -34,11 +43,18 @@ std::map< int , int > n_messages = {
{ 16 , 0 } // missing links
};
extern "C" int ecs_open(int dev, int bar);
extern "C" void ecs_close(int dev, int bar);
extern "C" unsigned ecs_read(int dev, int bar, unsigned add) ;
struct shm_crc {
int cnt ;
int complete ;
int first_crc ;
int crc_data ;
unsigned int data[ 10000 ] ;
};
const int CRC16_XMODEM_TABLE[] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
......@@ -86,9 +102,9 @@ void crc_calc( unsigned int & crc, const unsigned int & data ){
crc = (((crc)<<8)&0xff00) ^ CRC16_XMODEM_TABLE[(((crc)>>8)&0xff)^byte1] ;
}
unsigned int get_crc( const std::vector< unsigned int > &data , unsigned int initial_value ) {
unsigned int get_crc( unsigned int * data , int length , unsigned int initial_value ) {
unsigned int result = initial_value ;
for( auto it = data.begin() ; it != data.end() ; ++it ) crc_calc( result , (*it) ) ;
for ( int i = 0 ; i < length ; ++i ) crc_calc( result , data[ i ] ) ;
return result ;
}
......@@ -203,7 +219,8 @@ int analyzeHeader( unsigned int * & data , unsigned int & size , double & dsize
}
int analyzeEventData( unsigned int * data , int i , unsigned int size , unsigned int &exprun , unsigned int &runnumber , unsigned int &evtnum ,
std::set< int > vlinks ) {
std::set< int > vlinks , struct shm_crc * shmp[ NUMBER_OF_PROCESSES ] ) {
int expected_number_of_links = vlinks.size() ;
// TO CHECK LATER unsigned int event_size = data[ 8 ] ;
if ( ( data[ 1 ] & 0xFFFF0000 ) != 0x7F7F0000 ) {
n_messages[ 7 ] = n_messages[ 7 ] + 1 ;
......@@ -242,17 +259,9 @@ int analyzeEventData( unsigned int * data , int i , unsigned int size , unsigned
unsigned int exp_run = data[ 2 ] ;
unsigned int crc_init = 0xFFFF ;
std::vector< unsigned int > f_crc ;
f_crc.push_back( ctime ) ;
f_crc.push_back( myevtnum ) ;
f_crc.push_back( utime ) ;
f_crc.push_back( exp_run ) ;
unsigned int first_crc = get_crc( f_crc , crc_init ) ;
std::vector< unsigned int > all_crc_data ;
all_crc_data.reserve( 48 ) ;
std::vector< std::vector< unsigned int > > data_all_crc ;
unsigned int f_crc[ 4 ] = { ctime , myevtnum , utime , exp_run } ;
unsigned int first_crc = get_crc( f_crc , 4 , crc_init ) ;
// find number of links
unsigned int numLinks = 0 ;
unsigned int linksize = data[ 8 ] & 0xFFFFFFFF ; // to be checked with Yamada-san if OK
......@@ -285,17 +294,17 @@ int analyzeEventData( unsigned int * data , int i , unsigned int size , unsigned
printf( "Bad size of data %X\n" , data[ current_event_start + linksize -1 ] ) ;
return 1 ;
}
std::vector< unsigned int > data_crc( data + current_event_start + 2 , data + current_event_start + linksize - 2 ) ;
data_all_crc.push_back( data_crc ) ;
unsigned int crc_calc = get_crc( data_crc , first_crc ) ;
// std::vector< unsigned int > data_crc( data + current_event_start + 2 , data + current_event_start + linksize - 2 ) ;
unsigned int crc_data = data[ current_event_start + linksize - 2 ] & 0xFFFF ;
all_crc_data.push_back( crc_data ) ;
if ( crc_calc != crc_data ) {
n_messages[ 15 ] = n_messages[ 15 ] + 1 ;
if ( n_messages[ 15 ] < max_number_of_messages )
printf( "CRC Error %X %X\n" , crc_calc , crc_data ) ;
return 1 ;
}
int sh_index = ( i*expected_number_of_links + numLinks ) % NUMBER_OF_PROCESSES ;
while ( shmp[ sh_index ] -> complete == 0 ) { sleep( 0 ) ; } ;
memcpy( &(shmp[ sh_index ]->data), data+current_event_start+2 , ( linksize - 4 ) * 4 ) ;
shmp[ sh_index ]->cnt = linksize-4 ;
shmp[ sh_index ]->first_crc = first_crc ;
shmp[ sh_index ]-> crc_data = crc_data ;
shmp[ sh_index ]-> complete = 0 ;
// unsigned int crc_calc = get_crc( data_crc , first_crc ) ;
numLinks++ ;
if ( ( ( data[ current_event_start + linksize ] & 0xFFFF0000 ) == 0x7FFF0000 ) ) break ;
current_event_start = current_event_start + linksize ;
......@@ -309,18 +318,6 @@ int analyzeEventData( unsigned int * data , int i , unsigned int size , unsigned
return 1 ;
}
int index = 0 ;
for( auto it = data_all_crc.begin() ; it != data_all_crc.end() ; ++it ) {
// printf( "CRC Error %X %X for link %d\n" , get_crc( (*it) , first_crc ) , all_crc_data[ index ] , index ) ;
if ( get_crc( (*it) , first_crc ) != all_crc_data[ index ] ) {
n_messages[ 15 ] = n_messages[ 15 ] + 1 ;
if ( n_messages[ 15 ] < max_number_of_messages )
printf( "CRC Error %X %X for link %d\n" , get_crc( (*it) , first_crc ) , all_crc_data[ index ] , index ) ;
return 1 ;
}
index++ ;
}
return 0 ;
}
......@@ -375,10 +372,6 @@ void analyzeEventGenerator( unsigned int * data , int i , unsigned int size ) {
// 0 = data, 1 = generator
int main (int argc ,char** argv) {
double triggerRate = 400 ; // kHz
double data_size = 0. ;
int size = 0x1F ;
bool isData = true ;
printf( "Program to read events by DMA\n" ) ;
if ( argc != 2) {
......@@ -393,6 +386,51 @@ int main (int argc ,char** argv) {
printf( "Data mode\n" ) ;
}
int shmid[ NUMBER_OF_PROCESSES ] ;
// shared memory
for ( int p = 0 ; p < NUMBER_OF_PROCESSES ; ++p ) {
shmid[ p ] = shmget( 0x1234+p , sizeof( struct shm_crc ) , 0644|IPC_CREAT ) ;
if ( shmid[ p ] == -1 ) perror( "Create shared memory" ) ;
}
for ( int p = 0 ; p < NUMBER_OF_PROCESSES ; ++p ) {
if ( 0 == fork() ) {
unsigned int data_for_crc[ 10000 ] ;
int crc_processed = 0 ;
int crc_errors = 0 ;
struct shm_crc * shmp = ( struct shm_crc * ) shmat(shmid[ p ], NULL, 0);
if (shmp == (void *) -1) perror("Shared memory attach");
printf( "Process %d\n" , p ) ;
while( true ) {
// int status = mq_receive(mqfd, (char *)&value, 8 , 0);
// if ( status == -1 ) perror("Erreur:") ;
while( shmp->complete == 1 ) { sleep( 0 ) ;} ;
crc_processed++ ;
if ( -1 == shmp -> complete ) {
printf( "End of CRC thread\n" ) ;
printf( "Number of CRC processed = %d\n" , crc_processed-1 ) ;
printf( "Number of CRC errors = %d\n" , crc_errors ) ;
exit( 0 ) ;
}
memcpy( &data_for_crc[0] , &shmp->data[0] , shmp->cnt*4 );
int size = shmp->cnt ;
unsigned int first_crc = shmp->first_crc ;
shmp->complete = 1 ;
unsigned int value = shmp->crc_data ;
if ( get_crc( data_for_crc , size , first_crc ) != value ) {
// printf( "CRC Error %X %X\n" , get_crc( data_for_crc , size , first_crc ) , value ) ;
crc_errors++ ;
}
}
}
}
double triggerRate = 400 ; // kHz
double data_size = 0. ;
int size = 0x1F ;
int res = ecs_open( 0 , 0 ) ;
if ( -1 == res ) printf("ERROR: Could not open device (BAR 0)\n") ;
else printf("SUCCESS: Device opened for ECS 0\n");
......@@ -464,6 +502,14 @@ int main (int argc ,char** argv) {
int previous_index = 0 ;
unsigned int frag_size = 0 ;
auto t1 = std::chrono::high_resolution_clock::now();
struct shm_crc * shmp[ NUMBER_OF_PROCESSES ] ;
for ( int p = 0 ; p < NUMBER_OF_PROCESSES ; ++p ) {
shmp[p] = ( struct shm_crc *) shmat(shmid[p], NULL, 0);
if ( shmp[p] == (void *) -1 ) perror( "Attach shared memory" ) ;
shmp[p] -> complete = 1 ;
}
while ( k < nTot ) {
// start DMA and wait for one or more super pages of data
rv = pcie40_dmaStart( 0 ) ;
......@@ -473,7 +519,7 @@ int main (int argc ,char** argv) {
// data = pcie40_getSuperPagePointer( 0 , ( i / S_PAGE_SLOT_NMB ) % S_PAGES , i % S_PAGE_SLOT_NMB ) ;
data = pcie40_getSuperPageCopy( 0 , ( i / S_PAGE_SLOT_NMB ) % S_PAGES , i % S_PAGE_SLOT_NMB ) ;
if ( ( i == 0 ) && ( j == 0 ) ) t1 = std::chrono::high_resolution_clock::now() ;
// printf( "Event number %d\n" , getEventNumber( data ) ) ;
if ( ! isData ) analyzeEventGenerator( data , i , size ) ;
else {
......@@ -499,7 +545,7 @@ int main (int argc ,char** argv) {
}
} else esize = frag_size ;
if ( 0 != analyzeEventData( data , k , esize , exprun , runnumber , evtnum , valid_links ) ) {
if ( 0 != analyzeEventData( data , k , esize , exprun , runnumber , evtnum , valid_links , shmp ) ) {
if ( exit_on_error ) exit( 0 ) ;
errors++ ;
}
......@@ -509,10 +555,21 @@ int main (int argc ,char** argv) {
// if ( i != getEventNumber( data ) ) printf( "Mismatch event number %d %d\n" , i , getEventNumber( data ) ) ;
++i ;
++k ;
if ( ( k % 1000 ) == 0 ) printf( "Event number %d\n" , k ) ;
if ( ( k % 1000 ) == 0 ) {
printf( "Event number %d\n" , k ) ;
}
if ( ( i > 0 ) && ( ( i % S_PAGE_SLOT_NMB ) == 0 ) ) pcie40_freeSuperPage( 0 , 1 ) ;
}
}
// unsigned int message = -1 ;
//mq_send( mqfd , (char * ) &message , 8 , 0 ) ;
for ( int p = 0 ; p < NUMBER_OF_PROCESSES ; ++p ) {
shmp[ p ] -> complete = -1 ;
}
printf( "Event number %d\n" , k ) ;
for ( int p = 0 ; p < NUMBER_OF_PROCESSES ; ++ p )
wait( 0 ) ;
auto t2 = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();
double rate = 0. ;
......@@ -524,6 +581,8 @@ int main (int argc ,char** argv) {
printf( "Errors = %d (%.2f percent)\n" , errors , 100.*( ( (double) errors ) / ( (double) nTot ) ) ) ;
//
//
for ( int p = 0 ; p < NUMBER_OF_PROCESSES ; ++p )
if ( shmctl( shmid[ p ] , IPC_RMID , 0 ) == -1 ) perror( "Delete shared memory" ) ;
ecs_close( 0 , 0 ) ;
ecs_close( 0 , 2 ) ;
dma_close( 0 ) ;
......
......@@ -2,7 +2,7 @@ BUILD_PREFIX ?=
LIBDIR_SUFFIX ?=64
FLEX ?=flex
LFLAGS ?=
CFLAGS +=-Wall -g -O3
CFLAGS +=-Wall -g -O3 -fopenmp
CXXFLAGS +=-Wall -g -O3 -fopenmp
DOCRA ?=docra
ASCIIDOCTOR ?=asciidoctor
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment