I'm having a problem scheduling a task from an interrupt service routine 
under both rtlinux2.2 and 3.0,
the same code used to work fine under 1.x.
The task appears to schedule properly, but Linux appears to lose the 
ability to use userland timers, which
means many applications (eg top, nfs) fail to operate. I have included a 
modified version of the sound
demo (2.2 version) which shows this problem.  All I have done is to add 
a dummy task to the sound module which
should be run by the ISR and return immediately.
I have also included a linux test program which sleeps for 1 second then
returns under normal circumstances, but hangs forever after the sound 
module is loaded. I'm running
under redhat 7.0, and compiling the modules with kgcc. I get the same 
problem running on a 733MHz PIII
and a 350MHz AMD K6.
       Any clues?


test.c
---------------------------------------------
int main(int argc,char **argv)
{
  sleep(1);
  return 0;
}
----------------------------------------------
sound.c
----------------------------------------------
/*
* Interrupt handling in Real-Time. Play sounds with PC speaker.
*
* (C) Michael Barabanov, 1997
*  (C) FSMLabs  1999. [EMAIL PROTECTED]
*  Released under the GNU GENERAL PUBLIC LICENSE Version 2, June 1991
*  Any use of this code must include this notice.
*
*/

#include <linux/mc146818rtc.h>

#include <rtl_fifo.h>
#include <rtl_core.h>
#include <rtl_time.h>
#include <rtl_sched.h>
#include <rtl.h>


#define FIFO_NO 3

static pthread_t test_task_rec = 0;

static int filter(int x)
{
   static int oldx;
   int ret;

   if (x & 0x80) {
       x = 382 - x;
   }
   ret = x > oldx;
   oldx = x;
   return ret;
  
}

static void* test_task(void *arg)
    //
    // keep this as light weight as possible since it might get
    // called a lot untill we get the hardware programmed properly
    //
{
  while (1){
   //pthread_wait_np();
   pthread_suspend_np(pthread_self());
  }
}

unsigned int intr_handler(unsigned int irq, struct pt_regs *regs) {
   char data;
   char temp;
    (void) CMOS_READ(RTC_REG_C);        /* clear IRQ */
   if (rtf_get(FIFO_NO, &data, 1) > 0) {
       data = filter(data);
/*         if (data) conpr("1"); else conpr("0"); */
       temp = inb(0x61);           
       temp &= 0xfc;
       if (data) {
           temp |= 3;
       }
       outb(temp,0x61);
   }
   rtl_hard_enable_irq (8);
       pthread_wakeup_np(test_task_rec);
   return 0;
}

char save_cmos_A;
char save_cmos_B;


int init_module(void)
{
   char ctemp;
   pthread_attr_t attr;
    struct sched_param sched_param;
       int thread_status;
   pthread_attr_init (&attr);
   sched_param.sched_priority = 2;
   pthread_attr_setschedparam (&attr, &sched_param);
   thread_status = pthread_create(&test_task_rec,&attr,
                      test_task,
                      0);

   if (!I8253_channel2_free()) {
       conpr("RTL sound: can't use channel 2; bailing out\n");
       return -1;
   }
   rtf_create(FIFO_NO, 4000);

   /* this is just to ensure that the output of the counter is 1 */
   outb_p(0xb0, 0x43);    /* binary, mode 0, LSB/MSB, ch 2 */
   outb_p(0x1, 0x42);
   outb_p(0x0, 0x42);

   rtl_request_irq (8, intr_handler);

   /* program the RTC to interrupt at 8192 Hz */
   save_cmos_A = CMOS_READ(RTC_REG_A);
   save_cmos_B = CMOS_READ(RTC_REG_B);

   CMOS_WRITE(0x23, RTC_REG_A);      /* 32kHz Time Base, 8192 Hz 
interrupt frequency */
   ctemp = CMOS_READ(RTC_REG_B);
   ctemp &= 0x8f;                    /* Clear */
   ctemp |= 0x40;                    /* Periodic interrupt enable */
   CMOS_WRITE(ctemp, RTC_REG_B);

   rtl_hard_enable_irq (8);
   (void) CMOS_READ(RTC_REG_C);

   return 0;
}

void cleanup_module(void)
{
   rtf_destroy(FIFO_NO);
   outb_p(0xb6, 0x43);    /* restore the original mode */
   CMOS_WRITE(save_cmos_A, RTC_REG_A);
   CMOS_WRITE(save_cmos_B, RTC_REG_B);
   rtl_free_irq(8);
   pthread_delete_np(test_task_rec);
}

-------------------------------------------------------------------------------

-- [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