Гость
Задержка функции .poll в коде драйвера не вступила в силу?
Сообщение
Гость » 13 мар 2024, 16:31
Я добавил драйвер GPIO в код ядра Linux 3.10 и добавил
в код драйвера. Я не знаю, почему я добавил
в
функция тестового кода, но я заметил, что задержка не вступила в силу, когда
был напечатан. Я не знаю, почему? Также могу ли я спросить, уместно ли добавлять мьютекс в функцию обратного вызова прерывания?
#driver code:
Код: Выделить всё
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static int MajorDevNum = 0;
static struct class *SpiioClass;
static int SpiioGpio;
static int IrqOccurred = 0;
static wait_queue_head_t WaitQueue;
struct mutex RWLock;
static ssize_t spiio_drv_read(struct file *file, char __user *buf, size_t size, loff_t *offset)
{
int value = 0;
char userValue = value ? 1:0;
//wake_event_interruptible(wq, IrqOccrred);
userValue = gpio_get_value(SpiioGpio) ? 1 : 0;
printk("read value is %d\n", userValue);
if (copy_to_user(buf, &userValue, sizeof(char) != 0)) {
printk("failed to copy to user\n");
return -1;
} else {
return sizeof(char);
}
}
static ssize_t spiio_drv_write(struct file *file, const char __user *buf, size_t size, loff_t *offset)
{
#if 0
#endif
return -1;
}
static int spiio_drv_open(struct inode *node, struct file *file)
{
printk("this is open\n");
return 0;
}
static int spiio_drv_close(struct inode *node, struct file *file)
{
return 0;
}
static long spiio_drv_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
#if 0
#endif
return 0;
}
static unsigned int spiio_drv_poll(struct file *file, struct poll_table_struct *wait)
{
printk("this is poll.\n");
poll_wait(file, &WaitQueue, wait);
if (IrqOccurred)
{
mutex_lock(&RWLock);
IrqOccurred = 0; //need lock
mutex_unlock(&RWLock);
printk(" an irq occurred. return %d\n", POLLIN);
return POLLIN;
}
printk("no irq occurred, IrqOccurred = %d\n", IrqOccurred);
return 0;
}
static irqreturn_t spiio_irq_handler(int irq, void *dev_id)
{
//pr_info("spiio irq ocurred on IRQ %d\n", irq);
wake_up_interruptible(&WaitQueue);
mutex_lock(&RWLock);
IrqOccurred = 1;
mutex_unlock(&RWLock);
return IRQ_HANDLED;
}
static struct file_operations spiio_drv = {
.owner = THIS_MODULE,
.open = spiio_drv_open,
.read = spiio_drv_read,
.write = spiio_drv_write,
.release = spiio_drv_close,
.unlocked_ioctl = spiio_drv_ioctl,
.poll = spiio_drv_poll,
};
int spiio_probe(struct platform_device *pdev)
{
struct device_node *nd = pdev->dev.of_node;
struct gpio_config config;
printk("gpio count:%d\n", of_gpio_named_count(nd, "spiio_gpio"));
SpiioGpio = of_get_named_gpio_flags(nd, "spiio_gpio", 0, (enum of_gpio_flags *)&config);
if (!gpio_is_valid(SpiioGpio))
{
printk("gpio isn't valid\n");
}
if (gpio_request(SpiioGpio, pdev->name) < 0)
{
printk("gpio request faispiio %d\n", SpiioGpio);
}
if (gpio_direction_input(SpiioGpio) < 0)
{
printk("gpio_direction_input failed %d\n", SpiioGpio);
}
init_waitqueue_head(&WaitQueue);
//if (request_irq(gpio_to_irq(SpiioGpio), spiio_irq_handler, IRQF_TRIGGER_HIGH, "spiio_irq", NULL) < 0)
if (request_irq(gpio_to_irq(SpiioGpio), spiio_irq_handler, IRQF_TRIGGER_RISING, "spiio_irq", NULL) < 0)
{
printk("requst_irq failed\n");
}
MajorDevNum = register_chrdev(0, "spiio", &spiio_drv); /* /dev/spiio */
if (MajorDevNum < 0)
{
printk("failed to get major device number\n");
}
SpiioClass = class_create(THIS_MODULE, "spiio_class");
if (IS_ERR(SpiioClass))
{
printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
unregister_chrdev(MajorDevNum, "spiio");
gpio_free(SpiioGpio);
return PTR_ERR(SpiioClass);
}
device_create(SpiioClass, NULL, MKDEV(MajorDevNum, 0), NULL, "spiio%d", 0); /* /dev/100ask_spiio0 */
mutex_init(&RWLock);
printk("gpio is ok, registered GPIO: %d\n", SpiioGpio);
return 0;
}
int spiio_remove(struct platform_device *pdev)
{
free_irq(gpio_to_irq(SpiioGpio), NULL);
device_destroy(SpiioClass, MKDEV(MajorDevNum, 0));
class_destroy(SpiioClass);
unregister_chrdev(MajorDevNum, "spiio");
gpio_free(SpiioGpio);
mutex_destroy(&RWLock);
printk("gpio remove ...\n");
return 0;
}
struct of_device_id ids[] = {
{.compatible = "dobot, spiio"},
{},
};
static struct platform_driver chip_demo_gpio_driver = {
.probe = spiio_probe,
.remove = spiio_remove,
.driver = {
.name = "spiio",
.of_match_table = ids,
},
};
static int __init spiio_init(void)
{
int err;
err = platform_driver_register(&chip_demo_gpio_driver);
return err;
}
тестовый код:
Код: Выделить всё
#include "spidev.h"
#include
#include
int SpiDevFd = 0;
struct _SPI_Settings spi_settings;
int ReadData(int fd)
{
int ret = 0;
int ret2 = 0;
char buffer[2] = {0};
short revents;
struct pollfd pfd;
int timeout_ms = 8;
pfd.fd = fd;
pfd.events = POLLIN;
uint8_t tx[256] = {0};
for (int i = 0; i
Источник: [url]https://stackoverflow.com/questions/78154194/the-delay-of-the-poll-function-in-the-driver-code-has-not-taken-effect[/url]
1710336706
Гость
Я добавил драйвер GPIO в код ядра Linux 3.10 и добавил[code].poll[/code] в код драйвера. Я не знаю, почему я добавил[code]8ms[/code] в[code]pull[/code] функция тестового кода, но я заметил, что задержка не вступила в силу, когда[code]dmesg[/code] был напечатан. Я не знаю, почему? Также могу ли я спросить, уместно ли добавлять мьютекс в функцию обратного вызова прерывания? #driver code: [code]#include #include #include #include #include #include #include #include #include #include #include #include #include #include static int MajorDevNum = 0; static struct class *SpiioClass; static int SpiioGpio; static int IrqOccurred = 0; static wait_queue_head_t WaitQueue; struct mutex RWLock; static ssize_t spiio_drv_read(struct file *file, char __user *buf, size_t size, loff_t *offset) { int value = 0; char userValue = value ? 1:0; //wake_event_interruptible(wq, IrqOccrred); userValue = gpio_get_value(SpiioGpio) ? 1 : 0; printk("read value is %d\n", userValue); if (copy_to_user(buf, &userValue, sizeof(char) != 0)) { printk("failed to copy to user\n"); return -1; } else { return sizeof(char); } } static ssize_t spiio_drv_write(struct file *file, const char __user *buf, size_t size, loff_t *offset) { #if 0 #endif return -1; } static int spiio_drv_open(struct inode *node, struct file *file) { printk("this is open\n"); return 0; } static int spiio_drv_close(struct inode *node, struct file *file) { return 0; } static long spiio_drv_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { #if 0 #endif return 0; } static unsigned int spiio_drv_poll(struct file *file, struct poll_table_struct *wait) { printk("this is poll.\n"); poll_wait(file, &WaitQueue, wait); if (IrqOccurred) { mutex_lock(&RWLock); IrqOccurred = 0; //need lock mutex_unlock(&RWLock); printk(" an irq occurred. return %d\n", POLLIN); return POLLIN; } printk("no irq occurred, IrqOccurred = %d\n", IrqOccurred); return 0; } static irqreturn_t spiio_irq_handler(int irq, void *dev_id) { //pr_info("spiio irq ocurred on IRQ %d\n", irq); wake_up_interruptible(&WaitQueue); mutex_lock(&RWLock); IrqOccurred = 1; mutex_unlock(&RWLock); return IRQ_HANDLED; } static struct file_operations spiio_drv = { .owner = THIS_MODULE, .open = spiio_drv_open, .read = spiio_drv_read, .write = spiio_drv_write, .release = spiio_drv_close, .unlocked_ioctl = spiio_drv_ioctl, .poll = spiio_drv_poll, }; int spiio_probe(struct platform_device *pdev) { struct device_node *nd = pdev->dev.of_node; struct gpio_config config; printk("gpio count:%d\n", of_gpio_named_count(nd, "spiio_gpio")); SpiioGpio = of_get_named_gpio_flags(nd, "spiio_gpio", 0, (enum of_gpio_flags *)&config); if (!gpio_is_valid(SpiioGpio)) { printk("gpio isn't valid\n"); } if (gpio_request(SpiioGpio, pdev->name) < 0) { printk("gpio request faispiio %d\n", SpiioGpio); } if (gpio_direction_input(SpiioGpio) < 0) { printk("gpio_direction_input failed %d\n", SpiioGpio); } init_waitqueue_head(&WaitQueue); //if (request_irq(gpio_to_irq(SpiioGpio), spiio_irq_handler, IRQF_TRIGGER_HIGH, "spiio_irq", NULL) < 0) if (request_irq(gpio_to_irq(SpiioGpio), spiio_irq_handler, IRQF_TRIGGER_RISING, "spiio_irq", NULL) < 0) { printk("requst_irq failed\n"); } MajorDevNum = register_chrdev(0, "spiio", &spiio_drv); /* /dev/spiio */ if (MajorDevNum < 0) { printk("failed to get major device number\n"); } SpiioClass = class_create(THIS_MODULE, "spiio_class"); if (IS_ERR(SpiioClass)) { printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__); unregister_chrdev(MajorDevNum, "spiio"); gpio_free(SpiioGpio); return PTR_ERR(SpiioClass); } device_create(SpiioClass, NULL, MKDEV(MajorDevNum, 0), NULL, "spiio%d", 0); /* /dev/100ask_spiio0 */ mutex_init(&RWLock); printk("gpio is ok, registered GPIO: %d\n", SpiioGpio); return 0; } int spiio_remove(struct platform_device *pdev) { free_irq(gpio_to_irq(SpiioGpio), NULL); device_destroy(SpiioClass, MKDEV(MajorDevNum, 0)); class_destroy(SpiioClass); unregister_chrdev(MajorDevNum, "spiio"); gpio_free(SpiioGpio); mutex_destroy(&RWLock); printk("gpio remove ...\n"); return 0; } struct of_device_id ids[] = { {.compatible = "dobot, spiio"}, {}, }; static struct platform_driver chip_demo_gpio_driver = { .probe = spiio_probe, .remove = spiio_remove, .driver = { .name = "spiio", .of_match_table = ids, }, }; static int __init spiio_init(void) { int err; err = platform_driver_register(&chip_demo_gpio_driver); return err; } [/code] тестовый код: [code]#include "spidev.h" #include #include int SpiDevFd = 0; struct _SPI_Settings spi_settings; int ReadData(int fd) { int ret = 0; int ret2 = 0; char buffer[2] = {0}; short revents; struct pollfd pfd; int timeout_ms = 8; pfd.fd = fd; pfd.events = POLLIN; uint8_t tx[256] = {0}; for (int i = 0; i Источник: [url]https://stackoverflow.com/questions/78154194/the-delay-of-the-poll-function-in-the-driver-code-has-not-taken-effect[/url]