Hallo,

some times ago I started this thread before. Now I'm a little bit better
(hopefully) but the system is crashed by changing the func_id to ao_recktangle.
Why? It's using comedi for output and if rt_func_id = RT_FUNC_SET_CURRENT
or rt_func_id = RT_FUNC_IDLE there is no crash. The functions ao_set_current
and ao_recktangle are basicly the same.

I attached the short code for discuss as well to learn on the comments on it.

Thanks  Olaf

 ------8<----- cmd.h --------8<--------
#define CMD_DONE                        100
#define CMD_SET_DEBUG_LEVEL     101
#define CMD_SET_CURRENT_SOLL    102
#define CMD_SET_DEFAULT_CURRENT 103
#define CMD_GET_ACT_CURRENT_SOLL 104
#define CMD_SET_PERIOD          105
#define CMD_SUSPEND_THREAD      106
#define CMD_WAKEUP_THREAD               107
#define CMD_SET_FUNCTION                108

#define RT_FUNC_IDLE                    0
#define RT_FUNC_SET_CURRENT     1
#define RT_FUNC_SQUARE_WAVE     2
#define RT_FUNC_AI                      3
#define RT_FUNC_PRINT_SLUT              4
#define RT_FUNC_N                       5       /* !!! No. of RT-fcn !!! */

typedef struct {
    unsigned int cmd;
    int data1;
    int data2;
} rtf_msg_t;

------8<----- rt.c --------8<--------
extern volatile sampl_t sampl_current1; /* daq.c: current 1 dig. val. */
extern volatile sampl_t sampl_current2; /* daq.c: current 2 dig. val. */
....
pthread_t rt_thread;                    /* the thread */
void (*rt_func[RT_FUNC_N])(void);       /* the fnc ptr to the rt-code */
...
extern hrtime_t period_ns;                      /* mod param: rtreg_main.c */
int hz_freq;                            /* complement to period_ns (for daq.c) */
unsigned int volatile rt_func_id = RT_FUNC_IDLE; /* the numer of function */
...
void *thread_code(void *param)
{
  unsigned long flags;
   while(1) {
    pthread_wait_np();
    rtl_hard_savef_and_cli(flags);      /* critical section, disable interrrupts */
    rt_func[rt_func_id]();                      /* just do it */
    rtl_hard_restore_flags(flags);              /* restore interrupts */
  }  
  return 0;
}

int rtf_handler(unsigned int fifo)
{
    rtf_msg_t rtf_msg;
    hrtime_t now;
    int ret;

    if(rtf_get(CTRL_FIFO, &rtf_msg, sizeof(rtf_msg)) > 0) {
        switch(rtf_msg.cmd) {
        case CMD_SET_DEBUG_LEVEL:
        ....
        case CMD_SET_CURRENT_SOLL:
            if(rtf_msg.data1 >= 0 && rtf_msg.data1 <= NI_PCI_MIO_XE10_MAXDATA 
               && rtf_msg.data2 >= 0 && rtf_msg.data2 <= NI_PCI_MIO_XE10_MAXDATA ) {
                sampl_current1 = (sampl_t)rtf_msg.data1;
                sampl_current2 = (sampl_t)rtf_msg.data2;
            } else {
              RTREG_ERR("got invalid current soll %d, %d, command ignored\n", 
                        rtf_msg.data1, rtf_msg.data2);          
            }
            break;

        case CMD_SET_DEFAULT_CURRENT:
            sampl_current1 = (sampl_t)SAMPL_CURRENT1_DEFAULT;
            sampl_current2 = (sampl_t)SAMPL_CURRENT2_DEFAULT;

            break;

        ....
        case CMD_SET_PERIOD:
            if(rtf_msg.data1 >= PERIOD_NS_MIN && rtf_msg.data1 <= PERIOD_NS_MAX) {
                period_ns = (hrtime_t)rtf_msg.data1;
                now = gethrtime();
                if((ret = pthread_make_periodic_np(rt_thread, now + 1000, period_ns)) 
!= 0) {
                    RTREG_ERR("unable to make thread periodic (error %d) !\n", ret);
                }
                hz_freq = ns2Hz(period_ns);     /* this is for ao_recktangle */
            } else {
                RTREG_ERR("got invalid current period_ns %d, command ignored\n", 
                          rtf_msg.data1);               
            }
            break;
        case CMD_SET_FUNCTION:
            if(rtf_msg.data1 >= 0 && rtf_msg.data1 < RT_FUNC_N) {
                pthread_suspend_np(rt_thread);          /* stop the task */
                rt_func_id = (unsigned int)rtf_msg.data1;       /* set the new func_id 
*/
                pthread_wakeup_np(rt_thread);           /* and restart imediatly */
            } else {
                RTREG_ERR("got invalid function ID %d, command ignored\n", 
                          rtf_msg.data1);
            }
            break;      
        default:
        ....
        }    
    }  
    return 0;
}

int init_rtreg(void)
{
    int ret = 0;
    pthread_attr_t attr;
    struct sched_param sched_param;
    hrtime_t now; 

    if((ret = rtf_create(CTRL_FIFO, CTRL_FIFO_SIZE)) != 0) {
        goto fail_rtf_create_CTRL_FIFO;
    }
    if((ret = rtf_create(EVENT_FIFO, EVENT_FIFO_SIZE)) != 0) {
    .....
   if((ret = rtf_create(THREAD_FIFO, THREAD_FIFO_SIZE)) != 0) {
    .....
    if((ret = lock_daq_card()) != 0) {
     ......
    init_trig_struct_ni_pci_mio_xe10();

    /***
     * ... initialize function ptr
     */
    rt_func[RT_FUNC_IDLE] = &ao_idle;                   /* daq.c: the idle task */
    rt_func[RT_FUNC_SET_CURRENT] = &ao_set_current;     /* daq.c */
    rt_func[RT_FUNC_SQUARE_WAVE] = &ao_recktangle;      /* daq.c */
    rt_func[RT_FUNC_AI] = &ai;                          /* daq.c */
    rt_func_id = RT_FUNC_IDLE;                          /* default */
    
    hz_freq = ns2Hz(period_ns); 

    pthread_attr_init(&attr);
    sched_param.sched_priority = 100;
    pthread_attr_setschedparam(&attr, &sched_param);

    if((ret = pthread_create(&rt_thread, &attr, thread_code, (void *)0)) != 0) {
    ......
   } 

    now = gethrtime();
    if((ret = pthread_make_periodic_np(rt_thread, now + 1000, period_ns)) != 0) {      
 
        if((ret = pthread_setfp_np(rt_thread, 1)) != 0) {
            goto fail_pthread_setfp_np;
        }
    }

    /* sucess */
    return ret;

   /* failure handling */
        ...
}

-------8< ------ daq.c ----------8<-----------
inline void ao_idle(void)
{
    static char buf[80];
    ao_data[DAC0] = (sampl_t)SAMPL_CURRENT1_DEFAULT;
    ao_data[DAC1] = (sampl_t)SAMPL_CURRENT2_DEFAULT;

    if((ret = comedi_trig_ioctl(ao_dev, ao_subdev, &ao_trig)) < 0)
      RTREG_ERR("comedi_trig_ioctl() failed (error %d) !\n", ret);
}

inline void ao_set_current(void)
{
  int ret = 0;

  ao_data[DAC0] = (sampl_t)sampl_current1;      /* set current1 to ch0 */
  ao_data[DAC1] = (sampl_t)sampl_current2;      /* set current2 to ch1 */
  
  if((ret = comedi_trig_ioctl(ao_dev, ao_subdev, &ao_trig)) < 0)
      RTREG_ERR("comedi_trig_ioctl() failed (error %d) !\n", ret);
}

inline void ao_recktangle(void)
{
  static int loop_index = 0;
  static int square_on = 0;             /* flag for wheter square wave is on/off */
  int ret = 0;
  static char buf[80];

  if(square_on) {
      ao_data[DAC0] = (sampl_t)sampl_current1; /* amplitude of analog output */
      ao_data[DAC1] = (sampl_t)sampl_current2; /* amplitude of analog output */
      
      if((ret = comedi_trig_ioctl(ao_dev, ao_subdev, &ao_trig)) < 0)
          RTREG_ERR("comedi_trig_ioctl() failed (error %d) !\n", ret);
      
      if( !(loop_index % hz_freq) )
          square_on = 0;                /* turn off analog output */
      
  } else { /* !square_on */
      ao_data[DAC0] = NI_PCI_MIO_XE10_MAXDATA - (sampl_t)sampl_current1;
      ao_data[DAC1] = NI_PCI_MIO_XE10_MAXDATA - (sampl_t)sampl_current2;
      
      if((ret = comedi_trig_ioctl(ao_dev, ao_subdev, &ao_trig)) < 0)
          RTREG_ERR("comedi_trig_ioctl() failed (error %d) !\n", ret);
      
      if( !(loop_index % hz_freq) )
          square_on = 1;                /* turn on analog output */
  }
}
-- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
---
For more information on Real-Time Linux see:
http://www.rtlinux.org/rtlinux/

Reply via email to