diff options
Diffstat (limited to 'cli.c')
-rw-r--r-- | cli.c | 274 |
1 files changed, 255 insertions, 19 deletions
@@ -16,9 +16,12 @@ #include <arpa/inet.h> #include <sys/types.h> #include <dirent.h> +#include <pthread.h> #include <getopt.h> +#include "pcitool/sysinfo.h" + //#include "pci.h" #include "tools.h" #include "kernel.h" @@ -46,6 +49,11 @@ typedef uint8_t access_t; typedef enum { + GRAB_MODE_GRAB = 1, + GRAB_MODE_TRIGGER = 2 +} GRAB_MODE; + +typedef enum { MODE_INVALID, MODE_INFO, MODE_LIST, @@ -78,6 +86,19 @@ typedef enum { FLAG_WAIT = 2 } FLAGS; + +typedef enum { + FORMAT_RAW, + FORMAT_HEADER, + FORMAT_RINGFS +} FORMAT; + +typedef enum { + PARTITION_UNKNOWN, + PARTITION_RAW, + PARTITION_EXT4 +} PARTITION; + typedef enum { OPT_DEVICE = 'd', OPT_MODEL = 'm', @@ -96,6 +117,14 @@ typedef enum { OPT_HELP = 'h', OPT_RESET = 128, OPT_BENCHMARK, + OPT_TRIGGER, + OPT_DATA_TYPE, + OPT_EVENT, + OPT_TRIGGER_RATE, + OPT_TRIGGER_TIME, + OPT_RUN_TIME, + OPT_FORMAT, + OPT_BUFFER, OPT_LIST_DMA, OPT_LIST_DMA_BUFFERS, OPT_READ_DMA_BUFFER, @@ -128,6 +157,14 @@ static struct option long_options[] = { {"read", optional_argument, 0, OPT_READ }, {"write", optional_argument, 0, OPT_WRITE }, {"grab", optional_argument, 0, OPT_GRAB }, + {"trigger", optional_argument, 0, OPT_TRIGGER }, + {"data", required_argument, 0, OPT_DATA_TYPE }, + {"event", required_argument, 0, OPT_EVENT }, + {"run-time", required_argument, 0, OPT_RUN_TIME }, + {"trigger-rate", required_argument, 0, OPT_TRIGGER_RATE }, + {"trigger-time", required_argument, 0, OPT_TRIGGER_TIME }, + {"format", required_argument, 0, OPT_FORMAT }, + {"buffer", optional_argument, 0, OPT_BUFFER }, {"start-dma", required_argument, 0, OPT_START_DMA }, {"stop-dma", optional_argument, 0, OPT_STOP_DMA }, {"list-dma-engines", no_argument, 0, OPT_LIST_DMA }, @@ -168,11 +205,14 @@ void Usage(int argc, char *argv[], const char *format, ...) { " -l[l] - List (detailed) Data Banks & Registers\n" " -r <addr|reg|dmaX> - Read Data/Register\n" " -w <addr|reg|dmaX> - Write Data/Register\n" -" -g [event] - Grab Event\n" " --benchmark <barX|dmaX> - Performance Evaluation\n" " --reset - Reset board\n" " --help - Help message\n" "\n" +" Event Modes:\n" +" --trigger [event] - Trigger Events\n" +" -g [event] - Grab Events\n" +"\n" " DMA Modes:\n" " --start-dma <num>[r|w] - Start specified DMA engine\n" " --stop-dma [num[r|w]] - Stop specified engine or DMA subsystem\n" @@ -183,7 +223,7 @@ void Usage(int argc, char *argv[], const char *format, ...) { "\n" " Kernel Modes:\n" " --list-kernel-memory - List kernel buffers\n" -" --read-kernel-memory <blk> - Read the specified block of the kernel memory,\n" +" --read-kernel-memory <blk> - Read the specified block of the kernel memory\n" " block is specified as: use:block_number\n" " --free-kernel-memory <use> - Cleans lost kernel space buffers (DANGEROUS)\n" " dma - Remove all buffers allocated by DMA subsystem\n" @@ -203,6 +243,19 @@ void Usage(int argc, char *argv[], const char *format, ...) { " -o <file> - Append output to file (default: stdout)\n" " -t <timeout> - Timeout in microseconds\n" "\n" +" Event Options:\n" +" --event <evt> - Specifies event for trigger and grab modes\n" +" --data <type> - Data type to request for the events\n" +" --run-time <us> - Grab/trigger events during the specified time\n" +" --trigger-rate <tps> - Generate tps triggers per second\n" +" --trigger-time <us> - Specifies delay between triggers in microseconds\n" +" -s <num|unlimited> - Number of events to grab and trigger\n" +" --format [type] - Specifies how event data should be stored\n" +" raw - Just write all events sequentially\n" +" add_header - Prefix events with 256 bit header\n" +" ringfs - Write to RingFS\n" +" --buffer [size] - Request data buffering, size in MB\n" +"\n" " DMA Options:\n" " --multipacket - Read multiple packets\n" " --wait - Wait until data arrives\n" @@ -237,10 +290,11 @@ void Silence(const char *format, ...) { } void List(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, int details) { - int i; + int i,j; pcilib_register_bank_description_t *banks; pcilib_register_description_t *registers; pcilib_event_description_t *events; + pcilib_event_data_type_description_t *types; const pcilib_board_info_t *board_info = pcilib_get_board_info(handle); const pcilib_dma_info_t *dma_info = pcilib_get_dma_info(handle); @@ -358,7 +412,10 @@ void List(pcilib_t *handle, pcilib_model_description_t *model_info, const char * } if (bank == (char*)-1) events = NULL; - else events = model_info->events; + else { + events = model_info->events; + types = model_info->data_types; + } if (events) { printf("Events: \n"); @@ -367,6 +424,17 @@ void List(pcilib_t *handle, pcilib_model_description_t *model_info, const char * if ((events[i].description)&&(events[i].description[0])) { printf(": %s", events[i].description); } + + if (types) { + for (j = 0; types[j].name; j++) { + if (types[j].evid & events[i].evid) { + printf("\n %s", types[j].name); + if ((types[j].description)&&(types[j].description[0])) { + printf(": %s", types[j].description); + } + } + } + } } printf("\n"); } @@ -998,18 +1066,29 @@ int WriteRegister(pcilib_t *handle, pcilib_model_description_t *model_info, cons return 0; } -int Grab(pcilib_t *handle, const char *event, FILE *o) { - int err; +typedef struct { + pcilib_t *handle; + pcilib_event_t event; + pcilib_event_data_type_t data; + FILE *output; + + size_t run_time; + size_t trigger_time; - void *data = NULL; + int run_flag; +} GRABContext; + +int GrabCallback(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user) { +/* int err; + void *data; size_t size, written; - // ignoring event for now - - err = pcilib_grab(handle, PCILIB_EVENTS_ALL, &size, &data, PCILIB_TIMEOUT_TRIGGER); - if (err) { - Error("Grabbing event is failed"); - } + GRABContext *ctx = (GRABContext*)user; + pcilib_t *handle = ctx->handle; + FILE *o = ctx->output; + + data = pcilib_get_data(handle, ctx->event, ctx->data, &size); + if (!data) Error("Internal Error: No data is provided to event callback"); if (o) printf("Writting %zu bytes into file...\n", size); else o = stdout; @@ -1020,10 +1099,75 @@ int Grab(pcilib_t *handle, const char *event, FILE *o) { else Error("Write failed"); } - return 0; + pcilib_return_data(handle, ctx->event, data); +*/ + + printf("data callback: %lu\n", event_id); } +int raw_data(pcilib_event_id_t event_id, pcilib_event_info_t *info, pcilib_event_flags_t flags, size_t size, void *data, void *user) { +// printf("%i\n", event_id); +} +void *Trigger(void *user) { + GRABContext *ctx = (GRABContext*)user; + + pcilib_trigger(ctx->handle, PCILIB_EVENT0, 0, NULL); + usleep(3000); + pcilib_trigger(ctx->handle, PCILIB_EVENT0, 0, NULL); + + return NULL; +} + +int TriggerAndGrab(pcilib_t *handle, GRAB_MODE grab_mode, const char *event, const char *data_type, size_t num, size_t run_time, size_t trigger_time, PARTITION partition, FORMAT format, size_t buffer_size, FILE *ofile) { + int err; + GRABContext ctx; + void *data = NULL; + size_t size, written; + + pthread_t trigger_thread; + + ctx.handle = handle; + ctx.output = ofile; + ctx.event = PCILIB_EVENT0; + ctx.run_time = run_time; + ctx.trigger_time = trigger_time; + + ctx.run_flag = 1; + + // ignoring event for now + pcilib_configure_autostop(handle, 2, 1000000);//PCILIB_TIMEOUT_TRIGGER); + pcilib_configure_rawdata_callback(handle, &raw_data, NULL); + + err = pcilib_start(handle, PCILIB_EVENTS_ALL, PCILIB_EVENT_FLAGS_DEFAULT); + if (err) Error("Failed to start event engine, error %i", err); + + if (pthread_create(&trigger_thread, NULL, Trigger, (void*)&ctx)) + Error("Error starting trigger thread"); + +// sleep(1); + err = pcilib_stream(handle, &GrabCallback, &ctx); + if (err) Error("Error streaming events, error %i", err); + + pcilib_stop(handle, PCILIB_EVENT_FLAGS_DEFAULT); + +/* + err = pcilib_grab(handle, PCILIB_EVENTS_ALL, &size, &data, PCILIB_TIMEOUT_TRIGGER); + if (err) { + Error("Grabbing event is failed"); + } +*/ + ctx.run_flag = 0; + pthread_join(trigger_thread, NULL); + + return 0; +} + +/* +int Trigger(pcilib_t *handle, const char *event, size_t triggers, size_t run_time, size_t trigger_time) { + // +} +*/ int StartStopDMA(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_dma_engine_addr_t dma, pcilib_dma_direction_t dma_direction, int start) { int err; pcilib_dma_engine_t dmaid; @@ -1479,8 +1623,10 @@ int main(int argc, char **argv) { int i; long itmp; unsigned long utmp; + size_t ztmp; unsigned char c; + const char *stmp; const char *num_offset; int details = 0; @@ -1490,6 +1636,12 @@ int main(int argc, char **argv) { pcilib_model_t model = PCILIB_MODEL_DETECT; pcilib_model_description_t *model_info; MODE mode = MODE_INVALID; + GRAB_MODE grab_mode = 0; + size_t trigger_time = 0; + size_t run_time = 0; + size_t buffer = 0; + FORMAT format = FORMAT_RAW; + PARTITION partition = PARTITION_UNKNOWN; FLAGS flags = 0; const char *type = NULL; ACCESS_MODE amode = ACCESS_BAR; @@ -1500,6 +1652,7 @@ int main(int argc, char **argv) { const char *bank = NULL; char **data = NULL; const char *event = NULL; + const char *data_type = NULL; const char *dma_channel = NULL; const char *use = NULL; pcilib_kmem_use_t use_id; @@ -1568,11 +1721,34 @@ int main(int argc, char **argv) { else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++]; break; case OPT_GRAB: - if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); + if ((mode != MODE_INVALID)&&((mode != MODE_GRAB)||(grab_mode&GRAB_MODE_GRAB))) Usage(argc, argv, "Multiple operations are not supported"); mode = MODE_GRAB; - if (optarg) event = optarg; - else if ((optind < argc)&&(argv[optind][0] != '-')) event = argv[optind++]; + grab_mode |= GRAB_MODE_GRAB; + + stmp = NULL; + if (optarg) stmp = optarg; + else if ((optind < argc)&&(argv[optind][0] != '-')) stmp = argv[optind++]; + + if (stmp) { + if ((event)&&(strcasecmp(stmp,event))) Usage(argc, argv, "Redefinition of considered event"); + event = stmp; + } + break; + case OPT_TRIGGER: + if ((mode != MODE_INVALID)&&((mode != MODE_GRAB)||(grab_mode&GRAB_MODE_TRIGGER))) Usage(argc, argv, "Multiple operations are not supported"); + + mode = MODE_GRAB; + grab_mode |= GRAB_MODE_TRIGGER; + + stmp = NULL; + if (optarg) stmp = optarg; + else if ((optind < argc)&&(argv[optind][0] != '-')) stmp = argv[optind++]; + + if (stmp) { + if ((event)&&(strcasecmp(stmp,event))) Usage(argc, argv, "Redefinition of considered event"); + event = stmp; + } break; case OPT_LIST_DMA: if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); @@ -1708,7 +1884,11 @@ int main(int argc, char **argv) { break; case OPT_SIZE: if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &size) != 1)) - Usage(argc, argv, "Invalid size is specified (%s)", optarg); + if (strcasecmp(optarg, "unlimited")) + Usage(argc, argv, "Invalid size is specified (%s)", optarg); + else + size = (size_t)-1; + size_set = 1; break; case OPT_ENDIANESS: @@ -1733,6 +1913,47 @@ int main(int argc, char **argv) { if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &iterations) != 1)) Usage(argc, argv, "Invalid number of iterations is specified (%s)", optarg); break; + case OPT_EVENT: + event = optarg; + break; + case OPT_DATA_TYPE: + data_type = optarg; + break; + case OPT_RUN_TIME: + if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &run_time) != 1)) + Usage(argc, argv, "Invalid timeout is specified (%s)", optarg); + break; + case OPT_TRIGGER_TIME: + if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &trigger_time) != 1)) + Usage(argc, argv, "Invalid trigger-time is specified (%s)", optarg); + break; + case OPT_TRIGGER_RATE: + if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &ztmp) != 1)) + Usage(argc, argv, "Invalid trigger-rate is specified (%s)", optarg); + + trigger_time = 1000000 / ztmp + (1000000 % ztmp)?1:0; + break; + case OPT_BUFFER: + if (optarg) num_offset = optarg; + else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++]; + else num_offset = NULL; + + if (num_offset) { + if ((!isnumber(num_offset))||(sscanf(num_offset, "%zu", &buffer) != 1)) + Usage(argc, argv, "Invalid buffer size is specified (%s)", num_offset); + buffer *= 1024 * 1024; + } else { + buffer = get_free_memory(); + if (buffer < 256) Error("Not enough free memory (%lz MB) for buffering", buffer / 1024 / 1024); + + buffer -= 128 + buffer/16; + } + break; + case OPT_FORMAT: + if (!strcasecmp(optarg, "add_header")) format = FORMAT_HEADER; + else if (!strcasecmp(optarg, "ringfs")) format = FORMAT_RINGFS; + else if (strcasecmp(optarg, "raw")) Error("Invalid format (%s) is specified", optarg); + break; case OPT_QUIETE: quiete = 1; break; @@ -1869,6 +2090,21 @@ int main(int argc, char **argv) { } } } + + if (mode == MODE_GRAB) { + if (output) { + char fsname[128]; + if (!get_file_fs(output, 127, fsname)) { + if (!strcmp(fsname, "ext4")) partition = PARTITION_EXT4; + else if (!strcmp(fsname, "raw")) partition = PARTITION_RAW; + } + } + } + + if (mode != MODE_GRAB) { + if (size == (size_t)-1) + Usage(argc, argv, "Unlimited size is not supported in selected operation mode"); + } if ((bank)&&(amode == ACCESS_DMA)) { @@ -1931,7 +2167,7 @@ int main(int argc, char **argv) { pcilib_reset(handle); break; case MODE_GRAB: - Grab(handle, event, ofile); + TriggerAndGrab(handle, grab_mode, event, data_type, size, run_time, trigger_time, partition, format, buffer, ofile); break; case MODE_LIST_DMA: ListDMA(handle, fpga_device, model_info); |