Я хотел бы знать, как мне найти информацию о драйвере. И я хотел бы знать, возможно ли отложить инициализацию драйвера при загрузке или перезагрузке Beaglebone Black.
решение1
Если вы можете изменить драйвер, вы можете посмотреть мой ответздесь.
Мое решение — поместить usleep_range(1000000, 12000000);
взондфункция в вашем драйвере, так что драйвер будет задерживаться на 10 - 12 секунд.зондФункция — это место, где драйвер начинает выполняться/инициализироваться.
решение2
Является ли драйвер устройства открытым исходным кодом? Если да, вам нужно будет загрузить исходный код, чтобы вы могли его изменить.
Используя кратное системным часам, вы задерживаете направление драйвера изнутри с помощью следующего фрагмента кода:
while (time_before(jiffies, j1))
cpu_relax();
j1
это значение джиффов по истечении задержки
cpu_relax
- это вызов, который специально активирует архитектуру для указания на простаивающий процессор.
Опять же, все зависит от наличия исходного кода драйвера.
решение3
Вместо интенсивного цикла, вызывающего cpu_relax()
, или schedule()
, которые имеют потенциальные недостатки, лучше использовать функции таймера, которые предназначены для ожидания без потенциально неблагоприятных побочных эффектов (например, блокирования других действий таким образом, что это может быть неудобно в лучшем случае или привести к зависанию устройства в худшем).
Для более коротких задержек (например, при решении проблем с короткими задержками) можно использовать:
#include <linux/delay.h>
void ndelay(unsigned long nsecs);
void udelay(unsigned long usecs);
void mdelay(unsigned long msecs);
Хотя, возможно, в данном сценарии, где инициализация драйвера должна блокироваться и не возвращаться в ОС до тех пор, пока драйвер не будет инициализирован, они, как правило, бесполезны, когда вам нужно запланировать действие на более позднее время, не блокируя текущий процесс, таймеры ядра — это выход.
#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);
Чтобы использовать их, инициализируйте timer_list
запись. TIMER_INITIALIZER()
, — это удобная функция для этого, в которую передается указатель на функцию для выполнения, непрозрачные данные для передачи в функцию, а время _expires
— это момент времени, в который функция должна запуститься. Примечание: выделенные поля в timer_list
структуре представляют собой детали реализации, не нужные для этого обсуждения.
Затем вызов add_timer()
вставляет запись timer_list в очередь (т. е. «запускает» таймер).
Другая возможность — использовать что-то вроде wait_event()
, которое ждет, пока не выполнится некоторое условие, проверенное ядром, прежде чем снять ожидание, при этом вместо ожидания в течение произвольного периода времени, оно ждет, пока что-то не произойдет (TBD)