First kick off your printk() inside the
rt_treads, it is not RealTimeSave.
Replace it with rtl_print[fk]() or so.

Jens Michaelsen

----- Original Message -----
From: Ken Ramey <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Monday, June 25, 2001 7:05 PM
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