Я добавил драйвер GPIO в код ядра Linux 3.10 и добавил
Код: Выделить всё
.pollКод: Выделить всё
8msКод: Выделить всё
pullКод: Выделить всё
dmesg#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]