Jump to content
  • Advertisement
Sign in to follow this  
PeteGallo

run a second program in a project?

This topic is 4841 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hi i have the following file cantest.c in my project and it compiles and runs fine. how do i go about running a second file esd_example.c? should i not call int main()? should i call the program esd_example.c to run from cantes.c? cantest.c:
/************************************************************************/
/*                                                                      */
/*   Test/Demonstation program for CAN driver with NT-CAN-API           */
/*                                                                      */
/*          Copyright 1997-2002 esd - electronic system design gmbh     */
/*----------------------------------------------------------------------*/
/*                                                                      */
/*      Filename:      cantest.c                                        */
/*      Date:          09.11.99                                         */
/*      Language:      ANSI C                                           */
/*      Targetsystem:  Win NT, Win 9x, Win CE, QNX, UNIX, VxWorks       */
/*                     Linux-RTAI                                       */
/*                                                                      */
/*      Purpose:       Test and demonstration for drivers which support */
/*                     NT-CAN API                                       */
/*----------------------------------------------------------------------*/
/* Revision history:                                                    */
/*----------------------------------------------------------------------*/
/* 261,16mar02,ot  * Added support for RTX (define UNDER_RTSS)          */
/*                 * Added support for time unit in duration output     */
/* 260,05Nov01,mt  * Added test 22 Object mode                          */
/* 257,10may01,ot  * If possible use performance counter for Win32      */
/*                 *  instead of GetTickCount() to have a more accurate */
/*                 *  timing                                            */
/* 256,27feb01,fj  * Added start_rt_timer() and stop_rt_timer() for     */
/*                   rtai-version                                       */
/* 255,05feb01,fj  * Added support for rtlinux-3.0                      */
/* 254,06jul00,ot  * Display feature flags of each interface            */
/*                 * Added new error codes from NTCAN for Win32         */
/* 253,06jul00,ot  * Caller priority check for Vxworks (not used yet)   */
/* 252,05jul00,fj  * rtai: added kernel module parameter infifo and     */
/*                 *       outfifo. printf() now via /dev/rtfx, with    */
/*                 *       x=outfifo (printf() no longer via printk()   */
/*                 *       to syslog). If not specified, infifo defaults*/
/*                 *       to 0 and outfifo defaults to 1.              */
/* 251,27jun00,sr  * some // comments removed for vxworks               */
/* 250,09jun00,fj  * support for linux-rtai                             */
/* 249,17apr00,sr  * rtos-uh-support included                           */
/* 248,13jan00,mt  * rmos-support included                              */
/* 247,05jan00,ot  * Fixed bug in previous version that idend is set to */
/*                 *  idstart                                           */
/* 246,16dec99,ot  * Using strtol() instead of atoi() to parse baudrate */
/*                 *  and CAN-IDs to support hex and oct values         */
/*                 * Changes in value display for baudrate and idf      */
/* 245,01dec99,mt  * Test 19                                            */
/* 244,09nov99,mt  * canGetBaudrate                                     */
/* 243,20may99,ot  * Removed test 13 from D3X version                   */
/*                 * Return immediatelly if test is undefined           */
/*                 * Special test 6 for async I/O using signal handler  */
/*                 *  and poll for Solaris (D3X) version                */
/* 242,17may99,mt  * decimal netnumbers in help()                       */
/* 241,03may99,ot  * Windows CE support included (no test 6 and 7)      */
/*                 * Changed GET_CURRENT_TIME macro from WIN32 API call */
/*                 *  GetCurrentTime() to GetTickCount() as only the    */
/*                 *  latter is present in Windows CE                   */
/* 240,19mar99,mt  * Test 7 added                                       */
/* 230,19mar99,ot  * Support for VxWorks included                       */
/*                 * Minor changes to prevent GCC compiler warnings     */
/*                 * Replaced GetCurrentTime() call in Rev 2.2.1 with   */
/*                 *  macro                                             */ 
/*                 * Display code revision in help()                    */
/* 221,09mar99,mt  * NO_ASCII_OUTPUT => canRead/Take measures           */
/*                 * Frames per second                                  */
/* 220,01mar99,ot  * New macros GET_CURRENT_TIME and SLEEP for multi    */
/*                 *  OS support                                        */
/*                 * Replace DWORD with long                            */
/*                 * Replace ERROR_SUCCESS with NTCAN_SUCCESS           */
/*                 * Fixed bug with non initialized board status        */
/*                 * Minor changes to remove some BC and GCC compiler   */
/*                 *  warnings                                          */
/*                 * Support for UNIX (Solaris) based on macro unix     */
/*                 * Replaced macro SIEMENS with D3X                    */
/*                 * Description of test 9 in help()                    */
/*                 * Included ASCII output support for test 3 and 9     */
/*                 * Removed some junk code                             */
/*                 * Added RCS/CVS id                                   */
/*                 * Made help() and get_error_str() static             */
/*                 * Check for new NTCAN_INSUFICIENT_RESOURCES after    */
/*                 *  canIdAdd() and solve situation with sleep         */
/*                 * Rename module from nttest.c to cantest.c           */
/* 210,09dec98,mt  * New Parameter for nttest                           */
/* 202,18dec97,mt  * New Error-Code "NTCAN_INVALID_HARDWARE"            */
/* 201,06nov97,mt  * Bug-Fixes & different Default-values for testcount */
/* 200,28oct97,mt  * D3x-Version                                        */
/* 010,19jun97,mt  * Birth of module                                    */
/*----------------------------------------------------------------------*/
#define LEVEL    2
#define REVISION 6
#define CHANGE   1


#ifdef _WIN32
# include <windows.h>
#if 0
#define TIME_UNITS "us" 
#endif
#define GET_CURRENT_TIME mtime()
static unsigned long mtime(void);
# define SLEEP(arg)  Sleep(arg)
# ifdef _WIN32_WCE
# define atoi _wtoi   /* As we work with unicode redefine this */
int CreateArgvArgc(TCHAR *pProgName, TCHAR *argv[30], TCHAR *pCmdLine);
# endif /* of _WIN32_WCE */
# ifdef UNDER_RTSS
#  include "rtapi.h"
#  define TIME_UNITS   "us"
# endif /* of UNDER_RTSS */
#endif

#if defined(unix) && !defined(RTAI) && !defined(RTLINUX)
# include  <errno.h>
# include <sys/time.h>
# include <unistd.h>
# ifdef D3X   /* Solaris driver only */
#  include <signal.h>
  void sigio_handler(int arg);
# endif /* of D3X */
  static unsigned long mtime(void);
# define SLEEP(arg) (arg > 1000 ? sleep(arg/1000) : sleep(1))
#define GET_CURRENT_TIME mtime()
#endif /* of unix */


#ifdef qnx
# include <sys/time.h>
# include <unistd.h>
  static unsigned long mtime(void);
# define GET_CURRENT_TIME mtime()
# define SLEEP(arg) (arg > 1000 ? sleep(arg/1000) : sleep(1))
#endif


#ifdef VXWORKS
# include "vxWorks.h"
# include "sysLib.h"
# include "taskLib.h"
# include "semLib.h"
# include "tickLib.h"
# include "string.h"
# define GET_CURRENT_TIME ((tickGet() & 0x003fffff) * 1000 / sysClkRateGet())
# define SLEEP(arg) { register long ticks = arg * sysClkRateGet() / 1000;                       (ticks == 0 ? taskDelay(1) : taskDelay(ticks)); }
# define main _canTest   /* Redefine main for to be called from helper */
 static STATUS _checkPriority(int net);
#endif /* of VXWORKS */


#ifdef RMOS
# include <errno.h>
# include <rmapi.h>        /* RMOS3-Include                                  */
  static unsigned long mtime(void);
# define GET_CURRENT_TIME mtime()
# define SLEEP(arg) RmPauseTask( arg )
#endif /* RMOS */


#ifdef RTOSUH
# include <sys/types.h>
# include <fcntl.h>
# include <unistd.h>
# include <ctype.h>
# include <errno.h>
# define GET_CURRENT_TIME clock_()
/*# define SLEEP(arg)       ttire(0x80000000 | arg) */
PROGRAM_TYPE(PT_SHM);
SHELL_MODULE_SPEC(CANTEST, CANTEST, 30);
#endif /* RTOSUH */


#if defined(RTAI) || defined(RTLINUX)
#  include <linux/module.h>
#  include <asm/io.h>

# ifdef RTAI
#  include <rtai.h>
#  include <rtai_fifos.h>
#  include <rtai_sched.h>
RT_TASK thread;
#  define RT_TIMER_TICK_1MS 1000000 // ns (!!!!! CAREFULL NEVER GREATER THAN 1E7 !!!!!)
# else
#  include <rtl.h>
#  include <rtl_fifo.h>
#  include <rtl_sched.h>
#  include <rtl_time.h>
#  include <rtl_sched.h>
#  include <pthread.h>


#define WPX(x) printk("### %s:%d ###\n", x,  __LINE__);

pthread_attr_t attr;
pthread_t thread;
struct sched_param sched_param;

# endif /* RTAI */

#define STACK_SIZE 0xf00                                                                      
#define CANTEST_PRIO RT_HIGHEST_PRIORITY + 10                                                                                    
         

#  define DEFAULT_IN_FIFO  1
#  define DEFAULT_OUT_FIFO 2

#  define FIFO_BUF_SIZE 256
#  define MAX_ARGC 32


static int infifo=  DEFAULT_IN_FIFO;
static int outfifo= DEFAULT_OUT_FIFO;


int printf(const char *fmt, ...)
{
  char sbuf[FIFO_BUF_SIZE];
  va_list args;
  

  va_start(args, fmt);
  vsprintf(sbuf, fmt, args);
  va_end(args);
  rtf_put(outfifo, sbuf, strlen(sbuf));
  
  return 0;
}  
#  define strtoul(cp, end, base)  simple_strtoul(cp, end, base)
# ifdef RTAI
#  define TIME_TYPE RTIME
#  define GET_CURRENT_TIME rt_get_time_ns() 
#  define SLEEP(x) rt_sleep(nano2count(x * 1000 * 1000)) 
#else
#  define TIME_TYPE hrtime_t
#  define GET_CURRENT_TIME gethrtime()
#if 0
#  define SLEEP(x) do { pthread_make_periodic_np(pthread_self(), gethrtime()  + (x) * 1000 * 1000,  0); pthread_wait_np(); } while(0)
#else
#define SLEEP(x) usleep((x) > 1000 ? 999999 : (x) * 1000)
#endif /* if 0 */
# endif
#  define TIME_UNITS "ns" 


MODULE_PARM(infifo,  "1i");
MODULE_PARM(outfifo, "1i");


int atoi(char *str)
{
  char *endp;
  unsigned long ul;

  ul= simple_strtoul(str, &endp, 10);
  
  return ul;
}

/*
** Build argc and argv[] and call test program
*/
void fifoHandler(int fifo)
{
  int status, i, argc= 0;
  char buf[FIFO_BUF_SIZE], *cp;
  char *argv[MAX_ARGC];
  char *argv0= "cantest";
  int main(int argc, char *argv[]);
  

  while(1) {
    SLEEP(1000);
    if ((status= rtf_get(fifo, buf, FIFO_BUF_SIZE)) > 0) {

      buf[FIFO_BUF_SIZE - 1]= 0;
      i= 1;
      argv[0]= argv0;
      argc= 1;
      
      cp= strchr(buf, '\n');
      if (cp) {
	*cp= '\0';
	cp= strtok(buf, " ");
	while (cp && i < (MAX_ARGC - 2)) {
	  argv= vmalloc(strlen(cp) + 1);
	strcpy(argv, cp);
	i++;
	cp= strtok(0, " ");
	}
      }

      argc= i;
      argv[MAX_ARGC - 1]= 0;
      
      /* call test program */
      main(argc, argv);
	
      for(i= 1; i < argc; i++) {
	vfree(argv);
      }
    }
    else {
      SLEEP(250); /* 250 ms */
    }
  }

}






int init_module(void)
{
  int status;



  rtf_destroy(infifo);
  if ((status= rtf_create(infifo, 256)) < 0) {
    printk("CANTEST: Can't create infifo [%d=%#x]\n", status, status);
    return status;
  }


  rtf_destroy(outfifo);
  if ((status= rtf_create(outfifo, 4096)) < 0) {
    printk("CANTEST: Can't create outfifo [%d=%#x]\n", status, status);
    return status;
  }


#ifdef RTAI  
  { 
    RTIME __attribute__ ((unused)) ticks;
    ticks= start_rt_timer((int)nano2count(RT_TIMER_TICK_1MS));
    printk("CANTEST: rtai-timer started with tick time 1ms [%ld]\n", (long)ticks);
  }

  /*
   * rtai offers fifo_handlers, but semaphores doesn't work with fifo-handlers in rtai-1.2 !?
   * So we spawn a task and poll for fifo-data
   */
  if ((status= rt_task_init(&thread, fifoHandler, infifo, STACK_SIZE, CANTEST_PRIO, 0, 0)) < 0) {
    printk("CANTEST: rt_task_init() failed [%d=%#x]\n", status, status);
    return status;
  }
  rt_task_resume(&thread);
#else
  pthread_attr_init (&attr);
  sched_param.sched_priority = 1;
  pthread_attr_setschedparam (&attr, &sched_param);

  if ((status= pthread_create(&thread, &attr,  (void * (*)(void *))fifoHandler, (void *)infifo))) {
    printk("CANTEST: pthread_create() failed [%d=%#x]\n", status, status);
    return status;
  }
#endif /* RTAI */
  printk("CANTEST: Initialized using /dev/rtf%d as input and /dev/rtf%d as output-device\n",
	 infifo, outfifo);
  
  return 0;
}


void cleanup_module(void)
{

  rtf_destroy(infifo);
  rtf_destroy(outfifo);
#ifdef RTAI
  rt_task_delete(&thread);
#else
  pthread_delete_np(thread);
#endif /* RTAI */
  { 
    stop_rt_timer();
  }
  printk("CANTEST: cleanup ...\n");
}


#else
#  include <stdio.h>
#  include <stdlib.h>
# ifndef TIME_TYPE
#   define TIME_TYPE unsigned long
# endif 
# ifndef TIME_UNITS
#   define TIME_UNITS "msec"
# endif
#endif /* RTAI || RTLINUX */


#include "ntcan.h"

#define MAX_RX_MSG_CNT 8192
#define MAX_TX_MSG_CNT 2048

/*
 * RCS/CVS id with support to prevent compiler warnings about unused vars
 */
#if ((__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >=7))
static char* rcsid __attribute__((unused)) = "$Id: cantest.c,v 1.36 2002/05/02 06:57:58 oliver Exp $";
#else  /* No or old GNU compiler */
# define USE(var) static void use_##var(void *x) {if(x) use_##var((void *)var);}
static char* rcsid = "$Id: cantest.c,v 1.36 2002/05/02 06:57:58 oliver Exp $";
USE(rcsid);
#endif /* of GNU compiler */

/*
 * Forward declarations
 */
static void help(void);
static char *get_error_str(char *str_buf, long ntstatus);

/*
 * Globals
 */
int NO_ASCII_OUTPUT=0;

CMSG  rxmsg[MAX_RX_MSG_CNT];
CMSG  txmsg[MAX_TX_MSG_CNT];
CMSG  cmdmsg;             /* can-data from the command-line */
EVMSG evmsg;
#if defined(unix) && defined(D3X)
HANDLE h1;                /* Handle for async I/O test */
#endif /* of unix && D3X */

#ifdef _WIN32_WCE
int main (DWORD	hInstance,      /* Handle to current instance of application */
          DWORD hPrevInstance,  /* Handle to prev. instance of application */
          TCHAR *pCmdLine,      /* Command line for application w/o appname */
          int nShowCmd)         /* Windows show mode */
#else /* of _WIN32_WCE */
#ifdef RMOS
int _FAR main(int argc, char *argv[])
#else /* of RMOS */
int main(int argc, char *argv[])
#endif /* of RMOS */
#endif /* of _WIN32_WCE */
{
  HANDLE h0;
  int    test;
  int    net       =0;
  long   idstart   =0;
  long   idend     =0;
  long   maxcount  =1;
  long   txbufsize =10;
  long   rxbufsize =100;
  long   txtout    =1000;
  long   rxtout    =5000;
#ifdef D3X
  int baudrate  =7;
#else
  int baudrate  =2;
  unsigned long time_1;
#endif
  int testcount =10;
  int ever=0;
  char str_buf[100];
    
  int data_from_cmd =0;

  unsigned long mode=0;
  TIME_TYPE start_time, stop_time;
  TIME_TYPE start_test_time, stop_test_time;
  long  ret;
  long h,i, j, k;
  long frames=-1;
  CMSG *cm;
  long len;
  char *pend;

#ifdef _WIN32
# ifdef _WIN32_WCE
  TCHAR	*argv[30];
  int	argc;

  argc = CreateArgvArgc(TEXT("cantest.exe"), argv, pCmdLine);
# elif UNDER_RTSS
# else
  HANDLE hEvent;
  OVERLAPPED  overlapped;         /* overlapped-structure       */
# endif /* of _WIN32_WCE */
#endif /* of _WIN32 */


  if(argc >1)
    {
      test=atoi(argv[1] );
    }
  else
    {
      help();
      return(-1);
    }

  if(test >=2 && test <= 4)
    {
      testcount =-1;
    }

  if(argc >2)
    {
      net=atoi(argv[2] );
    }

  if(argc >3)
    {
      idstart = strtoul(argv[3], &pend, 0);
      if(*pend != '\0')
        {
          printf("!! Parameter id-1st invalid !!\n");
          return(-1);
        }
    }

  if(argc >4)
    {
      idend = strtoul(argv[4], &pend, 0);
      if(*pend != '\0')
        {
          printf("!! Parameter id-last invalid !!\n");
          return(-1);
        }
    }

  if(argc >5)
    {
      maxcount=atoi(argv[5] );
      if (maxcount > (long)(sizeof(rxmsg) / sizeof(CMSG)))
	maxcount=sizeof(rxmsg) / sizeof(CMSG);
    }

  if(argc >6)
    {
      txbufsize=atoi(argv[6]);
    }

  if(argc >7)
    {
      rxbufsize=atoi(argv[7]);
    }

  if(argc >8)
    {
      txtout=atoi(argv[8]);
    }

  if(argc >9)
    {
      rxtout=atoi(argv[9]);
    }

  if(argc >10)
    {
     baudrate = strtoul(argv[10], &pend, 0);
     if(*pend != '\0')
       {
         printf("!! Parameter baudrate invalid !!\n");
         return(-1);
       }
    }
  
  if(argc >11)
    {
      testcount=atoi(argv[11]);
    }

  /* prepare default-data */
  k=1;
  for(i=0; i < (long)(sizeof(txmsg) / sizeof(CMSG)); i++)
    {
      cm =&txmsg;
      cm->id=idstart;
      cm->len=8;
      *((unsigned long *)(&cm->data[0])) =0;
      *((unsigned long *)(&cm->data[4])) =k++;
   }


  for(i=0;i <=idend-idstart; i++)
    {
      cm =&rxmsg;
      cm ->id=idstart+i;
    }
  

  /* try to fetch data-bytes from command-line */
  evmsg.evid = (idstart & 0xff)+NTCAN_EV_BASE;
  cmdmsg.id  = idstart;
  cmdmsg.len =0;
  evmsg.len = 0;

  for(i =12; i < argc && i < 12+8; i ++)
   {
      cmdmsg.data[i-12] = (char)atoi(argv);
      cmdmsg.len ++;

      evmsg.evdata.c[i-12] = (char)atoi(argv);
      evmsg.len ++;
    }
  
  if( i > 12 )
    {
      
  
      data_from_cmd =1;

      for( i=0; i < (long)(sizeof(txmsg) / sizeof(CMSG)); i++ )
	{
	  txmsg = cmdmsg;
	}
    }

  if(testcount == -1)
    ever =1;
    
  printf("test=%d net=%d ", test, net);
  if((idstart > 0x7FF) || (idend > 0x7FF))
    printf("id-1st=0x%lx id-last=0x%lx ", idstart, idend);
  else
    printf("id-1st=%ld id-last=%ld ", idstart, idend);
  printf("count=%ld\ntxbuf=%ld rxbuf=%ld txtout=%ld rxtout=%ld ",
	 maxcount, txbufsize, rxbufsize, txtout, rxtout);
  if((unsigned long)baudrate >= 15)
    printf("baudrate=0x%lx ", (unsigned long)baudrate);
  else
    printf("baudrate=%d ", baudrate);
  printf("testcount=%d\n", testcount);

  if(test ==22)                  
    mode |=NTCAN_MODE_OBJECT;  /* set object-mode */

  /*
   * Mark overlapped for Win NT/Win 9x overlapped operations
   */
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(UNDER_RTSS) 
  if(test ==6 || test == 7)
    mode |=NTCAN_MODE_OVERLAPPED;
#endif /* of _WIN32 && !_WIN32_WCE */  

  /*
   *  Async I/O test for UNIX(Solaris) D3X interface driver
   *  Install signal handler and make driver call SIGIO for each received frame
   */
#if defined(unix) && defined(D3X)
  if(test == 6)
    {
      if(signal(SIGIO, sigio_handler) == SIG_ERR)
	{
	  printf("Initialising signal handler failed\n");
	  return(-1);
	}    
      mode |= (NTCAN_MODE_OVERLAPPED | SIGIO);
    }
#endif /* of unix && D3X */

#if 0    /* #ifdef VXWORKS */
  if(ERROR == _checkPriority(net))
    return(ERROR);      /* Check priority of caller */
#endif

  ret = canOpen(net, mode, txbufsize, rxbufsize, txtout, rxtout, &h0);
  if(ret != NTCAN_SUCCESS)
    {
      printf("canOpen returned: %s\n", get_error_str(str_buf,ret));
      return(-1);
    }

  if((test < 4) || (test > 5))
    {
      ret = canSetBaudrate(h0, baudrate);
      if(ret != NTCAN_SUCCESS)
        {
          printf("canSetBaudrate returned: %s\n", get_error_str(str_buf,ret));
          return(-1);
        }
    }
  
  if(idend >=2048)
    {
      ret = canIdAdd(h0, NTCAN_20B_BASE);
      if(ret != NTCAN_SUCCESS)
	{
	  printf("canIdAdd for all 29-Bit ids returns error %s\n",
                 get_error_str(str_buf,ret));
	}

      idend =2047;
    }

  for(i =idstart; i <=idend; i ++)
    {
      for(j = 0; j < 2; j++)
      {
	if(test ==4)          /* if event-reading-test */
	    ret = canIdAdd(h0, i + NTCAN_EV_BASE);
	else
	    ret = canIdAdd(h0, i);

	/*
	 * If driver return NTCAN_INSUFFICIENT_RESOURCES the FIFO is full.
	 * So we sleep some time in order to wait for an empty FIFO
	 */
	if(ret == NTCAN_INSUFFICIENT_RESOURCES)
	{
	    SLEEP(100);
	    continue;
	}
	
	break;
      }

      if(ret != NTCAN_SUCCESS)
	{
	  if(test ==4)          /* if event-reading-test */
	    printf("canIdAdd for event  %ld returns error %s\n", i, get_error_str(str_buf,ret));
	  else
	    printf("canIdAdd for can-id %ld returns error %s\n", i, get_error_str(str_buf,ret));

	  break;
	}
    }
  
  start_test_time = GET_CURRENT_TIME;

  for( h=0; h < testcount || ever; h++ )
    {
      switch(test)
	{
#ifndef D3X
	case 0:     /* write without wait */
	  len = maxcount;
	  
	  if(!data_from_cmd)
	    {
	      for(i=0; i < len; i++)
		{
		  *((unsigned long *)(&txmsg.data[0])) =h;
		}
	    }


	  start_time = GET_CURRENT_TIME;
	  ret =canSend(h0, txmsg, &len);
	  stop_time =GET_CURRENT_TIME;

	  printf("Duration=%9lu %s Can-Messages=%ld \n",
		 (unsigned long)(stop_time - start_time), TIME_UNITS, len);
	  
	  if(ret != NTCAN_SUCCESS)
	    {
	      printf("canSend returned:%s\n", get_error_str(str_buf,ret) );
	      SLEEP(1000);
	    }
	  
	  break;
#endif	  
	case 1:     /* write with wait    */
	  len = maxcount;
	  if(!data_from_cmd)
	    {
	      for(i=0; i < len; i++)
		{
		  *((unsigned long *)(&txmsg.data[0])) =h;
		}
	    }

	  start_time = GET_CURRENT_TIME;
	  ret = canWrite(h0, txmsg, &len, NULL);
	  stop_time =GET_CURRENT_TIME;
	  printf("Duration=%9lu %s Can-Messages=%ld \n",
		 (unsigned long)(stop_time - start_time), TIME_UNITS, len);
	  
	  if(ret != NTCAN_SUCCESS)
	    {
	      printf("canWrite returned:%s\n", get_error_str(str_buf,ret) );
	      SLEEP(1000);
	    }

	  break;

        case 11:
	  if(!data_from_cmd)
	    {
	      for(i=0; i < maxcount; i++)
		{
		  *((unsigned long *)(&txmsg.data[0])) =h;
		}
	    }

	  start_time = GET_CURRENT_TIME;

#if 0
          for(i = 0; i < maxcount; i++)
            {
              len = 1;
              (void)canWrite(h0, &txmsg, &len, NULL);
            }
#endif

          for(i = 0; i < maxcount; i++)
            {
              do {
                len = 1;
                ret = canSend(h0, &txmsg, &len);
              } while(ret == NTCAN_CONTR_BUSY);
            }

	  stop_time= GET_CURRENT_TIME;
	  printf("Duration=%6ld %s Can-Messages=%ld \n",
		 (unsigned long)(stop_time - start_time), TIME_UNITS, len);
	  
	  if(ret != NTCAN_SUCCESS)
	    {
	      printf("canWrite returned:%s\n", get_error_str(str_buf,ret) );
	      SLEEP(1000);
	    }

	  break;

#ifndef D3X
        case 22:
          len = idend-idstart+1;
          if(rxtout)
            SLEEP(rxtout);
          goto take_common;
        case 12:    /* read without wait and NO_ASCII_OUTPUT */
          NO_ASCII_OUTPUT =1;
	case 2:     /* read without wait  */
	  len = maxcount;
        take_common:
	  start_time = GET_CURRENT_TIME;
#ifdef RTAI
	  /* To better see canTake working ... */
	  SLEEP(100);
#endif
	  ret =canTake(h0, rxmsg, &len);
	  stop_time =GET_CURRENT_TIME;

	  if(frames>=10000)
	    {
	      stop_test_time = GET_CURRENT_TIME;
	      printf("Test-Duration=%lu %s frames=%ld\n",
		     (unsigned long)(stop_test_time - start_test_time), TIME_UNITS, frames);
	      start_test_time = GET_CURRENT_TIME;
	      frames =0;
	    }

          if( !NO_ASCII_OUTPUT )
            {
              printf("Duration=%9lu %s Can-Messages=%ld \n",
                     (unsigned long)(stop_time - start_time), TIME_UNITS, len);
            }
          
	  if(ret ==NTCAN_SUCCESS)
	    {
              if( NO_ASCII_OUTPUT  )              
                {
                  if( frames ==-1  )
                    {
                      start_test_time = GET_CURRENT_TIME;
                      frames =0;
                      continue;
                    }
                }

	      for(i=0; i < len; i ++)
		{
		  cm =&rxmsg;
                  if(cm->len & NTCAN_NO_DATA )
                    {
                      printf("RX-ID=%9ld (0x%08lx) NO DATA\n",
                             cm->id, cm->id );
                    }
                  else
                    if(cm->len & NTCAN_RTR )
                      {
                        if(cm->msg_lost !=0)
                          {
                            printf("%02x Messages lost !\n", cm->msg_lost );
                          }
                        if(!NO_ASCII_OUTPUT)		      
                          {
                            printf("RX-RTR-ID=%9ld (0x%08lx) len=%01X\n",
                                   cm->id, cm->id, cm->len & 0x0f );
                          }
                      }
                    else
                      {
                        cm->len &= 0x0f;
                        if(cm->msg_lost !=0)
                          {
                            printf("%02x Messages lost !\n", cm->msg_lost );
                          }
                        
                        if( !NO_ASCII_OUTPUT )
                          {
                            printf("RX-ID=%9ld (0x%08lx) len=%01X data= ", cm->id, cm->id, cm->len );
                            for(j=0; j < cm->len; j++)
                              {
                                printf("%02X ", cm->data[j] );
                              }
                            
                            printf("  [");
                            {
                              int c;
                              for(j=0; j < cm->len; j++)
                                {
                                  c= cm->data[j];
                                  printf("%c", c > 31 && c < 128 ? c : '.' );
                                }
                            }
                            printf("]\n");
                          }		      
                        
                      }
                  
		  frames ++;
		}
	    }
	  else
	    {
	      printf("canTake returned:%s\n", get_error_str(str_buf,ret));
	      SLEEP(1000);
	    }
	  
	  break;


	case 13:     /* read with wait and NO_ASCII_OUTPUT */
          NO_ASCII_OUTPUT =1;
#endif /* of !D3X */
	case 3:     /* read with wait */
	  len = maxcount;
	  start_time = GET_CURRENT_TIME;
	  ret =canRead(h0, rxmsg, &len, NULL);
#ifdef RTAI
	  /* To better see canRead working ... */
	  SLEEP(100);
#endif
	  stop_time =GET_CURRENT_TIME;

	  if(frames>=10000)
	    {
	      stop_test_time = GET_CURRENT_TIME;
	      printf("Test-Duration=%lu %s frames=%ld\n",
		     (unsigned long)(stop_test_time - start_test_time), TIME_UNITS, frames);
	      start_test_time = GET_CURRENT_TIME;
	      frames =0;
	    }
          
          if( !NO_ASCII_OUTPUT )		      	  
            {
              printf("Duration=%6lu %s Can-Messages=%ld \n",
                     (unsigned long)(stop_time - start_time), TIME_UNITS, len);
            }

	  if(ret ==NTCAN_SUCCESS)
	    {
              if( NO_ASCII_OUTPUT  )              
                {
                  if( frames ==-1 )
                    {
                      start_test_time = GET_CURRENT_TIME;
                      frames =0;
                      continue;
                    }
                }

	      for( i=0; i < len; i ++)
		{
		  cm =&rxmsg;
		  if(cm->len & NTCAN_RTR)
		    {
		      if(cm->msg_lost !=0)
			{
			  printf("%02x Messages lost !\n", cm->msg_lost );
			}

                      if(!NO_ASCII_OUTPUT)		      
                        {
                          printf("RX-RTR-ID=%9ld (0x%08lx) len=%01X\n",
                                 cm->id, cm->id, cm->len & 0x0f );	 
                        }
		    }
		  else
		    {
		      cm->len &= 0x0f;
		      if(cm->msg_lost !=0)
			{
			  printf("%02x Messages lost !\n", cm->msg_lost );
			}

                      if(!NO_ASCII_OUTPUT)
                        {
                          printf("RX-ID=%9ld (0x%08lx) len=%01X data= ", cm->id, cm->id, cm->len );
                          for(j=0; j < cm->len; j++)
                            {
                              printf("%02X ", cm->data[j] );
                            }
                          
                          printf("  [");
                          {
                            int c;
                            for(j=0; j < cm->len; j++)
                              {
                                c= cm->data[j];
                                printf("%c", c > 31 && c < 128 ? c : '.' );
                              }
                          }
                          printf("]\n");
                        }
		    }
                  
		  frames ++;
		}
	    }
	  else
	    {
	      printf("canRead returned:%s\n", get_error_str(str_buf,ret));
	      SLEEP(100);
	    }
	  
	  break;

	case 4:
	  start_time = GET_CURRENT_TIME;
	  ret =canReadEvent(h0, &evmsg, NULL);
	  stop_time = GET_CURRENT_TIME;
	  printf("Duration=%lu %s\n", (unsigned long)(stop_time - start_time), TIME_UNITS);
	  	  
	  if(ret ==NTCAN_SUCCESS)
	    {
	      printf("EVENT-ID=%8lx len=%01X data= " , evmsg.evid, evmsg.len );
	  
	      for(j=0; j < evmsg.len; j++)
		{
		  printf("%02X ", evmsg.evdata.c[j] );
		}
	      
	      printf("\n");
	    }
	  else
	    {
	      printf("canReadEvent returned:%s\n", get_error_str(str_buf,ret));
	    }
	  
	  break;

	case 5:
	  ret =canSendEvent( h0, &evmsg );
	  if(ret ==NTCAN_SUCCESS)
	    {
	      printf("Event %08lx, data written: ", evmsg.evid);

	      for(j=0; j < evmsg.len; j++)
		{
		  printf("%02X ", evmsg.evdata.c[j] );
		}
	      
	      printf ("\n" );
	    }
	  else
	    {
	      printf("canSendEvent returned:%s\n", get_error_str(str_buf,ret));
	    }

	  SLEEP(1000);
	  break;

#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(UNDER_RTSS)
	case 6:
	  if(h==0)
	    {
	      hEvent = CreateEvent(NULL,
				   TRUE,	/* flag for manual-reset  */
				   FALSE,	/* flag for initial state */
				   NULL );
      
	      if(hEvent == NULL)
		{
		  printf("CreateEvent returned handle=%08x\n", hEvent);
		  break;
		}
	      
	      overlapped.hEvent= hEvent;
	    }
  

	  len = sizeof(rxmsg) / sizeof(CMSG);
	  start_time = GET_CURRENT_TIME;
	  ret =canRead(h0, rxmsg, &len, &overlapped);
	  stop_time =GET_CURRENT_TIME;
	  printf("async-Read triggered; Duration=%lu %s\n",
		 stop_time - start_time, TIME_UNITS);
	  printf("canRead returned %s \n", get_error_str(str_buf,ret));
	  
          if(ret != NTCAN_SUCCESS && ret != NTCAN_IO_PENDING)
	    {
	      break;
	    }

	  start_time = GET_CURRENT_TIME;
	  ret =
	    WaitForSingleObject(hEvent,            /* event-handle      */
				INFINITE);         /* wait indefinitely */
	  stop_time =GET_CURRENT_TIME;

	  printf("WaitForSingleObject returned %s; Duration=%lu %s\n",
		 get_error_str(str_buf,ret), stop_time - start_time, TIME_UNITS);

	  ret = canGetOverlappedResult(h0,            /* filehandle     */
				       &overlapped,
				       &len,          /* ret cmsg-count */
				       FALSE);        /* do not wait    */
	  
	  


	  if(ret ==NTCAN_SUCCESS )
	    {
	      printf("Len(cmsg)=%d\n", len);
	      for(i=0; i < len; i ++)
		{
		  cm =&rxmsg;
		  if(cm->len & NTCAN_RTR)
		    {
		      printf("RX-RTR-ID=%9d len=%01X\n",
			     cm->id, cm->len & 0x0f );
		    }
		  else
		    {
		      cm->len &= 0x0f;
		      printf("RX-ID=%9ld (0x%08lx) len=%01X data= ", cm->id, cm->id, cm->len );
		      for(j=0; j < cm->len; j++)
			{
			  printf("%02X ", cm->data[j] );
			}
		      
		      printf("\n");
		    }
		}
	    }
	  else
	    {
	      printf("canOverlappedResult returned:%s\n", get_error_str(str_buf,ret));
	    }
	  
	  break;

	case 7:
	  if(h==0)
	    {
	      hEvent = CreateEvent(NULL,
				   TRUE,	/* flag for manual-reset  */
				   FALSE,	/* flag for initial state */
				   NULL );
      
	      if(hEvent == NULL)
		{
		  printf("CreateEvent returned handle=%08x\n", hEvent);
		  break;
		}
	      
	      overlapped.hEvent= hEvent;
            }
          
	  len = maxcount;
	  if(!data_from_cmd)
	    {
	      for(i=0; i < len; i++)
		{
		  *((unsigned long *)(&txmsg.data[0])) =h;
		}
	    }

	  start_time = GET_CURRENT_TIME;
	  ret =canWrite(h0, txmsg, &len, &overlapped);
	  stop_time =GET_CURRENT_TIME;
	  printf("async-Write triggered; Duration=%lu %s\n",
		 stop_time - start_time, TIME_UNITS);

	  printf("canWrite returned %s \n", get_error_str(str_buf,ret));
	  
          if(ret != NTCAN_SUCCESS && ret != NTCAN_IO_PENDING)
	    {
	      break;
	    }

	  start_time = GET_CURRENT_TIME;
#if 1
	  ret =
	    WaitForSingleObject(hEvent,            /* event-handle      */
				INFINITE);         /* wait indefinitely */
          
	  printf("WaitForSingleObject returned %s; \n",
		 get_error_str(str_buf,ret) );
          
	  ret = canGetOverlappedResult(h0,            /* filehandle     */
				       &overlapped,
				       &len,          /* ret cmsg-count */
				       FALSE);        /* do not wait    */
#else
	  ret = canGetOverlappedResult(h0,            /* filehandle     */
				       &overlapped,
				       &len,          /* ret cmsg-count */
				       TRUE);         /* wait    */

	  

#endif
	  stop_time =GET_CURRENT_TIME;
  	  
	  if(ret ==NTCAN_SUCCESS )
	    {
	      printf("Duration=%6lu %s Can-Messages=%d \n",
		     stop_time - start_time, TIME_UNITS, len);
	    }
	  else
	    {
	      printf("canOverlappedResult returned:%s\n", get_error_str(str_buf,ret));
	    }
	  
	  break;
#endif /* of _WIN32 */

#if defined(unix) && defined(D3X)
	case 6:
	  h1 = h0;   /* Store handle in global variable, start of test */
	  printf("Async Read triggred\n");
	  while(1);
	  start_time = GET_CURRENT_TIME;	  
	  break;
#endif /* of unix && D3X */
	  
#ifndef D3X
     	case 19:
          NO_ASCII_OUTPUT =1;
	case 9:
	  /*
	   * Send RTR of len 0 and keep system time
	   */
	  len = 1;
	  txmsg->len |= NTCAN_RTR; /* rtr */
	  start_time = GET_CURRENT_TIME;
	  ret = canSend(h0, txmsg, &len);

	  if(ret != NTCAN_SUCCESS)
	    {
	      printf("canSend returned:%s\n", get_error_str(str_buf,ret) );
	      break;
	    }

	  /*
	   * Wait for reply to this remote request and keep system time
	   */
	  time_1 =GET_CURRENT_TIME;
	  len=maxcount;
	  ret =canRead(h0, rxmsg, &len, NULL);
 	  stop_time =GET_CURRENT_TIME;

	  /*
	   * Print durations and reply
	   */
	  if( !NO_ASCII_OUTPUT  )              
	    {
	      printf("Duration=%9lu %s Duration2=%9lu %s Can-Messages=%ld \n",
		     (unsigned long)(time_1-start_time),  TIME_UNITS, 
			 (unsigned long)(stop_time - time_1), TIME_UNITS, len);
	    }

	  if(ret == NTCAN_SUCCESS)
	    {
	      if( !NO_ASCII_OUTPUT )
		{
		  for(i=0; i < len; i ++)
		    {
		      cm = &rxmsg;
		      if(cm->len & NTCAN_RTR)
			{
			  if(cm->msg_lost !=0)
			    printf("%02x Messages lost !\n", cm->msg_lost );
			  
			  printf("RX-RTR-ID=%9ld (0x%08lx) len=%01X\n",
				 cm->id, cm->id, cm->len & 0x0f );	 
			}
		      else
			{
			  cm->len &= 0x0f;
			  if(cm->msg_lost !=0)
			    printf("%02x Messages lost !\n", cm->msg_lost );
			  printf("RX-ID=%9ld (0x%08lx) len=%01X data= ", cm->id, cm->id, cm->len );
			  for(j=0; j < cm->len; j++)
			    {
			      printf("%02X ", cm->data[j] );
			    }
			  
			  {
			    printf("  [");
			    {
			      int c;
			      for(j=0; j < cm->len; j++)
				{
				  c= cm->data[j];
				  printf("%c", c > 31 && c < 128 ? c : '.' );
				}
			    }
			    printf("]");
			  }
			  
			  printf("\n");
			}
		    }
		}
	    }
	  else
	    {
	      printf("canRead returned:%s\n", get_error_str(str_buf,ret));
	    }
	  
	  break;
#endif /* of !D3X */

	default:
	  printf("Undefined Test!\n");
	  canClose(h0);
	  return(-1);
	}


    }
  
  stop_test_time = GET_CURRENT_TIME;

  canClose(h0);

  printf("Test-Duration=%lu %s \n", (unsigned long)(stop_test_time - start_test_time), TIME_UNITS); 

  return(0);
}

static void help(void)
{
  long ret;
  int i;
  HANDLE h0;
  CAN_IF_STATUS cstat;
#ifndef D3X 
#  if defined(RTAI) || defined(RTLINUX)
  int  baudrate;
#  else
  unsigned long baudrate; /* ???? */
#  endif
#endif

  printf("CAN Test Rev %x.%x.%x  -- (c) 1997-2002 electronic system design gmbh\n\n",
         LEVEL, REVISION, CHANGE);


  printf("Available CAN-Devices: \n");
  
  for(i=0; i < 255; i++)
    {
      ret = canOpen(i, 0, 1, 1, 0, 0, &h0);
      if(ret == NTCAN_SUCCESS)
	{
	  ret =canStatus(h0, &cstat);
	  if(ret != NTCAN_SUCCESS)
	    {
	      printf("Cannot get Status of Net-Device %02X\n", i );
	    }
	  else
	    {
#ifndef D3X   
	      ret =canGetBaudrate(h0, &baudrate);
	      if(ret != NTCAN_SUCCESS)
		{
		  printf("Cannot get Baudrate of Net-Device %02X\n", i );
		}
	      else
		{
#endif

			  printf("Net %3d: ID=%s "
			 "Dll=%1X.%1X.%02X "
			 "Driver=%1X.%1X.%02X"
			 " Firmware=%1X.%1X.%02X\n"
			 "         Hardware=%1X.%1X.%02X "
#ifdef D3X 
			 "Status=%08lx\n",
#else  		
			 "Baudrate=%08lx Status=%08lx Features=%04x\n",
#endif
			 i, cstat.boardid, 
			 cstat.dll     >>12, (cstat.dll     >>8) & 0xf,cstat.dll      & 0xff,  
			 cstat.driver  >>12, (cstat.driver  >>8) & 0xf,cstat.driver   & 0xff,  
			 cstat.firmware>>12, (cstat.firmware>>8) & 0xf,cstat.firmware & 0xff,  
			 cstat.hardware>>12, (cstat.hardware>>8) & 0xf,cstat.hardware & 0xff, 
#ifdef D3X 
			 cstat.boardstatus );
#else
		  (unsigned long)baudrate, cstat.boardstatus, cstat.features );
                }
#endif
            }
      
          canClose(h0);
        }
    }

#ifdef D3X
  printf("\nSyntax: d3xtest test-Nr "
#elif defined(VXWORKS)
  printf("\nSyntax: canTest test-Nr "
#else
  printf("\nSyntax: cantest test-Nr "
#endif
	 "[net id-1st id-last count\n"
         "        txbuf rxbuf txtout rxtout baud testcount data0 data1 ...]\n");
#ifndef D3X
  printf("Test  0:  canSend()\n");
#endif
  printf("Test  1:  canWrite()\n");
#ifndef D3X
  printf("Test  2:  canTake()\n");
  printf("Test 12:  canTake() with time-measurement for 10000 can-frames\n");
  printf("Test 22:  canTake() in Object-Mode\n");
#endif
  printf("Test  3:  canRead()\n");
#ifndef D3X
  printf("Test 13:  canRead() with time-measurement for 10000 can-frames\n");
#endif
  printf("Test  4:  canReadEvent()\n");
  printf("Test  5:  canSendEvent()\n");
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(UNDER_RTSS)
  printf("Test  6:  Overlapped-canRead()\n");
  printf("Test  7:  Overlapped-canWrite()\n");
#endif /* of _WIN32 && !_WIN32_WCE && !UNDER_RTSS */
#if defined(unix) && defined(D3X)
  printf("Test  6:  Async canRead()\n");
#endif /* of unix && D3X */
#ifndef D3X
  printf("Test  9:  Wait for RTR reply\n");
  printf("Test 19:  Wait for RTR reply without text-output\n");
#endif
}

static char *get_error_str(char *str_buf, long ntstatus)
{
  
  struct ERR2STR
  {
    long ntstatus;
    const char *str;
  }; 
  
  static const struct ERR2STR err2str[]=    
  {
    { NTCAN_SUCCESS            , "NTCAN_SUCCESS"            },
    { NTCAN_RX_TIMEOUT         , "NTCAN_RX_TIMEOUT"         },
    { NTCAN_TX_TIMEOUT         , "NTCAN_TX_TIMEOUT"         },
    { NTCAN_TX_ERROR           , "NTCAN_TX_ERROR"           },
    { NTCAN_CONTR_OFF_BUS      , "NTCAN_CONTR_OFF_BUS"      },
    { NTCAN_CONTR_BUSY         , "NTCAN_CONTR_BUSY"         },
    { NTCAN_CONTR_WARN         , "NTCAN_CONTR_WARN"         }, 
    { NTCAN_NO_ID_ENABLED      , "NTCAN_NO_ID_ENABLED"      },
    { NTCAN_ID_ALREADY_ENABLED , "NTCAN_ID_ALREADY_ENABLED" },
    { NTCAN_ID_NOT_ENABLED     , "NTCAN_ID_NOT_ENABLED"     },
    { NTCAN_INVALID_FIRMWARE   , "NTCAN_INVALID_FIRMWARE"   },
    { NTCAN_MESSAGE_LOST       , "NTCAN_MESSAGE_LOST"       },
    { NTCAN_INVALID_PARAMETER  , "NTCAN_INVALID_PARAMETER"  },
    { NTCAN_INVALID_HANDLE     , "NTCAN_INVALID_HANDLE"     },
#ifdef _WIN32
    { NTCAN_IO_INCOMPLETE      , "NTCAN_IO_INCOMPLETE"      },
    { NTCAN_IO_PENDING         , "NTCAN_IO_PENDING"         },
#endif
    { NTCAN_NET_NOT_FOUND      , "NTCAN_NET_NOT_FOUND"      },
#ifdef _WIN32
    { NTCAN_INVALID_HARDWARE   , "NTCAN_INVALID_HARDWARE"   },
	{ NTCAN_PENDING_WRITE      , "NTCAN_PENDING_WRITE"      },
	{ NTCAN_PENDING_READ       , "NTCAN_PENDING_READ"       },
    { NTCAN_INVALID_DRIVER     , "NTCAN_INVALID_DRIVER"     },
    { NTCAN_OPERATION_ABORTED  , "NTCAN_OPERATION_ABORTED"  },
#endif
    { NTCAN_INSUFFICIENT_RESOURCES, "NTCAN_INSUFFICIENT_RESOURCES"      },
    { 0xffffffff               , "NTCAN_UNKNOWN"            }    /* stop-mark */
  };
  
  const struct ERR2STR *es=err2str;
  
  do
   { 
     if(es->ntstatus == ntstatus)
       break;
     
     es ++;
   }
  while((unsigned long)es->ntstatus != 0xffffffff);

  printf(str_buf, "%s(0x%08lx)", es->str, ntstatus);

  return str_buf; 
}

#if defined(unix) && !defined(RTAI) && !defined(RTLINUX)
static unsigned long mtime(void)
{
  struct timeval  tv;
  struct timezone tz;

  gettimeofday(&tv, &tz);
  
  return( tv.tv_sec *1000 + tv.tv_usec/1000);
}


#ifdef D3X
void sigio_handler(int arg)
{
  register CMSG *cm;
  int i, j, err;
  long len;
  char str_buf[100];

  printf("Received signal SIGIO %d\n", arg);

  len = 1;
  err = canRead(h1, rxmsg, &len, NULL);

  if(err == NTCAN_SUCCESS)
    {
      if( !NO_ASCII_OUTPUT )		      	  
	printf("Signal = %d Can-Messages=%ld \n", arg, len);
      
      for( i=0; i < len; i ++)
	{
	  cm =&rxmsg;
	  if(cm->len & NTCAN_RTR)
	    {
	      if(cm->msg_lost !=0)
		printf("%02x Messages lost !\n", cm->msg_lost );

	      if(!NO_ASCII_OUTPUT)		      
		{
		  printf("RX-RTR-ID=%4ld len=%01X\n",
			 cm->id, cm->len & 0x0f );	 
		}
	    }
	  else
	    {
	      cm->len &= 0x0f;
	      if(cm->msg_lost !=0)
		printf("%02x Messages lost !\n", cm->msg_lost );
	      
	      if(!NO_ASCII_OUTPUT)
		{
		  printf("RX-ID=%4ld len=%01X data= ", cm->id, cm->len );
		  for(j=0; j < cm->len; j++)
		    {
		      printf("%02X ", cm->data[j] );
		    }
		  
		  printf("  [");
		  {
		    int c;
		    for(j=0; j < cm->len; j++)
		      {
			c= cm->data[j];
			printf("%c", c > 31 && c < 128 ? c : '.' );
		      }
		  }
		  putchar(']');
		  
		  printf("\n");
		}
	    }
#if 0	  
	  frames ++;
#endif
	}
    }
  else
    {
      printf("canRead returned:%s\n", get_error_str(str_buf,err));
      SLEEP(100);
    }
	  
  if(signal(SIGIO, sigio_handler) == SIG_ERR)
    printf("Re-Initialising signal handler failed\n");
  else
    printf("Re-Initialising signal handler succesfull\n");

}
# endif /* of D3X */
#endif /* of unix */

#ifdef qnx
static unsigned long mtime(void)
{
  struct timespec tv;

  clock_gettime( CLOCK_REALTIME, &tv );
  
  return( tv.tv_sec *1000 + tv.tv_nsec/1000000);
}
#endif /* of qnx */

#ifdef VXWORKS

# define MAX_ARGS 30 /* Maximum arguments for command line */

/*
 * Helper code for VxWorks limited capability to deal with many cmd line args
 */
int canTest(char *args)
{
  char *token;
  int argc = 1;
  char *argv[MAX_ARGS] = {"canTest"};
  
  /*
   * Prevent direct start from shell
   */

  /*
   * Make comand line from given string
   */
    
  for(token = strtok(args, " "); token && argc < (MAX_ARGS - 1); argc ++)
    {
      argv[argc] = token;
      token = strtok(NULL, " ");
    }

  /*
   * Call real test program. Main is redefined for VxWorks
   */
  return(main(argc, argv));
}

/*
 * Helper code for VxWorks to prevent start with priority higher than
 * backend
 */
static STATUS _checkPriority(int net)
{
  char *taskName = "CANx";
  int prioSelf, prioBackend;
  int tid;

  taskName[3] = (char)('0' + net);

  /*
   * Get TID of backend
   */
  tid = taskNameToId(taskName);

  if(ERROR == tid)
    {
      printf("\nError: No backend %s running\n", taskName);
      return(ERROR);
    }
  
  /*
   * Return error if getting own or backend priority failed
   */
  if(ERROR == taskPriorityGet(tid, &prioBackend))
    {
      printf("\nError getting priority of backend %s\n", taskName);
      return(ERROR);
    }

  /*
   * Return error if getting backend priority failed
   */
  if(ERROR == taskPriorityGet(NULL, &prioSelf))
    {
      printf("\nError getting own priority\n");
      return(ERROR);
    }

  /*
   * Return error if own prio is higher than backend prio
   */
  if(prioSelf <= prioBackend)
    {
      printf("\nOwn priority (%d) is higher than priority of backend"
             " '%s' (%d) which can cause unexpected results."
             " Spawn canTest with lower priority !!\n\n",
             prioSelf, taskName, prioBackend);
      return(ERROR);
    }

  return(OK);
}

#endif /* of VXWORKS */

#ifdef _WIN32_WCE
/*
 * Helper code for VxWorks to create argc/argv arrays for programs by
 * parsing the command line given as unicode string without the 
 * program name into individual arguments.
 * It does not handle quoted strings.
 */
int CreateArgvArgc(TCHAR *pProgName, TCHAR *argv[30], TCHAR *pCmdLine)
{
  TCHAR		*pEnd;
  int			argc = 0;

  /* Insert the program name as argc 1 */
  argv[argc++] = pProgName;

  while (*pCmdLine != TEXT('\0'))
    {
      while (iswspace (*pCmdLine))
        pCmdLine++;             /* Skip to first whitsacpe */

      if (*pCmdLine == TEXT('\0'))
        break;                  /* Break at EOL */

      /*
       * Check for '' or ""
       */
      if ((*pCmdLine == TEXT('"')) || (*pCmdLine == TEXT('\'')))
        {
          TCHAR cTerm = *pCmdLine++;
          for (pEnd = pCmdLine; (*pEnd != cTerm) && (*pEnd != TEXT('\0'));)
            pEnd++;
        }
      else
         {
           /* Find the end.*/
           for (pEnd = pCmdLine; !iswspace(*pEnd) && (*pEnd != TEXT('\0'));)
             pEnd++;
         }
		
      if (*pEnd != TEXT('\0'))
        {
          *pEnd = TEXT('\0');
          pEnd++;
        }
		
      argv[argc] = pCmdLine;

      argc++;
      pCmdLine = pEnd;
    }
  return argc;
}
#endif /* of _WIN32_WCE */


#ifdef RMOS
static unsigned long mtime(void)
{ 
  int rmStatus;
  RmAbsTimeStruct time;
  rmStatus =RmGetAbsTime(&time);
  if(rmStatus != RM_OK)
    {
      printf("Cannot get RMOS-Time! Err=%d!\n", rmStatus);
      return 0;
    }
  else
    return time.lotime;
}
#endif


#ifdef _WIN32
# ifdef UNDER_RTSS
static unsigned long mtime(void)
{
  LARGE_INTEGER ticks;
 
  RtGetClockTime(CLOCK_FASTEST, &ticks);	/* Get 100 ns tick */

  return ((unsigned long)(ticks.QuadPart / 10));			/* Return us tick */
}
# else
static unsigned long mtime(void)
{
  LARGE_INTEGER frequency;
 

  if( QueryPerformanceFrequency(&frequency) )
    {
      LARGE_INTEGER ticks;
      
      QueryPerformanceCounter(&ticks);

	  return (unsigned long) (((ticks.QuadPart) * 1000) / frequency.QuadPart);
     	  
    }
  else
    {
      return GetTickCount();
    }
}
# endif
#endif

esd_xample.c: #include <stdio.h> #include <ntcan.h> /* * This example demonstrates how the NTCAN-API can be used to open a handle, * set a baudrate and wait for reception of a CAN frame with an * identifier that has been previously enabled for this handle. * Finally all proper cleanup operations are performed */ int main(void) { int net=0; /* logical netnumber used for example */ unsigned long mode=0; /* mode for canOpen */ long txqueuesize=8; /* maximum number of messages to transmit */ long rxqueuesize=8; /* maximum number of messages to receive */ long txtimeout=100; /* timeout for transmit */ long rxtimeout=10000; /* timeout for receiving data */ HANDLE rxhandle; /* can handle for used functions */ DWORD retvalue; /* returnvalue for used functions */ DWORD baud=2; /* used baudrate (here: 500 kBit/sec.) */ CMSG cmsg[8]; /* buffer for can messages */ int rtr=0; /* rtr bit */ int i; /* loop counter */ int len; /* Bufsize in number of messages for canRead() */ /* ############################################################### */ retvalue = canOpen( net, mode, txqueuesize, rxqueuesize, txtimeout, rxtimeout, &rxhandle); if (retvalue != NTCAN_SUCCESS) { printf("canOpen() failed with error %d!\n", retvalue); return(-1); } printf("function canOpen() returned OK !\n"); /* ############################################################### */ retvalue = canSetBaudrate( rxhandle, baud); if (retvalue != 0) { printf("canSetBaudrate() failed with error %d!\n", retvalue); canClose(rxhandle); return(-1); } printf("function canSetBaudrate() returned OK !\n"); /* ############################################################### */ retvalue = canIdAdd(rxhandle, 0); if (retvalue != NTCAN_SUCCESS) { printf("canIdAdd() failed with error %d!\n", retvalue); canClose(rxhandle); return(-1); } printf("function canIdAdd() returned OK !\n"); /* ############################################################### */ do { /* * Set max numbers of messages that can be returned with * one canRead() call according to buffer size */ len = 8; retvalue = canRead( rxhandle, &cmsg[0], &len, NULL); if (retvalue == NTCAN_RX_TIMEOUT) { printf("canRead() returned timeout\n"); continue; } else if(retvalue != NTCAN_SUCCESS) { printf("canRead() failed with error %d!\n", retvalue); } else { printf("function canRead() returned OK !\n"); printf("Id of received message :%x!\n", cmsg[0].id); printf("Len of received message :%x!\n", (cmsg[0].len & 0x0f)); printf("Rtr of received message :%x!\n", ((cmsg[0].len & 0x10)>>4)); for (i=0;i<(cmsg[0].len & 0x0f);i++) printf("Byte %d of received message :%x!\n", i, cmsg[0].data); } break; } while(1); /* ############################################################### */ retvalue = canIdDelete( rxhandle, 0); if (retvalue != NTCAN_SUCCESS) printf("canIdDelete() failed with error %d!\n", retvalue); printf("function canIdDelete() returned OK !\n"); /* ############################################################### */ retvalue = canClose (rxhandle); if (retvalue != NTCAN_SUCCESS) printf("canClose() failed with error %d!\n", retvalue); printf("function canClose returned OK !\n"); /* ############################################################### */ return(0); } /* * This example demonstrates how the NTCAN-API can be used to open a handle, * set a baudrate and transmitting a CAN frame. * Finally all proper cleanup operations are performed */ int main(void) { int net=0; /* Net number used in this example */ unsigned long mode=0; /* mode used for canOpen */ long txqueuesize=8; /* size of transmit queue */ long rxqueuesize=8; /* size of receive queue */ long txtimeout=100; /* timeout for transmit operations */ long rxtimeout=1000; /* timeout for receive operations */ HANDLE txhandle; /* can handle used for several functions */ DWORD retvalue; /* returnvalue for can functions */ DWORD baud=2; /* baudrate of this example. (here: 500 kBit/s.)*/ CMSG cmsg[8]; /* can message buffer */ int rtr=0; /* rtr bit */ int i; /* loop counter */ int len; /* no of messages of the message buffer (cmsg) */ /* that should be transmitted */ /* ############################################################### */ retvalue = canOpen(net, mode, txqueuesize, rxqueuesize, txtimeout, rxtimeout, &txhandle); if (retvalue != NTCAN_SUCCESS) { printf("canOpen() failed with error %d!\n", retvalue); return(-1); } printf("function canOpen() returned OK !\n"); /* ############################################################### */ retvalue = canSetBaudrate( txhandle, baud); if (retvalue != 0) { printf("canSetBaudrate() failed with error %d!\n", retvalue); canClose(txhandle); return(-1); } printf("function canSetBaudrate() returned OK !\n"); /* ############################################################### */ /* * Initialize the first message in buffer to CAN id = 0, len = 3 * and data0 - data2 = 0,1,2 Example Programs */ cmsg[0].id=0x00; cmsg[0].len=0x03; cmsg[0].len |= cmsg[0].len + (rtr<<4); for (i=0;i<3;i++) cmsg[0].data = i; len=1; /* Number of valid messages in cmsg buffer*/ retvalue = canWrite( txhandle, &cmsg[0], &len, NULL); if (retvalue != NTCAN_SUCCESS) printf("canWrite failed() with error %d!\n", retvalue); else printf("function canWrite() returned OK !\n"); /* ############################################################### */ retvalue = canClose (txhandle); if (retvalue != NTCAN_SUCCESS) printf("canClose failed with error %d!\n", retvalue); else printf("function canClose() returned OK !\n"); /* ############################################################### */ return(0); }[/source] Thank You Pete Gallo

Share this post


Link to post
Share on other sites
Advertisement
What do you mean by "run a second program" ?

- replace the first program with the second program? (exec)
- execute the second program and then go back to the first (system)
- run the second 'program' in parallel within the same address space? (threads)
- run the second program in parallel but semi-independently? (fork)

Share this post


Link to post
Share on other sites
Hi,

In VisualStudio you could just create a second project within the solution for the second file. Then you can right click on the project you want to run, choose "Set as startup project" and then press F5 to run it with the debugger or Ctrl-F5 to run it without the debugger. This is the best solution.

Alternatively you could just include both files in the same project and simply rename main() to something else in the file you do not want to run.

Mike.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!