Ник:
Пароль:
Главная
Профиль
Рекомендовать
Обратная связь
В избранное
Навигация
Главная
О нас
Магазин
Где/как купить
Форум
Статьи
Новости
Опросы
Поиск
Рекомендовать
Обратная связь
Сертификат ISO9001
Контакты
E-mail:
info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм:
t.me/starterkit_ru
Способы оплаты
Новости
Выпуск SK-T507-SODIMM
Выпуск SK-A40i-NANO-2E-V
Выпуск SK-A40i
Выпуск SK-A40i-NANO/-2E
Выпуск ES-T113-NANO
Выпуск SK-A40i-SODIMM
Выпуск SK-NUC906-NANO
Участие в Экспоэлектроник…
Выпуск SK-STM32H743
Выпуск SK-iMX8Mini-CAN-Pl…
Выпуск SK-iMX8Mini-Artix-…
Выпуск SK-XC6SLX9-MB-SODI…
Выпуск SK-iMX6ULL-NANO-2E
Выпуск SK-PLC-NANO-MB
Выпуск SK-iMX8Mini-SODIMM
User Info
Добро пожаловать,
Guest
Регистрация или вход
Потеряли пароль?
Ник:
Пароль:
Пользователей:
4
Поисковых ботов:
3
Гостей:
1
Всего:
8
DavidMus
forum
Google Bot
account
IvoryLosse
forum
oBot
forum
PaulineTew
forum
seniiagrom…
account
Yandex Bot
account
Форум
»
starterkit.ru
»
Embedded Linux
Вопрос по созданию драйвера
Pavel Ivanchenko
08.06.2009 19:36
0
Сообщение: 1
Admin
4.39
Пункты: 92788
Регистрация: 24.03.2009
Пол: Мужчина
Цитата
Если не трудно, помогите понять один момент. Я написал чар-драйвер, внутри которого инитится spi_driver структура, в котором определены две функции: .probe и .remove. Драйвер нормально инсталлируется (insmod затем mknod) и безошибочно вызывается функция spi_register_driver().
Вопрос: насколько я понял, после успешного вызова spi_register_driver () должен вызваться probe функция. Но она у меня не вызывается. Прилагаю файл драйвера. Если не трудно, посмотрите пожалуйста
Код
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/uaccess.h> // copy_*_user(*)
#include <linux/fs.h> // file_operations
#include <linux/cdev.h> // cdev
#include <asm/uaccess.h> /* for get_user and put_user */
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/uaccess.h>
//#include <linux/ioctl.h>
#define MAJOR_NUM 252
#define MINOR_NUM 252
#define BUF_LEN 100
#define DEVICE_FILE_NAME "spi_char_dev"
//static int count = 1;
//static int Device_Open = 0;
static dev_t drv_dev;
static struct cdev drv_cdev;
static char * Message;
//////////////////////////SPI Data/////////////////
struct spi_device *spi ; /* Representation of a
SPI device */
struct spi_transfer xfer; /* Contains transfer buffer
details */
struct spi_message sm; /* Sequence of spi_transfer
segments */
u8 *command_buffer; /* Data to be transferred */
int len; /* Length of data to be
transferred */
////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
static ssize_t drv_read(struct file* filp,
char __user * buffer, size_t length,
loff_t * offset )
{
printk(KERN_ALERT "\n INFO: drv_read \n");
if(copy_to_user(buffer,Message,length))
{
printk(KERN_INFO "\n DRV READ: copy_to_user ERROR \n");
return -EFAULT;
}
else
{
// printk(KERN_INFO "\n DRV READ: copy_to_user OK = %s lengght= %d \n",Message , length);
return length;
}
return 0;
}
static ssize_t drv_write(struct file* filp,
const char __user * buffer,
size_t length, loff_t * offset )
{
int i = 0;
printk(KERN_ALERT "\nINFO: drv_write \n");
for(i = 0;i<BUF_LEN; i++)
Message[i] = '\0';
if(copy_from_user(Message,buffer,length))
{
printk(KERN_INFO "\n DRV Write: Copy_from_user ERROR\n");
return -EFAULT;
}
else
{
// printk(KERN_INFO "\n DRVWrite: Copy_from_user OK %s\n", buffer);
return length;
}
return 0;
}
static int device_open(struct inode *inode, struct file *file)
{
int i = 0;
/*
if (Device_Open)
return -EBUSY;
Device_Open++;
try_module_get(THIS_MODULE);
*/
Message = kmalloc(BUF_LEN,GFP_KERNEL);
for(i = 0;i<BUF_LEN; i++)
Message[i] = '\0';
printk(KERN_ALERT "\nINFO: device_open \n");
return 0;//SUCCESS;
}
static int device_release(struct inode *inode, struct file *file)
{
/*
Device_Open--;
module_put(THIS_MODULE);
*/
printk(KERN_ALERT "\nINFO: device_release \n");
kfree(Message);
return 0;//SUCCESS;
}
////////////////////////SPI Function ////////////////////////////////
static void spi_command(struct spi_device *spi, unsigned int c)
{
unsigned int w = c & ~0x0100;
spi_write(spi, (u8 *)&w, 2);
}
static void spi_data(struct spi_device *spi, unsigned int d)
{
unsigned int w = d | 0x0100;
spi_write(spi, (u8 *)&w, 2);
}
static int __init spidev_probe(struct platform_device *spi)
{
int status =0 ;
printk(KERN_INFO "\n INFO SPI Probe \n");
/*
struct spidev_data *spidev;
unsigned long minor;
//Allocate driver data
spidev = kzalloc(sizeof(*spidev), GFP_KERNEL);
if (!spidev)
return -ENOMEM;
//Initialize the driver data
spidev->spi = spi;
mutex_init(&spidev->buf_lock);
INIT_LIST_HEAD(&spidev->device_entry);
// If we can allocate a minor number, hook up this device.
// Reusing minors is fine so long as udev or mdev is working.
mutex_lock(&device_list_lock);
minor = find_first_zero_bit(minors, N_SPI_MINORS);
if (minor < N_SPI_MINORS) {
spidev->dev.parent = &spi->dev;
spidev->dev.class = &spidev_class;
spidev->dev.devt = MKDEV(SPIDEV_MAJOR, minor);
snprintf(spidev->dev.bus_id, sizeof spidev->dev.bus_id,
"spidev%d.%d",
spi->master->bus_num, spi->chip_select);
status = device_register(&spidev->dev);
} else {
dev_dbg(&spi->dev, "no minor number available!\n");
status = -ENODEV;
}
if (status == 0) {
set_bit(minor, minors);
dev_set_drvdata(&spi->dev, spidev);
list_add(&spidev->device_entry, &device_list);
}
mutex_unlock(&device_list_lock);
if (status != 0)
kfree(spidev);
*/
return status;
}
static int spidev_remove(struct spi_device *spi)
{
printk(KERN_INFO "\n INFO SPI Remov \n");
/*
struct spidev_data *spidev = dev_get_drvdata(&spi->dev);
mutex_lock(&device_list_lock);
list_del(&spidev->device_entry);
dev_set_drvdata(&spi->dev, NULL);
clear_bit(MINOR(spidev->dev.devt), minors);
device_unregister(&spidev->dev);
mutex_unlock(&device_list_lock);
*/
return 0;
}
static void spidev_classdev_release(struct device *dev)
{
printk(KERN_INFO "\n INFO SPI spidev_classdev_release \n");
// struct spidev_data *spidev;
// spidev = container_of(dev, struct spidev_data, dev);
// kfree(spidev);
}
//////////////////////////////////////////////////////////////////////
static struct class spidev_class = {
.name = DEVICE_FILE_NAME,
.owner = THIS_MODULE,
.dev_release = spidev_classdev_release,
};
struct file_operations drv_fops =
{
.owner = THIS_MODULE,
.read = drv_read,
.write = drv_write,
.open = device_open,
.release = device_release,
};
static struct spi_driver myspi_driver = {
.driver = {
.name = DEVICE_FILE_NAME,
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = spidev_probe,
.remove = __devexit_p(spidev_remove),
};
int init_module()
{
int err;
if (alloc_chrdev_region(&drv_dev, 0, MINOR_NUM, DEVICE_FILE_NAME))
{
err = -ENODEV;
printk(KERN_INFO "\n Init ERROR: Function: alloc_chrdev_region \n");
goto err_exit;
}
cdev_init(&drv_cdev, &drv_fops);
drv_cdev.owner = THIS_MODULE;
if (cdev_add(&drv_cdev, drv_dev, MINOR_NUM))
{
err = -ENODEV;
printk(KERN_INFO "\n Init ERROR: Function: cdev_add \n");
goto err_dev_unregister;
}
// int status = register_chrdev(MINOR_NUM, DEVICE_FILE_NAME, &drv_dev);
// if (status < 0)
// return status;
if (class_register(&spidev_class) < 0) {
printk(KERN_INFO "\n Init ERROR: Function: spidev_class \n");
goto err_dev_unregister;
}
else
{
printk(KERN_INFO "\n Init OK: Function: spidev_class \n");
}
if (spi_register_driver(&myspi_driver) < 0) {
//class_unregister(&myspi_driver);
printk(KERN_INFO "\n Init ERROR: Function: spi_register \n");
goto err_dev_unregister;
//unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name);
}
else
{
printk(KERN_INFO "\n Init OK: Function: spi_register \n");
}
////////////////////////////////////////////////////////////////
printk(KERN_INFO "%s The major device number is %d.\n",
"Registeration is a success", MAJOR_NUM);
printk(KERN_INFO "If you want to talk to the device driver,\n");
printk(KERN_INFO "you'll have to create a device file. \n");
printk(KERN_INFO "We suggest you use:\n");
printk(KERN_INFO "mknod %s c %d 0\n", DEVICE_FILE_NAME, MAJOR_NUM);
printk(KERN_INFO "The device file name is important, because\n");
printk(KERN_INFO "the ioctl program assumes that's the\n");
printk(KERN_INFO "file you'll use.\n");
/////////////////////////////////////////////////////////////////
return 0;
err_dev_unregister:
class_unregister(&spidev_class);
unregister_chrdev_region(drv_dev, MINOR_NUM);
err_exit:
return err;
}
void cleanup_module()
{
printk(KERN_ALERT "\nINFO: exit \n");
spi_unregister_driver(&myspi_driver);
class_unregister(&spidev_class);
cdev_del(&drv_cdev);
unregister_chrdev_region(drv_dev, MINOR_NUM);
}
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SPI char device driver");
MODULE_AUTHOR("Vaagn Grigoryan");
alexey123
08.06.2009 20:02
Сообщение: 2
0
Пункты: 32
Регистрация: 25.05.2009
а в spi_board_info есть структура, отнсящаяся к вашему драйверу?
Guest (Guest)
09.06.2009 10:46
Сообщение: 3
Здравствуйте alexey123
Ваш вопрос сразу подсказал мне ответ, спасибо.
Я не добавлял описание моего драйвера в структуру spi_board_info.
Форум
»
starterkit.ru
»
Embedded Linux
Темы
Автор
От.
Пр.
Последний
зависает sunxi-fel.exe
rez74
0
40
rez74
Запуск Qt-приложений через webgl на A40i
senyor_pomidor
0
54
senyor_pomidor
Mango-pi T113-S3, Buildroot, оптимизация размера о…
dolmatov
0
51
dolmatov
Работа с кодеками IMX-GPU
geostart
8
284
geostart
SK-iMX6S-SODIMM-Ind, новая eMMC
Pavel Ivanchenko
25
13256
incredi
Mango-pi T113-S3 возможность работы с BLE?
dolmatov
1
90
sasamy
Камера
rez74
1
148
sasamy
настройка CAN bus
Kamil_ufa
6
281
sasamy
QT6 в Buildroot
senyor_pomidor
1
125
sasamy
Ввод данных через консоль Putty по uart
VetalGerq
2
162
VetalGerq
Перевод USB-OTG в режим host
senyor_pomidor
4
262
senyor_pomidor
Нужны 3 порта USB в режиме хост
АрсТерм
3
1147
sasamy
Armbian/ubuntu 24.04 для t507
sasamy
3
899
sasamy
Allwinner T507-H версия сборки
Pavel Ivanchenko
0
256
Pavel Ivanchenko
Зависание системы, помогите разобраться.
NovVal
7
231
murdemon