Форум программистов, компьютерный форум, киберфорум
Наши страницы

С под Linux

Войти
Регистрация
Восстановить пароль
 
den25
0 / 0 / 0
Регистрация: 15.05.2016
Сообщений: 5
#1

Загружаемый модуль ядра зависает - C Linux

03.01.2018, 11:39. Просмотров 234. Ответов 6
Метки нет (Все метки)

Добрый день. Пишу загружаемый модуль ядра, который должен через заданный интервал времени отправлять данные устройству. Однако после первого срабатывания таймера вся система зависает и приходится перезагружать компьютер. При этом светодиод на устройстве загорается, т.е. данные должны были отправиться. Подскажите, пожалуйста, в чем может быть проблема.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
 
/*---------------------------------------------------------------------------*/
/*                               DEVICE DECLARATIONS                         */
/*---------------------------------------------------------------------------*/
 
#include <linux/usb.h>
#include <linux/hid.h>
#include <linux/hidraw.h>
 
#define VENDOR_ID 0x03EB
#define PRODUCT_ID 0x204F
#define DRIVER_NAME "blm_driver"
 
static struct hid_device *blm;
 
static int blm_probe(struct hid_device *hdev,
    const struct hid_device_id *id);
static void blm_remove(struct hid_device *dev);
 
static const struct hid_device_id blm_id_table[] =
{
    { HID_USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, {}
};
 
static struct hid_driver blm_driver =
{
    .name = DRIVER_NAME,
    .id_table = blm_id_table,
    .probe = blm_probe,
    .remove = blm_remove
};
 
/*---------------------------------------------------------------------------*/
/*                               TIMER DECLARATIONS                          */
/*---------------------------------------------------------------------------*/
 
#include <linux/timer.h>
#include <linux/interrupt.h>
 
#define IO_PERIOD 1000
 
static struct timer_list io_timer;
static unsigned long io_timer_data;
 
static void init_io_timer(void);
static void delete_io_timer(void);
static void restart_io_timer(unsigned period);
static void io_timer_func(unsigned long data);
 
/*---------------------------------------------------------------------------*/
/*                               DEVICE OPERATIONS                           */
/*---------------------------------------------------------------------------*/
 
static int blm_probe(struct hid_device *dev,
                            const struct hid_device_id *id)
{
    printk(KERN_INFO "Device connected.\n");
 
    int err = hid_parse(dev);
    if (err)
    {
        printk(KERN_ERR "Parse failed.\n");
        return err;
    }
 
    err = hid_hw_start(dev, HID_CONNECT_HIDRAW);
    if (err)
    {
        printk(KERN_ERR "Start failed.\n");
        return err;
    }
 
    err = hid_hw_open(dev);
    if (err)
    {
        printk(KERN_ERR "Cannot open hidraw.\n");
        return err;
    }
 
    blm = dev;
 
    init_io_timer();
    restart_io_timer(IO_PERIOD);
 
    return 0;
}
 
static void blm_remove(struct hid_device *dev)
{
    printk(KERN_INFO "Device disconnected.\n");
 
    hid_hw_close(dev);
    hid_hw_stop(dev);
 
    delete_io_timer();
}
 
/*---------------------------------------------------------------------------*/
/*                               TIMER OPERATIONS                            */
/*---------------------------------------------------------------------------*/
 
static void init_io_timer(void)
{
    init_timer(&io_timer);
    io_timer.function = io_timer_func;
}
 
static void delete_io_timer(void)
{
    del_timer(&io_timer);
}
 
static void restart_io_timer(unsigned period)
{
    io_timer.expires = jiffies + period;
    add_timer(&io_timer);
}
 
static void io_timer_func(unsigned long data)
{
    printk(KERN_INFO "Interrupted %d times.\n", io_timer_data++);
 
    __u8 *io_data = kmalloc(1, GFP_KERNEL);
    if (!io_data)
    {
        printk(KERN_ERR "Out of memory.\n");
        return;
    }
 
    io_data[0] = 0b10000000;
    int err = hid_hw_raw_request(blm, 0, io_data, 1,
        HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
    if (err < 0)
    {
        printk(KERN_ERR "Could not send data to device.\n");
    }
    else
    {
        printk(KERN_INFO "Sent data to device.\n");
    }
 
    kfree(io_data);
 
    if (err > 0)
    {
        restart_io_timer(IO_PERIOD);
    }
}
 
/*---------------------------------------------------------------------------*/
/*                               MODULE OPERATIONS                           */
/*---------------------------------------------------------------------------*/
 
module_driver(blm_driver, hid_register_driver, hid_unregister_driver);
 
MODULE_LICENSE("GPL");
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.01.2018, 11:39
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Загружаемый модуль ядра зависает (C Linux):

Модуль ядра, работа с мышью - C Linux
Здравствуйте, нужно написать модуль ядра Linux,который будет при нажатии мышиной кнопки выводить некоторое сообщение. Причем желательно,...

Написать простейший модуль ядра - C Linux
Привет. Необходимо написать простейший модуль ядра. Имеются следующие исходники: #include &lt;linux/module.h&gt; #include...

Модуль ядра и прерывания от сетевой карты - C Linux
Здравствуйте! Учусь писать модули ядра. Посоветуйте, каким образом можно осуществить перехват прерываний от сетевой карты и...

Модуль ядра, создающий файл с текстом - C Linux
Здравствуйте. Файл proc_module.c. Его задача создать файл, в котором будет текст. #include &lt;stdio.h&gt; int createFile() { ...

Модуль ядра, вывод сообщения в dmesg - C Linux
Я реализовал это таким образом, но msleep вешает консоль. int record(void) { for(;;) { printk(KERN_ALERT&quot;Hello,...

Модуль ядра линукс ошибка make файла - C Linux
Помогите пожалуйста.Первый раз пытаюсь написать ядро,и ничего не получается. Выдаёт ошибку: Makefile:5: *** missing separator. Stop. ...

6
peter_irich
19 / 19 / 4
Регистрация: 18.10.2017
Сообщений: 131
03.01.2018, 18:48 #2
Я не могу ответить, т.к. сам драйверов не писал, но какое из printk() последнее?
И почему заголовочные файлы не из linux-headers? Для драйверов должны браться оттуда:
/lib/modules/$(uname -r)/build/include/linux

Пётр.
0
den25
0 / 0 / 0
Регистрация: 15.05.2016
Сообщений: 5
03.01.2018, 19:11  [ТС] #3
Цитата Сообщение от peter_irich Посмотреть сообщение
Я не могу ответить, т.к. сам драйверов не писал, но какое из printk() последнее?
И почему заголовочные файлы не из linux-headers? Для драйверов должны браться оттуда:
/lib/modules/$(uname -r)/build/include/linux

Пётр.
Пётр, все заголовочные файлы из linux-headers. Модуль собирается и устанавливается. Функция blm_probe отрабатывает без ошибок (проверял отдельно без таймера). Для сборки использую такой makefile:
Код
obj-m := blm_driver.o
KVERSION := $(shell uname -r)
KDIR := /lib/modules/$(KVERSION)/build
PWD := $(shell pwd)
modules modules_install clean:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $@
install: modules_install
	install -D -m 0644 blm.conf /etc/modprobe.d/blm.conf
	depmod -a
uninstall:
	bash uninstall.sh
0
peter_irich
19 / 19 / 4
Регистрация: 18.10.2017
Сообщений: 131
03.01.2018, 20:54 #4
Не могу сказать. Разве что установка io_data меня смущает, должно быть явное приведение "void *" к типу.
Во всяком случае, в обычных программах так требуется.

Пётр.
0
tmpValue
Нарушитель
48 / 59 / 10
Регистрация: 04.10.2017
Сообщений: 181
05.01.2018, 07:56 #5
Цитата Сообщение от den25 Посмотреть сообщение
система зависает и приходится перезагружать компьютер
Типичная проблема ошибки выхода из цикла. Выявляется отладкой.
0
rosten
22 / 4 / 1
Регистрация: 05.01.2017
Сообщений: 43
05.01.2018, 08:06 #6
io_data[0] = 0b10000000;


затирается участок памяти, где находится указатель.

Не проверял свои рассуждения, но всёравно пишу.

io_data это указатель на динамически выделенную память. находящийся по адресу 0x123450 и указывающий на 0x555555
если обращаться к io_data ,как к массиву. То компилятор воспримет это как обращение к массиву, чей первый элемент (под индексом ноль) находится по этому адресу - 0x123450.

делая так : io_data[0] = 0b10000000;
ты превращаешь
io_data == 0x555555
в
io_data = 0b10000000


ну а далее через kfree освобождаешь память по адресу 128 (могбы хоть код упростить, убрать двоичное значение)
естественно такое освобождение памяти приводит к зависанию.
1
Olej
159 / 158 / 18
Регистрация: 25.03.2012
Сообщений: 621
10.01.2018, 21:13 #7
Цитата Сообщение от den25 Посмотреть сообщение
Пишу загружаемый модуль ядра, который должен через заданный интервал времени отправлять данные устройству. Однако после первого срабатывания таймера вся система зависает и приходится перезагружать компьютер.
Это обычная практика при начальном вхождении в этот предмет (ядро Linux).
Никто детально рыться в вашем конкретном коде не станет ... зато я, как писавший множество целевых модулей для Linux (в отличие от общих рассуждений), могу вас подбросить вот такие 2 (но они сильно похожи) руководства по написанию модулей ... больше 400 стр. каждое + несколько сот примеров кода - это может вам сильно помочь.
Вот они:
Практикум по Linux Kernel
Драйверы и модули ядра Linux (очередной цикл обновлений)
Вы там найдёте самые разнообразные примеры работающего кода.
1
10.01.2018, 21:13
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.01.2018, 21:13
Привет! Вот еще темы с ответами:

Написать модуль ядра, который будет блокировать определённые кнопки мыши - C Linux
Здравствуйте! По заданию нужно написать модуль ядра Linux,который будет блокировать определённые кнопки мыши и при нажатии на...

Написать модуль ядра, который сохраняет в файле журнала все операции изменения файлов внутри заданного каталог - C Linux
Написать модуль ядра, который сохраняет в файле журнала все операции изменения файлов внутри заданного каталог(платформа разработки - oc...

Модули ядра - C Linux
пытаюсь написать простейший модуль ядра не находит файл linux/module.h linux/init.h Стоит убунту 8.10

Ожидание завершения потоков ядра - C Linux
Для ядра Linux 2.6.18 или новее написать модуль, который будет делать следующее: 1. Сформировать в памяти двусвязный список...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.