Gibt es eine Möglichkeit, die Treiberinitialisierung auf Beaglebone Black zu verzögern?

Gibt es eine Möglichkeit, die Treiberinitialisierung auf Beaglebone Black zu verzögern?

Ich möchte wissen, wie ich die Treiberinformationen finden kann. Und ich möchte wissen, ob es möglich ist, die Treiberinitialisierung zu verzögern, wenn ich den Beaglebone Black boote oder neu starte.

Antwort1

Wenn Sie den Treiber ändern können, können Sie sich meine Antwort ansehenHier.

Meine Lösung besteht darin, usleep_range(1000000, 12000000);in dieSondeFunktion in Ihrem Treiber, so dass der Treiber 10 - 12 Sekunden verzögert wird. DieSondeFunktion ist der Punkt, an dem der Treiber mit der Ausführung/Initialisierung beginnt.

Antwort2

Ist der Gerätetreiber Open Source? Wenn ja, sollten Sie den Quellcode herunterladen, damit Sie ihn ändern können.

Unter Ausnutzung eines Vielfachen der Systemuhr verzögern Sie die Treiberrichtung von innen mit dem folgenden Code-Schnipsel:

while (time_before(jiffies, j1))
    cpu_relax();

j1ist der Wert von Jiffies nach Ablauf der Verzögerung. cpu_relaxDies ist ein Aufruf, der die Architektur speziell aufruft, um einen inaktiven Prozessor anzuzeigen.

Auch hier ist alles davon abhängig, ob der Quellcode des Treibers vorliegt.

Antwort3

Anstelle einer Busy-Loop, die cpu_relax(), oder aufruft schedule()und potenzielle Nachteile mit sich bringt, sollten Sie besser Zeitgeberfunktionen verwenden, die so konzipiert sind, dass sie ohne potenziell nachteilige Nebenwirkungen warten (wie etwa das Blockieren anderer Aktivitäten auf eine Art und Weise, die im besten Fall unangenehm sein oder im schlimmsten Fall zum Blockieren des Geräts führen könnte).

Für kürzere Verzögerungen (beispielsweise bei der Behebung von Problemen mit kurzer Latenz) können folgende verwendet werden:

#include <linux/delay.h>
void ndelay(unsigned long nsecs);
void udelay(unsigned long usecs);
void mdelay(unsigned long msecs);

Obwohl dies in diesem Szenario wahrscheinlich nicht sinnvoll ist, da die Treiberinitialisierung blockiert werden muss und nicht zum Betriebssystem zurückkehren darf, bis der Treiber initialisiert ist, sind Kernel-Timer im Allgemeinen die beste Lösung, wenn Sie eine Aktion für einen späteren Zeitpunkt planen müssen, ohne den aktuellen Prozess zu blockieren.

#include <linux/timer.h>
struct timer_list {
        /* ... */
        unsigned long expires;
        void (*function)(unsigned long);
        unsigned long data;
};

struct timer_list TIMER_INITIALIZER(_function, _expires, _data);

void init_timer(struct timer_list *timer);
void add_timer(struct timer_list * timer);
int del_timer(struct timer_list * timer);
int mod_timer(struct timer_list *timer, unsigned long expires);
int timer_pending(const struct timer_list * timer);

Um diese zu verwenden, initialisieren Sie einen timer_listEintrag. Dies TIMER_INITIALIZER()ist eine praktische Funktion, bei der ein Zeiger auf die auszuführende Funktion, undurchsichtige Daten, die an die Funktion übergeben werden sollen, und eine Zeitangabe, _expiresdie die genaue Zeit angibt, zu der die Funktion ausgeführt werden soll. Hinweis: Die ausgelassenen Felder in der timer_listStruktur sind Implementierungsdetails, die für diese Diskussion nicht benötigt werden.

Der Aufruf fügt dann add_timer()den Timer_list-Eintrag in die Warteschlange ein (startet also den Timer).

Eine andere Möglichkeit besteht darin, etwas wie zu verwenden wait_event(), das wartet, bis eine Bedingung erfüllt ist, die vom Kernel überprüft wird, bevor die Wartezeit aufgehoben wird. Anstatt eine beliebige Zeitspanne abzuwarten, wartet es, bis etwas TBD passiert.

verwandte Informationen