Anzeige:
Ergebnis 1 bis 2 von 2

Thema: wlan-treiber: probleme mit wake_up_interruptible()

  1. #1
    a.ti
    Gast

    wlan-treiber: probleme mit wake_up_interruptible()

    Hallo zusammen,

    ich schreibe gerade einen Treiber für ein embedded-System (Linux-Version 2.6.16.11-rt18). Mein Problem ist, dass sich der schlafende Thread nicht mehr aufwecken lässt.

    Hier ein kleiner Ausschnitt des Codes:
    Code:
    u8 u8tmp = 0;   //that wake_up isn't called before sleeping
    u8 condition = 0; //...for wait_event_interruptible()
    
    struct dd_private_t {
       (...)
       pid_t thr_pid;
       wait_queue_head_t thr_wait;
       (...)
    }
    
    static int dd_open(struct net_device* dev)
    {
       (...)
       int result;
       result = request_irq(dev->irq, my_irq_handler, SA_INTERRUPT|SA_SHIRQ, dev->name, dev);
       if(result)
          printk("can't get assign IRQ\n");
       (...)
    }
    
    static int dd_start(struct net_device *dev)
    {
       struct dd_private_t* priv = (struct dd_private_t*)dev->priv;
       (...)
       init_waitqueue_head(&priv->thr_wait);
       priv->thr_pid = kernel_thread(dd_thread, dev, CLONE_FS|CLONE_FILES);
       (...)
    }
    
    irqreturn_t my_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
    {
       struct net_device *dev = dev_id;
       struct dd_private_t *priv = (struct dd_private_t*)dev->priv;
    
       if(u8tmp) {
          condition = 1;
          wake_up_interruptible(&priv->thr_wait);
          return IRQ_HANDLED;
       }
       return IRQ_NONE;
    }
    
    static int dd_thread(void* data)
    {
       struct net_device* dev = data;
       struct dd_private_t* priv = (struct dd_private_t*)dev->priv;
       int tmpVal;
    
       daemonize("%s", dev->name);
       allow_signal(SIGTERM);
    
       while(1) {
          u8tmp = 1; //now you can try to wake up...
          tmpVal = wait_event_interruptible(priv->thr_wait, condition);
          printk("juhuu! - woke up\n");
          (...)
    }
    Ich bin mir sicher, dass die Funktion wake_up_interruptible aus der ISR aufgerufen wird. (Festgestellt durch printk's in der Zeile drüber und drunter), aber der Thread will irgendwie nicht aufwachen (Keine "juhuu!"-Ausgabe zu sehen.

    Fehlt noch irgendwas in dem Code, bzw. muss noch irgendwas früher oder später aufgerufen werden?
    Mir kommt's irgendwie so vor, als ob der schlafende Prozess nicht gefunden wird.

    Ich hab auch die Funktion interruptible_sleep_on() ausprobiert, bekomme dann aber einen Kernel-Oops:

    Code:
    BUG: scheduling with  irqs disabled: eth1/0x00000000/746
    caller is interruptible_sleep_on+0x58/0xa4
    Call Trace:
    [C7803F40] [C000B98C] show_stack+0x40/0x194 (unreliable)
    [C7803F70] [C0210A18] schedule+0xd8/0x110
    [C7803F80] [C0210F6C] interruptible_sleep_on+0x58/0xa4
    ...
    für jegliche Tipps wäre ich sehr dankbar!

    Beste Grüße von hier aus!

    a.ti

  2. #2
    a.ti
    Gast
    ich glaub', ich hab's gelöst:
    der interrupt wurde nicht rechtzeitig bestätigt, weswegen die ISR die ganze Zeit aufgerufen wurde und sich der Kernel (oder die CPU) nicht um die wake_up()-Funktion kümmern konnte.

    Ich weiss nicht, ob das jetzt die richtige Erklärung ist, aber jetzt bestätige ich den IRQ noch vor der wake_up()-Funktion und .... es klappt!

    Allerdings bahnt sich gerade ein neues Problem an:
    Der erste Durchgang der while(1)-Schleife verläuft einwandfrei. Wenn ich dann allerdings das zweite Mal an die wait_event_interruptible()-Funktion komme, friert die Konsole ein, bzw. schaut es so aus, als ob er wieder wartet, aber sonst eben nichts zulässt.

    Wartet die Funktion "wait_event_interruptible()" aktiv? Und gibt es vielleicht eine Möglichkeit passiv zu warten?
    Wie oben schon geschrieben: Am besten ohne "interruptible_sleep_on()" (da kommt bei mir ja der Kernel-oops...)

    Beste Grüße!

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •