Ник:
Пароль:

Контакты

E-mail: info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм: t.me/starterkit_ru
Партнеры:
otladka.com.ua - г.Киев

Способы оплаты

User Info


Добро пожаловать,
Guest

Регистрация или входРегистрация или вход
Потеряли пароль?Потеряли пароль?

Ник:
Пароль:

ПользователейПользователей:0
Поисковых ботовПоисковых ботов:3
ГостейГостей:1

ОбновитьПодробнееВсегоВсего:4
Форум » starterkit.ru » Embedded Linux
Вопрос по созданию драйвера
Pavel Ivanchenko
Добавлено 08.06.2009 19:36
0
Сообщение: 1
Pavel Ivanchenko
Admin
4.39

Пункты: 91348
Регистрация: 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
alexey123
0

Пункты: 32
Регистрация: 25.05.2009
а в spi_board_info есть структура, отнсящаяся к вашему драйверу?
Спуститься к концу Подняться к началу
Персональная информация
Guest (Guest)
Добавлено 09.06.2009 10:46 Сообщение: 3
Guest (Guest)

Здравствуйте alexey123
Ваш вопрос сразу подсказал мне ответ, спасибо.
Я не добавлял описание моего драйвера в структуру spi_board_info.
Спуститься к концу Подняться к началу
Форум » starterkit.ru » Embedded Linux