Hello,

> Sorry I've been so quiet about this thread, but I am a) busy, and
> b) clueless.  But I have two questions:  Does it work with older
> versions, and does similar code work from user space?

It's seems that's is really a comedi problem (version 0.7.47). At this state
the example (only threads, no comedi ! ) program is running without freezing
several times (insmod .. rmmod ...). If I using only comedi callback
(with/without thread) the system is frozen. It seems to be only a problem of
the callback function (there were no problems with the periodic mode 0).

We have no idea why bionics code is working 8)). (only the code structure was
changed IMO).

Bye Olaf
#ifdef __RTL__
# include <rtl_conf.h>
# ifndef RTLINUX_V2
#  error "We need NMN RTLinux v2!"
# endif
#endif

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/errno.h>

#ifdef RTLINUX_V2
#include <rtl.h>
#include <rtl_fifo.h>
#include <rtl_sched.h>
#include <rtl_sync.h>
#include <rtl_debug.h>
#endif

#include <comedi.h>

#define THREAD_STACK_SIZE 2048

pthread_t my_pthread;
pthread_attr_t my_pthread_attr;

comedi_trig ai_trig;
unsigned int ai_dev = 0;
unsigned int ai_subdev = 0;
unsigned int ai_chan[1];
sampl_t ai_data[1];

comedi_trig ao_trig;
unsigned int ao_dev = 0;
unsigned int ao_subdev = 1;
unsigned int ao_chan[1];
sampl_t ao_data[1];


void* thread_code( void* par ) {
    for(;;) {
	rtl_printf("suspend pthread self ... ");
	pthread_wait_np(); // todo: spaeter suspend...
	rtl_printf("done\n");
    }
    return 0;
}

int callback( unsigned int flags, void* arg ) {
    rtl_printf("callback wakeup pthread\n");
    return 1;
}





int create_daq_thread(void) {
    int res = 0;
    res += pthread_attr_init(&my_pthread_attr);	
    res += pthread_create(&my_pthread, &my_pthread_attr, &thread_code, (void*) 0 );

    return res;
}

void remove_daq_thread(void) {
    pthread_delete_np( my_pthread );
    pthread_attr_destroy( &my_pthread_attr );
}




int create_daq_channels(void) {
    int res = 0;
    int i;
    for( i = 0; i != 1; ++i )	
	ai_chan[i] = CR_PACK( i, 0, AREF_GROUND );

    for( i = 0; i != 1; ++i )	
	ao_chan[i] = CR_PACK( i, 0, AREF_GROUND );

    // set up input structure
    ai_trig.subdev=ai_subdev;   // Subdevice number
    ai_trig.mode=2;             // Mode 2: event-driven program
    ai_trig.flags=TRIG_WAKE_EOS; // Trigger on end-of-scan event
    ai_trig.n_chan=1;           // One input channel
    ai_trig.chanlist=ai_chan;  // Pointer to the channel variable
    ai_trig.data=ai_data;      // Address of the variable to put conversion result
    ai_trig.data_len = sizeof(ai_data); // lenght of data
    ai_trig.n=1;                // Single sample
    ai_trig.trigsrc=TRIG_ANY;
    ai_trig.trigvar = 50000;   // Sampling period in ns eq. 20 kHz
    ai_trig.trigvar1 = 10000;   //

    // set up output structure
    ao_trig.subdev=ao_subdev;
    ao_trig.mode=0;
    ao_trig.flags=0;
    ao_trig.n_chan=1;
    ao_trig.chanlist=ao_chan;
    ao_trig.data=ao_data;
    ao_trig.data_len=sizeof(ao_data);
    ao_trig.n=1;
    ao_trig.trigsrc=0;
    ao_trig.trigvar=0;
    ao_trig.trigvar1=0;

    res += comedi_lock_ioctl(ai_dev, ai_subdev );
    res += comedi_lock_ioctl(ao_dev, ao_subdev );
    res += comedi_register_callback( ai_dev, ai_subdev, COMEDI_CB_EOS, &callback, (void*)0);
    res += comedi_trig_ioctl( ai_dev, ai_subdev, &ai_trig );

    return res;
}

void remove_daq_channels(void) {
    comedi_cancel_ioctl( ai_dev, ai_subdev );
    comedi_unlock_ioctl( ao_dev, ao_subdev );
    comedi_unlock_ioctl( ai_dev, ai_subdev );
}

int init_module(void) {
    // todo: besseren schutz implementieren...
    // rtf_destroy(1);
    // rtf_create(1,4096);

    if( create_daq_thread() != 0 )     rtl_printf("cannot create daq_thread");
    //if( create_daq_channels() != 0 )   rtl_printf("cannot create daq_channels");


    rtl_printf("modules initialized\n");

    return 0;
}

void cleanup_module(void) {
    //remove_daq_channels();
    remove_daq_thread();
}

Reply via email to