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/