Gostaria de saber como posso encontrar as informações do driver. E gostaria de saber se é possível atrasar a inicialização do driver ao inicializar ou reiniciar o Beaglebone Black.
Responder1
Se você pode modificar o driver, você pode ver minha respostaaqui.
Minha solução é colocar usleep_range(1000000, 12000000);
nosondafunção em seu driver, de forma que o driver atrase de 10 a 12 segundos. Osondafunção é onde o driver começa a ser executado/inicializado.
Responder2
O driver do dispositivo é de código aberto? Nesse caso, você desejará baixar o código-fonte para poder modificá-lo.
Utilizando um múltiplo do relógio do sistema, você atrasa a direção do driver de dentro com o seguinte trecho de código:
while (time_before(jiffies, j1))
cpu_relax();
j1
é o valor dos instantes na expiração do atraso
cpu_relax
é uma chamada que invoca a arquitetura especificamente para indicar um processador ocioso.
Novamente, tudo depende de ter o código-fonte do driver.
Responder3
Em vez de um loop ocupado que chama cpu_relax()
, ou schedule()
, que tem desvantagens potenciais, é melhor usar funções de temporizador projetadas para esperar sem efeitos colaterais potencialmente adversos (como bloquear outras atividades de uma forma que possa ser, na melhor das hipóteses, estranha ou causar o dispositivo para apreender na pior das hipóteses).
Para atrasos mais curtos (por exemplo, lidar com problemas de latência curta), estes podem ser usados:
#include <linux/delay.h>
void ndelay(unsigned long nsecs);
void udelay(unsigned long usecs);
void mdelay(unsigned long msecs);
Embora provavelmente não seja útil neste cenário, onde a inicialização do driver precisa ser bloqueada e não retornar ao sistema operacional até que o driver seja inicializado, geralmente, quando você precisa agendar uma ação para acontecer mais tarde, sem bloquear o processo atual, os temporizadores do kernel são o caminho ir.
#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);
Para usá-los, inicialize uma timer_list
entrada. O TIMER_INITIALIZER()
, é uma função de conveniência para fazer isso, onde é passado um ponteiro para a função a ser executada, dados opacos para passar para a função e um tempo _expires
é o instante em que a função deve ser executada. Nota: Os campos com reticências na timer_list
estrutura são detalhes de implementação desnecessários para esta discussão.
Então, a chamada add_timer()
insere a entrada timer_list na fila (por exemplo, 'inicia' o cronômetro).
Outra possibilidade é usar algo como wait_event()
, que espera até que alguma condição seja verificada pelo kernel antes de liberar a espera, onde ao invés de esperar por um período de tempo arbitrário, ele espera até que algo aconteça.