📄 asyncdem.c
字号:
/*---------------------------------------------------------------------------*/
/* */
/* FILE: asyncdem.c */
/* */
/* PURPOSE: This example illustrates how to use the Asynchronous Timer */
/* instrument driver to enable a multithreaded timer. The library */
/* alows you to create an asynchronous timer, whose callback will be*/
/* executed in its own thread. This means that the timer callback */
/* will be called no matter what the main thread of the application */
/* is doing, unlike regular UI timers. */
/* */
/* This application will spawn a timer to go off and simulate some */
/* data colection. The main UIR has a timer that will periodically */
/* monitor the data acquisition and update the UIR. You will see */
/* that, when using the async. timer, data is collected even when */
/* the main thread of the application is tied up, as in the case */
/* when you drag its window on the screen. */
/* */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Include files */
/*---------------------------------------------------------------------------*/
#include <ansi_c.h>
#include <userint.h>
#include <utility.h>
#include "asynctmr.h"
#include "asyncdem.h"
/*---------------------------------------------------------------------------*/
/* Defines */
/*---------------------------------------------------------------------------*/
#define ASYNC_TIMER 0
#define CVI_TIMER 1
#define TIME_QUEUE_SIZE 1000
#define DATA_QUEUE_SIZE 1000
/*---------------------------------------------------------------------------*/
/* Module-globals */
/*---------------------------------------------------------------------------*/
static int g_msDelay;
static int g_activeTimer = CVI_TIMER;
static int g_timerId = 0;
static int g_timerWasStopped = 0;
static int g_timerQueueHdl = 0;
static int g_dataQueueHdl = 0;
/*---------------------------------------------------------------------------*/
/* Thread-safe Module-globals */
/*---------------------------------------------------------------------------*/
DefineThreadSafeVar (int, Index);
DefineThreadSafeVar (int, TimeOfLastCall);
/*---------------------------------------------------------------------------*/
/* Internal function prototypes */
/*---------------------------------------------------------------------------*/
static int StartupTimer (int panelHandle);
static int ShutdownTimer (int panelHandle);
static int UpdateUIRWithTime (int panelHandle);
static int UpdateUIRWithData (int panelHandle);
static int DoWork (int);
int CVICALLBACK MyTimerCallback (int reserved, int theTimerId, int event,
void *callbackData, int eventData1,
int eventData2);
/*---------------------------------------------------------------------------*/
/* This is the application's entry-point. */
/*---------------------------------------------------------------------------*/
int main (int argc, char *argv[])
{
int panelHandle;
if (InitCVIRTE (0, argv, 0) == 0)
return -1;
/* Create Thread-Safe Queues to transfer data between threads */
if (CmtNewTSQ (TIME_QUEUE_SIZE, sizeof(double), OPT_TSQ_DYNAMIC_SIZE,
&g_timerQueueHdl) < 0)
return -1;
if (CmtNewTSQ (DATA_QUEUE_SIZE, sizeof(double), OPT_TSQ_DYNAMIC_SIZE,
&g_dataQueueHdl) < 0)
return -1;
/* Initialize Thread-Safe Variables */
InitializeIndex();
InitializeTimeOfLastCall();
if ((panelHandle = LoadPanel (0, "asyncdem.uir", PANEL)) < 0)
return -1;
DisplayPanel (panelHandle);
/* Tell CVI to not poll for events so often, and set up the GUI */
SetSleepPolicy (VAL_SLEEP_MORE);
GetCtrlVal (panelHandle, PANEL_DELAY, &g_msDelay);
SetAxisRange (panelHandle, PANEL_TIMESTRIPCHART, VAL_NO_CHANGE, 0.0, 1.0,
VAL_MANUAL, 0.0, (g_msDelay < 10) ? 20 : (g_msDelay*2.0));
GetCtrlVal (panelHandle, PANEL_WHICHTIMER, &g_activeTimer);
RunUserInterface ();
/* Free resources and return */
ShutdownTimer (panelHandle);
DiscardPanel (panelHandle);
UninitializeTimeOfLastCall();
UninitializeIndex();
CmtDiscardTSQ (g_timerQueueHdl);
CmtDiscardTSQ (g_dataQueueHdl);
CloseCVIRTE ();
return 0;
}
/*---------------------------------------------------------------------------*/
/* Respond to the timer Start/Stop control to start or stop the appropriate */
/* timer. */
/*---------------------------------------------------------------------------*/
int CVICALLBACK TimerStartStop (int panel, int control, int event,
void *callbackData, int eventData1,
int eventData2)
{
int startStop;
switch (event)
{
case EVENT_COMMIT:
GetCtrlVal (panel, PANEL_TIMERSTARTSTOP, &startStop);
if (startStop)
{
SetTimeOfLastCall(0);
StartupTimer (panel);
}
else
ShutdownTimer (panel);
break;
}
return 0;
}
/*---------------------------------------------------------------------------*/
/* Create and start the appropriate type of timer control. */
/*---------------------------------------------------------------------------*/
static int StartupTimer (int panelHandle)
{
int count = -1;
int enabled = 1;
/* Delete any already running timer */
ShutdownTimer (panelHandle);
/* Create the new timer */
if (g_activeTimer == CVI_TIMER)
{
g_timerId = NewCtrl (panelHandle, CTRL_TIMER, "", 0, 0);
if (g_timerId <= 0)
{
MessagePopup ("CVI Timer", "CVI timer could not be created");
g_timerId = 0;
return -1;
}
SetCtrlAttribute (panelHandle, g_timerId, ATTR_INTERVAL,
((double)g_msDelay) / 1000.0);
SetCtrlAttribute (panelHandle, g_timerId, ATTR_ENABLED, enabled);
SetCtrlAttribute (panelHandle, g_timerId,
ATTR_CALLBACK_FUNCTION_POINTER, MyTimerCallback);
SetCtrlAttribute (panelHandle, g_timerId, ATTR_CALLBACK_DATA, NULL);
}
if (g_activeTimer == ASYNC_TIMER)
{
g_timerId = NewAsyncTimer (((double)g_msDelay) / 1000.0, count,
enabled, MyTimerCallback, NULL);
if (g_timerId <= 0)
{
MessagePopup("Async Timer", "Async timer could not be created");
g_timerId = 0;
return -1;
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
/* Stop and discard active timer. */
/*---------------------------------------------------------------------------*/
static int ShutdownTimer (int panelHandle)
{
if (g_timerId > 0)
{
if (g_activeTimer == CVI_TIMER)
{
DiscardCtrl (panelHandle, g_timerId);
g_timerId = 0;
}
if (g_activeTimer == ASYNC_TIMER)
{
DiscardAsyncTimer (-1);
g_timerId = 0;
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
/* Respond to the UIR to change the current timer interval setting */
/*---------------------------------------------------------------------------*/
int CVICALLBACK ChangeDelay (int panel, int control, int event,
void *callbackData, int eventData1,
int eventData2)
{
switch (event)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -