Subj : Re: A really stupid Question - how to build a library To : borland.public.cpp.borlandcpp From : dkat Date : Thu Oct 07 2004 12:17 am "Ed Mulroy [TeamB]" wrote in message news:416472b4@newsgroups.borland.com... > I am disturbed by how much processing is in that ISR (interrupt > service routine) and how long it keeps interrupts off. I hope you are > running it on a fast machine. Machines are fast. The interrupt rate is 16K at it's fastest (16000/sec). I used to do something similar at 10K on a UNIX OS. The only code that actually takes significant time I believe is the outpw. This is standard DOS exe. Nothing happens in the ISR unless the PLAYFLAG and/or the BUTTONFLAG are true. Each is set to true then a while loop that only reads in a new buffer when the flag is triggered runs until the flags are false. BUTTONFLAG = true; PLAYFLAG = true; while(PLAYFLAG){if(READFLAG)get_next_buffer;} //tad more complex than this but not much - 2 buffers about 4096 while(counter<(MAXWAIT+numsamples) || BUTTONFLAG); BUTTONFLAG = false; It is the DAQ802 but I'm not using DMA. what we do often requires doing one sample of output at a time. > Assuming that this or something like it is what you mean by DAQ801 > http://www.shorl.com/bujujulogufa > AKA > http://www.netfusion.co.za/Network_Solutions/Quatech/products/daq801.htm > then it has several K of data buffering so you'll probably get away > with so much processing but I suggest that you think about how much of > that processing you want to do prior to re-enabling interrupts. From > a quick look at the code, it looks like you are doing things like > incrementing whole array in a loop and then using only the first two > elements in the array to develop port outputs, waiting until all that > is done before reading another port (to set PC_buttons) and then doing > another loop prior to clearing the 8259 and renabling interrupts. > > Yes of course you can put an object file containing an ISR into a > library. > > You can provide a header file which declares the needed arrays as > extern and have library code declare the instances of the arrays. In > the file containing the ISR you can use #pragma exit to register a > function also in the library which cleans up at the end should the > student forget and #pragma startup to register one that does whatever > you want to force being done prior to main being called. Just > remember to provide the functions referenced by the pragmas in object > files in the library. > > If you are going to show that code to students it might be useful to > not encourage bad habits. You might want to alter all but one of the > increments and all of the decrements to pre instead of post. Post is > expensive when used with objects and should not be allowed to be a > habit. >Similarly you might want to change the all-caps variable > names. All-caps normally are macros (and macros in that code are > all-caps). Things like that are often viewed in industry as a sign of > amateur behavior. You want your students to look good to industry. > > . Ed we are a science research lab that knows just enough about programming to get by (no one is going to see our code other than us). The all caps is from Unix days - maybe fortran - can't remember... where all caps were used for #define which is how we used to do constants (aren't you proud of me that I now use const rather than #define for my Constants :) ).... But I do want to learn what I can and very much appreciate your effort to educate. I now have to go read about #pragma, post and pre increment/decrement, figure out how to use decrement given that my mind set is to make the variable change after the fact rather than before...., etc. Thank you again. > > D Kat wrote in message > > news:41645253$1@newsgroups.borland.com... > > > > Now on to a question about ..... what can and cannot go in the lib > > file.. > > > > Where to begin. > > > > The programs written by the students opens a binary file that is > > then output to a D/A. > > > > I would like the Library to have in it the function that > > initializes the board, resets the computer vectors after the board > > is done with, etc. > > > > Ideally I would like to have the interrupt function in the library > > itself but this is going to be using the file being opened by the > > program which the student writes that uses the library... In > > addition I'm using double buffering so using a pointer in a simple > > sense won't work... Should I declare the double array FileBuffer > > that is used to be an external in the Library? I'm currently using > > a pointer that is assigned the active buffer each time an end of > > buffer is reached..... Then of course there are the counters (ticks > > for each call to the interrupt) and other variables that are needed > > by the main program. I seem to be going around in circles on this. > > > > I think I have just convinced myself that this routine cannot go > > into the library. Thoughts or advice would be appreciated. > > > > //========================================================================== > > //interrupt routine with play and button catch > > //======================================================================= > > void __interrupt i_service(...)// Daq801 interrupt service routine > > { > > disable(); // disable the interrupts > > > > int button,i; // button iterator > > unsigned char PA_buttons,PC_buttons; // temp holding register for > > current buttons > > > > inp(I_STATUS); // read the interrupt status register and clear > > interrupt > > > > for (i=0;i > { > > counter[i]++; // increment all up-counters > > if (timer[i] !=0) > > { timer[i]--;} // decrement ?32 timer array elements if not > > zero! > > } > > if (counter[0] == file_length)PLAYFLAG=0; > > if (PLAYFLAG==1) > > { > > if (counter[1] == (readlength[playndx]-1)) > > {//if at end of buffer point to next buffer > > playndx++; > > if(playndx==NUMBUF)playndx=0;//next buffer at 0 if beyond last > > buffer > > if(readlength[playndx]<2) PLAYFLAG=0;//if buffer empty - stop > > play > > else{ //else setup to play next buffer and read next buffer > > da_point = &wavebuffer[playndx][0]; //point to next buffer to > > play > > counter[1]=0;//counter for this buffer set to beginning > > READ = 1; > > }// read flag: buffer is empty -> fill buffer > > } > > outpw(DA_0,*da_point); > > outpw(DA_1,*da_point++); > > } > > if (BUTTONFLAG) > > { > > PA_buttons=(inp(PA)); // freeze data > > if (PA_buttons != MASK)// process following path only if one or > > more > > { // buttons were pressed! > > for (button=0;button > { > > if ((PA_buttons &(1< > { > > press_count++; // increment press counter > > counter_time[button]=counter[0]; // record response time > > } > > } > > } > > PC_buttons=(inp(PC)&UPPER_MASK); // freeze data & mask off upper > > buttons > > if ((PC_buttons) != UPPER_MASK)// process following path only if > > one or more > > { // buttons were pressed! > > for (button=4;button > { > > if ((PC_buttons &(1< > { > > press_count++; // increment press counter > > counter_time[button+4]=counter[0]; // record response time > > } > > } > > } > > } > > outp(0x20,EOI_IRQ3); // clear the 8259 interrupt > > enable(); // re-enable the interrupts > > } // end of interrupt service routine > > .