Your issue sounds not too complex and I
almost work on the same one these days.

In fact I just program with redhat linux6.2,not rtlinux.
my job run fine now.And I glance through your codes
and comments.I think at least you did not do MUTEX
when do such operation 
"csr_temp = IOSPACEW(adc_slot,ADC_CSR) & 0xe3f0",
I am not sure what this really doing but i guess it interact
with hardware,so if no MUTEX.the result is unpredictable.

I am not familar with rtlinux but I think the mutex is the same.

----- Original Message ----- 
From: "Ken Ramey" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Tuesday, June 26, 2001 1:05 AM
Subject: [rtl] Problem with multiple threads


> I have been beating my head against this problem for over a week now and thought
> I'd solicit some help from this group.  I have a system with the following two
> functions, each of which needs to run as a seperate thread in RTLinux.  adcThread
> is supposed to run at a rate of 100Hz and monitor the forces on a set of load
> cells.  servo_thread runs at 50Hz and compares the currently recorded load cell
> readings with the target readings and implements a PI servo loop to control the
> forces.  The printk() statements were put in for debugging purposes to show what is
> happening in the system.
> 
> Here are the symptoms I am seeing:
> 
> * Both threads appear to be successfully created, marked for periodic execution,
> and started.
> 
> * servo_thread runs at 100Hz, as expected, until removed from the system with
> rmmod.
> 
> * adcThread runs _one_ time, going to sleep and never again being awakened.
> 
> I have tried various re-arrangements of the code; putting servoTask ahead of
> adcTask, decreasing the frequency of each and of both tasks, and having adcTask be
> the _only_ task in the system.  In each case, the behavior is the same.
> 
> I apologize for the length of this note, but I couldn't think of any other way to
> illustrate what is happening besides including the code in question.  Any
> help/ideas/suggestions that anyone can provide would be greatly appreciated and
> publically acknowledged.   :-)
> 
> Thanks.
> 
> Ken Ramey
> 
> void *adcThread(void *t)
> {
>   unsigned short int      adc_chan;
>   unsigned short int      csr_temp, ctrl_reg;
>   int                     sampleCnt;
>   int                     adc_counts[ADC_CHANS];
> 
>   while (TRUE)
>     {
>       printk(KERN_INFO "adcThread active\n");
>       csr_temp = IOSPACEW(adc_slot,ADC_CSR) & 0xe3f0;
> 
>       for (adc_chan = 0; adc_chan < ADC_CHANS; adc_chan++)
>          adc_counts[adc_chan] = 0;
> 
>       sampleCnt = 0;
>       while (sampleCnt < SAMPLE_SIZE)
>          {
>                for (adc_chan = 1; adc_chan <= ADC_CHANS; adc_chan++)
>                  {
>                        ctrl_reg = csr_temp | ((adc_chan - 1) >> 1);
>                        if ((adc_chan % 2) == 0)
>                           ctrl_reg |= 0x10;
>                        else
>                           ctrl_reg |= 0x08;
> 
>                        IOSPACEW(adc_slot,ADC_CSR) = ctrl_reg;
>                        usleep(5);
> 
>                        IOSPACEW(adc_slot,ADC_CONVERT) = 0xffff;
>                        usleep(11);
> 
>                        adc_counts[adc_chan - 1] += IOSPACEW(adc_slot,ADC_DATA);
>                  }
>            sampleCnt++;
>      }
> 
>       for (adc_chan = 0; adc_chan < ADC_CHANS; adc_chan++)
>            curCounts[adc_chan] = adc_counts[adc_chan] / SAMPLE_SIZE;
> 
>       IOSPACEW(adc_slot,ADC_CSR) = csr_temp;
>       printk(KERN_INFO "adcThread going to sleep\n");
>       pthread_wait_np();
>     }
>     printk(KERN_IN FO "adcThread exiting\n");
> }
> 
> void *servo_thread(void *t)
> {
>   int          error;
>   int          ival;
>   int          dacout[AXIS];
>   int          i;
>   int          rawCount = 0;
>   int          errSum[AXIS] = {0, 0};
> 
>   while (TRUE)
>     {
>       printk(KERN_INFO "servo_thread active\n");
>       for (i = 0; i < AXIS; i++)
>          {
>                rawCount = curCounts[6 + i];  /* raw value from the adc     */
>                error  = targetCount[i] - rawCount;
>                ival   = errSum[i] + 0.015 * error;
>                if (ival > DAC_MID + 1000)     /* +1000 from midpoint of DAC */
>                  ival = DAC_MID + 1000;
>                if (ival < DAC_MID - 1000)     /* -1000 from midpoint of DAC */
>                  ival = DAC_MID - 1000;
> 
>                dacout[i] = (1 * error + errSum[i]);
>                errSum[i] = ival;
> 
>                if (dacout[i] < 0)
>                  dacout[i] = 0;
>                else if (dacout[i] > 65535)
>                  dacout[i] = 65535;
>                IOSPACEW(dac_slot,i * 2) = (unsigned short) dacout[i];
>              }
>       /* Sleep until our next interval occurs */
>       printk(KERN_INFO "servo_thread sleeping\n");
>       pthread_wait_np();
>     }
> }
> 
> The two threads are started with the following code:
> 
> ...
>  pthread_attr_init(&attr);
>   sched_param.sched_priority = 90;
>   pthread_attr_setschedparam(&attr, &sched_param);
> 
>   retVal = pthread_create(&adcTask, &attr, adcThread, (void *)1);
>   if (retVal != 0)
>     printk(KERN_INFO "Unable to create ADC Thread. RC = %d\n", retVal);
> 
>   retVal = pthread_make_periodic_np(adcTask, gethrtime() , 10000000);
>   if (retVal != 0)
>     printk(KERN_INFO "Unable to start adcThread\n");
> 
>   sched_param.sched_priority = 100;
>   pthread_attr_setschedparam(&attr, &sched_param);
> 
>  retVal = pthread_create(&servoTask, &attr, servo_thread, (void *)1);
>  if (retVal != 0)
>     printk(KERN_INFO "Unable to create Servo Thread. RC = %d\n", retVal);
>   pthread_attr_setfp_np(servoTask, 1);
> 
>   retVal = pthread_make_periodic_np(servoTask, gethrtime() , 20000000);
>   if (retVal != 0)
>     printk(KERN_INFO "Unable to start servoTask\n");
> ...
> 
> ----- End of forwarded message from [EMAIL PROTECTED] -----
> -- [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/
> 
> 

----- End of forwarded message from [EMAIL PROTECTED] -----
-- [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/

Reply via email to