LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

How to detect we are in the first execution of a timer?

My program has a timer that executes repetitive activities. I need to detect the first time timer callback is executed to initialize some local variables and perform some task I cannot do elsewhere.

One possibility is to look at the eventData2 parameter of the function: if this is 0 then I'm in the first execution of the routine:
if (*(double *)eventData2 == 0.0) {
// Instructions for the first execution
}

Another possibility is to use a static variable set to 0 in the declaration and raised to 1 every time I am in the timer callback. If this variable is 0 then I am in the first execution of the callback.

I used the first solution which was always satisfactory in my tests in the IDE and in compiled executa
ble, but now my customer is blaming me for some strange behaviour that seems to be connected to unsuccesful environment initialization.

Has anyone found some problems in a situation similar to mine? Or can someone suggest me a securer way to initialize my environment?

Thanks for your help.
Roberto


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 1 of 4
(3,492 Views)
Roberto,
give that your solution seems to be the best you could use, what do you mean when you say "..my customer is blaming me for some strange behaviour that seems to be connected to unsuccesful environment initialization..".
Is the customer receiving errors in his application? what kind of problem is he experiencing?

AlessioD
National Instruments
0 Kudos
Message 2 of 4
(3,492 Views)
Dear Alessio
the situation I was referring to was an unsuccesful update of a remote file on the plant network to which my equipment is connected. I finally succeeded to get in touch with the system administrator of my customer and after reviewing (and renewing) all authorizations and objects rights the application turned to work well again.

I was erroneously thinking of an error in the software since the application doesn't report any error in accessing the file on the network, but indeed the problem was there and not in the software (in my laboratory all the application always worked well).

Here is a skeleton of my code: I don't know why I had no error in accessing the network. Have you some idea? There is some known reason why the access to the file could be unsuccesful without reporting an error? (BTW this caused some difficulty to me in convincing my customer to operate on HIS network instead of my application...)

//---------------------------------------------------
int UpdateStatusOnServer (void)

{
int i, line, error = 0;
char file[MAX_PATHNAME_LEN];
FILE *fh = NULL;

errno = 0;

// Remote file to open
sprintf (file, "\134\134%s\134%s\134formazione.369", r.IPaddr, r.path);
fh = fopen (file, "rb+");
if (errno) { line = __LINE__; goto Error; }

//-----------------------------------------------------------------
// Time of update
//-----------------------------------------------------------------
fwrite (TimeStr (), 8, 1, fh);
if (errno) { line = __LINE__; goto Error; }

//-----------------------------------------------------------------
// Some data
//-----------------------------------------------------------------
// Seek the right position and write the file
fseek (fh, 101, SEEK_SET);
if (errno) { line = __LINE__; goto Error; }
fwrite ((char *)sa.s, sizeof(aspiratori), 5, fh);
if (errno) { line = __LINE__; goto Error; }

//-----------------------------------------------------------------
// Othe data written the same way
//-----------------------------------------------------------------
fseek (fh, 1000, SEEK_SET);
fwrite (string, strlen (string), 1, fh);
if (errno) { line = __LINE__; goto Error; }

//-----------------------------------------------------------------
// Close file
//-----------------------------------------------------------------
fclose(fh); fh = NULL;
if (errno) { line = __LINE__; goto Error; }

Error:
/*
Platform-specific values put in errno by the O.S.

EACCES - Access denied.
+ Attempt to write to read-only file.
+ Attempt to open a directory.
+ Attempt to write to CD-ROM.
+ Network file requires a password.
+ Sharing is denied by another application.
+ Attempt to remove a nonempty directory.
+ Attempt to rename file across drives.

EBADF - Invalid file handle.
+ File was closed using close() or CloseFile()
instead of fclose().
+ Attempt to seek or get file position on a nonseeking
device.

EEXIST - File exists.
+ Attempt to rename a file to one that already exists.

EIO - General I/O error.
+ Attempt to access an unformatted floppy disk.
+ Attempt to access media that has been removed (floppy
disk or CD-ROM).
+ Unknown error.

EMFILE - Too many open files.
+ Attempt to open a file when system imposed limit of
open files has been reached.

ENAMETOOLONG - Path name too long.

ENOENT - Invalid path.
+ One of the directories in the path does not exist.
+ Path contains invalid characters.

ENOMEM - Insufficient memory.

ENOSPC - Disk is full.


For EACCES, EBADF, EIO, ENOENT, and ENOSPC you can call the
Windows/SDK GetLastError function to obtain system-specific
error information.
*/
if (errno) { // ERROR IN ACCESSING THE SERVER
r.err = 1; r.errID = errno; r.line = line;
switch (errno) {
case EACCES: // Access denied.
strcpy (r.errMsg, "Access denied.");
break;
case EBADF: // Invalid file handle.
strcpy (r.errMsg, "Invalid file handle.");
break;
case EEXIST: // File exists.
strcpy (r.errMsg, "File already exists.");
break;
case EIO: // General I/O error.
strcpy (r.errMsg, "General I/O error.");
break;
case EMFILE: // Too many open files.
strcpy (r.errMsg, "Too meny open file.");
break;
case ENAMETOOLONG: // Path name too long.
strcpy (r.errMsg, "Path name too long.");
break;
case ENOENT: // Invalid path.
strcpy (r.errMsg, "Invalid path.");
break;
case ENOMEM: // Insufficient memory.
strcpy (r.errMsg, "Insufficient memory.");
break;
case ENOSPC: // Disk is full.
strcpy (r.errMsg, "Disk is full.");
break;
}
}
else { // Trasmissione riuscita: azzera flag errore
r.err = 0; r.errID = 0; r.line = 0;
strcpy (r.errMsg, "No error");
}
if (fh) fclose (fh);
// Output some detail on monitoring panel
if (monH) {
SetCtrlVal (monH, mon_file, file);
SetCtrlVal (monH, mon_errno, r.errID);
SetCtrlVal (monH, mon_line, r.line);
ResetTextBox (monH, mon_errmsg, r.errMsg);
}

return 0;


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 3 of 4
(3,492 Views)
If there is no error in accessing the file on the network, the network file should contain your updated output. You should also be able to see the file and access it from the Explorer from the Target Machine.

There's not much that could get past the error switch statement but you might want to add a 'default' case for any unknown error codes.
Another way of catching things is changing the error checking from "if(errno)" to "if(errno || !fh)" just in case your not getting the error from the system but the file pointer is not assigned.

Good luck
0 Kudos
Message 4 of 4
(3,492 Views)