Threads and the Rulbus Device Library
[User Manual]

Multithreading

Because the Rulbus Device Library is used on a multitasking--multithreading operating system, attention must be given to the effects this may have. For example, it should not be possible that in one thread a Rulbus device just selected its rack, followed by a second device in another thread setting one of its registers, assuming that its rack still is selected.

The Rulbus Device Library enforces the following:

Serialized means that an operation is completed before the next operation will be allowed to commence. To this end semaphores are used.

Because of the way DLLs use memory, the following applies:

Example

The following program example shows the use of three threads, two of which control their own DAC. One thread generates a square wave voltage, the other thread generates a sawtooth voltage. Error handling has been omitted for clarity.

/*
 * threads.cpp - use Rulbus Device Library from three threads.
 *
 * compile: bcc32 threads.cpp rulbus.lib
 */

#include <conio.h>                      // for kbhit()
#include <stdio.h>                      // for fprintf(), sscanf()
#include <string.h>                     // for stricmp()
#include <windows.h>                    // for DWORD HANDLE, Sleep()

#include "rulbus.h"                     // for rb8510_dac12_open() etc.

const char *title = "Threads  1.0  use Rulbus DLL from three threads.\n";

enum { E_OK, E_OPT, E_ARG, };           // program return codes

static int           threads   ( );
static HANDLE        mkThread  ( const char *msg, DWORD WINAPI (*ThreadFunc)(LPVOID), int32 *pHandle );
static DWORD  WINAPI SquareWave( LPVOID arg );
static DWORD  WINAPI SawTooth  ( LPVOID arg );

/*
 * main - the program.
 */

int main( int argc, char *argv[] )
{
   fprintf( stdout, "%s\n", title );

   return threads();
}

/*
 * threads - create a separate thread for each of two DAC channels
 *           and generate a square wave and a sawtooth.
 *
 *      100% |--    --    --
 *           |  |  |  |  |  |
 *       50% |   --    --
 *           | /| /| /| /| /
 *        0% |/_|/_|/_|/_|/___
 */

static volatile int runthread = 1;

static int threads()
{
   rdl_printRulbusInterface();

   fprintf( stdout, "\nGenerating waveforms on DAC channels 0 & 1.\n" );

   /*
    * open two DACs:
    */

   int32 dac0, dac1;

   rb8510_dac12_open( &dac0, "dac-ch0" );
   rb8510_dac12_open( &dac1, "dac-ch1" );

   /*
    * create and resume threads:
    */

   HANDLE thread0 = mkThread( "DAC channel-0", SquareWave, &dac0 );
   HANDLE thread1 = mkThread( "DAC channel-1", SawTooth  , &dac1 );

   fprintf( stderr, "\n\nPress a key to stop...\n\n" );

   ResumeThread( thread0 );
   ResumeThread( thread1 );

   /*
    * wait for key pressed; eat character:
    */

   while (!kbhit() )
     Sleep( 10 );

   (void) getch();

   /*
    *  stop and remove threads and close DACs:
    */

   runthread = 0; Sleep( 10 );

   CloseHandle( thread0 );
   CloseHandle( thread1 );

   rb8510_dac12_close( dac1 );
   rb8510_dac12_close( dac0 );

   return E_OK;
}

/*
 * mkThread - create a thread.
 */

static HANDLE mkThread( const char *msg, DWORD WINAPI (*ThreadFunc)(LPVOID), int32 *pHandle )
{
   fprintf( stdout, "\ncreating thread for %s", msg );

   DWORD id;

   return CreateThread(
      NULL,             // pointer to thread security attributes
      0,                // initial thread stack size, in bytes
      ThreadFunc,       // pointer to thread function
      pHandle,          // argument for new thread
      CREATE_SUSPENDED, // creation flags
      &id               // pointer to returned thread identifier
   );
}

/*
 * SquareWave - generate a square wave voltage.
 */

static DWORD WINAPI SquareWave( LPVOID arg )
{
   int32 handle = *(int32 *) arg;

   fprintf( stdout, "thread function: squarewave on " ); RulbusDevice_print(handle);

   while ( runthread )
   {
      rb8510_dac12_setValue( handle, 2048 ); Sleep(50);
      rb8510_dac12_setValue( handle, 4095 ); Sleep(50);
   }

   return 0;
}

/*
 * SawTooth - generate a sawtooth voltage.
 */

static DWORD WINAPI SawTooth( LPVOID arg )
{
   int32 handle = *(int32 *) arg;

   fprintf( stdout, "thread function: sawtooth on " ); RulbusDevice_print(handle);

   while ( runthread )
   {
      for( int n = 0; n <= 2047; n = (n + 50) % 2048 )
      {
         rb8510_dac12_setValue( handle, n ); Sleep(1);
      }
   }

   return 0;
}

/*
 * End of file
 */

previous top next


Generated on Wed Apr 6 08:59:21 2005 for Rulbus Device Library for Microsoft Windows by doxygen 1.4.0