root/branches/libffado-2.0/tests/systemtests/test-isoxmit-1.cpp

Revision 1721, 8.5 kB (checked in by ppalmers, 14 years ago)

fix all format string warnings

Line 
1 /*
2  * Parts Copyright (C) 2005-2008 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 /*
25  * ISO xmit stall test
26  * This test stalls on certain controllers from a packet size = 225 on
27  *
28  * Controllers affected:
29  *  O2 Micro, Inc. Firewire (IEEE 1394) (rev 02)
30  *  Texas Instruments XIO2200(A) IEEE-1394a-2000 Controller (PHY/Link) (rev 01)
31  * not affected:
32  *  NEC Corporation uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr (rev 01)
33  *
34  * gcc -g -O2 -Wall -D_REENTRANT -std=c99 -D_GNU_SOURCE -o testxmitstall testxmitstall.c -lm -lpthread -lraw1394
35  *
36  */
37
38 /*
39  * based on howdysend.c (unknown source, maybe Maas Digital LLC)
40  */
41
42 #include <libraw1394/raw1394.h>
43 #include <stdio.h>
44 #include <string.h>
45 #include <errno.h>
46 #include <stdint.h>
47 #include <stdlib.h>
48 #include <argp.h>
49
50 #include "debugmodule/debugmodule.h"
51 #include "realtimetools.h"
52
53 #define SPEED           RAW1394_ISO_SPEED_400
54
55 uint32_t count = 0;
56
57 DECLARE_GLOBAL_DEBUG_MODULE;
58
59 #define MAX_EXTRA_ARGS 2
60 // Program documentation.
61 // Program documentation.
62 static char doc[] = "FFADO -- ISO transmit stall test\n\n";
63
64 // A description of the arguments we accept.
65 static char args_doc[] = "";
66
67 struct arguments
68 {
69     long int verbose;
70     long int port;
71     long int channel;
72     long int packetsize;
73     long int buffersize;
74     long int interval;
75     long int prebuffers;
76     long int startoncycle;
77     long int countdown;
78     long int printinterval;
79     long int rtprio;
80     char* args[MAX_EXTRA_ARGS];
81 };
82
83 // The options we understand.
84 static struct argp_option options[] = {
85     {"verbose",  'v', "level",    0,  "Verbose level" },
86     {"port",  'p', "port",  0,  "firewire port to use" },
87     {"channel",  'c', "channel",  0,  "iso channel to use" },
88     {"packetsize",  's', "packetsize",  0,  "packet size to use" },
89     {"buffersize",  'b', "buffersize",  0,  "number of packets to buffer" },
90     {"interval",  'i', "interval",  0,  "interrupt interval in packets" },
91     {"prebuffers",  'x', "packets",  0,  "number of packets to prebuffer" },
92     {"startoncycle",  't', "cycle",  0,  "start on a specific cycle" },
93     {"countdown",  'u', "count",  0,  "number of iterations to run" },
94     {"printinterval",  'r', "packets",  0,  "number of packets between successive status prints" },
95     {"rtprio",  'P', "prio",  0,  "real time priority of the iterator process/thread (0 = no RT)" },
96     { 0 }
97 };
98
99 // Parse a single option.
100 #define PARSE_ARG_LONG(XXletterXX, XXvarXX, XXdescXX) \
101     case XXletterXX: \
102         if (arg) { \
103             XXvarXX = strtol( arg, &tail, 0 ); \
104             if ( errno ) { \
105                 fprintf( stderr,  "Could not parse '%s' argument\n", XXdescXX ); \
106                 return ARGP_ERR_UNKNOWN; \
107             } \
108         } \
109         break;
110
111 static error_t
112 parse_opt( int key, char* arg, struct argp_state* state )
113 {
114     // Get the input argument from `argp_parse', which we
115     // know is a pointer to our arguments structure.
116     struct arguments* arguments = ( struct arguments* ) state->input;
117     char* tail;
118
119     errno = 0;
120     switch (key) {
121     PARSE_ARG_LONG('v', arguments->verbose, "verbose");
122     PARSE_ARG_LONG('p', arguments->port, "port");
123     PARSE_ARG_LONG('c', arguments->channel, "channel");
124     PARSE_ARG_LONG('s', arguments->packetsize, "packetsize");
125     PARSE_ARG_LONG('b', arguments->buffersize, "buffersize");
126     PARSE_ARG_LONG('i', arguments->interval, "interval");
127     PARSE_ARG_LONG('x', arguments->prebuffers, "prebuffers");
128     PARSE_ARG_LONG('t', arguments->startoncycle, "startoncycle");
129     PARSE_ARG_LONG('u', arguments->countdown, "countdown");
130     PARSE_ARG_LONG('r', arguments->printinterval, "printinterval");
131     PARSE_ARG_LONG('P', arguments->rtprio, "rtprio");
132
133     case ARGP_KEY_ARG:
134         break;
135     case ARGP_KEY_END:
136         break;
137     default:
138         return ARGP_ERR_UNKNOWN;
139     }
140     return 0;
141 }
142
143 // Our argp parser.
144 static struct argp argp = { options, parse_opt, args_doc, doc };
145
146 // the global arguments struct
147 struct arguments arguments;
148
149 int32_t last_cycle = -1;
150
151 static enum raw1394_iso_disposition myISOSender(raw1394handle_t handle,
152         unsigned char *data,
153         uint32_t *len,
154         unsigned char *tag,
155         unsigned char *sy,
156         int32_t cycle,
157         uint32_t dropped1)
158 {
159     unsigned int skipped = (dropped1 & 0xFFFF0000) >> 16;
160     unsigned int dropped = dropped1 & 0xFFFF;
161
162     //debugOutput(DEBUG_LEVEL_INFO, "In handler\n");
163     //sprintf((char *)data, "Hello World %8u\n", count);
164     if (last_cycle >= 0) {
165         if (cycle != (last_cycle + 1) % 8000) {
166             debugOutput(DEBUG_LEVEL_INFO, "nonmonotonic cycles: this: %04d, last: %04d, dropped: 0x%08X\n", cycle, last_cycle, dropped1);
167         }
168     }
169     last_cycle = cycle;
170     count++;
171     *len = arguments.packetsize;
172     *tag = 1;
173     *sy = 0;
174     if(dropped) debugOutput(DEBUG_LEVEL_INFO, "Dropped packets! (%d)\n", dropped);
175     if(skipped) debugOutput(DEBUG_LEVEL_INFO, "Skipped packets! (%d)\n", skipped);
176     if (count % arguments.printinterval == 0) debugOutput(DEBUG_LEVEL_INFO, "cycle=%d count=%d\n", cycle, count);
177     return RAW1394_ISO_OK;
178 }
179
180 void prepareXmit(raw1394handle_t handle)
181 {
182     if(raw1394_iso_xmit_init(handle,
183                 myISOSender,
184                 arguments.buffersize,
185                 arguments.packetsize,
186                 arguments.channel,
187                 SPEED,
188                 arguments.interval))
189     {
190         perror("raw1394_iso_xmit_init");
191         exit(1);
192     }
193
194     if(raw1394_iso_xmit_start(handle, arguments.startoncycle, arguments.prebuffers))
195     {
196         perror("raw1394_iso_xmit_start");
197         exit(1);
198     }
199 }
200
201 int32_t myResetHandler(raw1394handle_t handle, uint32_t generation)
202 {   
203     debugOutput(DEBUG_LEVEL_INFO, "Reset happened\n");   
204     raw1394_iso_shutdown(handle);
205     raw1394_update_generation(handle, generation);
206     prepareXmit(handle);
207     return 0;
208 }
209
210 int32_t main(int32_t argc, char **argv)
211 {
212     raw1394handle_t handle;
213
214     // Default values.
215     arguments.verbose = DEBUG_LEVEL_VERBOSE;
216     arguments.port = 0;
217     arguments.channel = 0;
218     arguments.packetsize = 1024;
219     arguments.buffersize = 100;
220     arguments.interval = -1;
221     arguments.prebuffers = 0;
222     arguments.startoncycle = -1;
223     arguments.countdown = 10000;
224     arguments.printinterval = 100;
225     arguments.rtprio = 0;
226
227     // Parse our arguments; every option seen by `parse_opt' will
228     // be reflected in `arguments'.
229     if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) {
230         debugError("Could not parse command line\n" );
231         return -1;
232     }
233
234     debugOutput(DEBUG_LEVEL_NORMAL, "verbose level = %ld\n", arguments.verbose);
235     setDebugLevel(arguments.verbose);
236
237     debugOutput(DEBUG_LEVEL_INFO, "Get 1394 handle...\n");
238     handle = raw1394_new_handle();
239     if(!handle)
240     {
241         perror("raw1394_new_handle");
242         return -1;
243     }
244
245     debugOutput(DEBUG_LEVEL_INFO, "Select 1394 port %ld...\n", arguments.port);
246     do
247     {
248         if (raw1394_get_port_info(handle, NULL, 0) < 0)
249         {
250             perror("raw1394_get_port_info");
251             return 1;
252         }
253         raw1394_set_port(handle, arguments.port );
254     } while (errno == ESTALE);
255
256     if(errno)
257     {
258         perror("raw1394_set_port");
259         return 1;
260     }
261
262     debugOutput(DEBUG_LEVEL_INFO, "Prepare/start ISO transmit...\n");
263     prepareXmit(handle);
264
265     if(raw1394_busreset_notify(handle, RAW1394_NOTIFY_ON))
266     {
267         perror("raw1394_busreset_notify");
268         exit(1);
269     }
270     raw1394_set_bus_reset_handler(handle, myResetHandler);
271
272     debugOutput(DEBUG_LEVEL_INFO, "Setting RT priority (%ld)...\n", arguments.rtprio);
273     set_realtime_priority(arguments.rtprio);
274
275     int countdown = arguments.countdown;
276     debugOutput(DEBUG_LEVEL_INFO, "Starting iterate loop...\n");
277     while(countdown--)
278     {
279         if(raw1394_loop_iterate(handle))
280         {
281             perror("raw1394_loop_iterate");
282             return 1;
283         }
284     }
285     return 0;
286 }
Note: See TracBrowser for help on using the browser.