OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3523|回复: 1

关于linux内核定时器,进入定时器了,但是指令输入灯立马就亮了

[复制链接]

2

主题

2

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2022-6-10
在线时间
1 小时
发表于 2022-6-10 19:21:57 | 显示全部楼层 |阅读模式
在阿尔法开发板上仿真,编写了一个led的定时驱动,发现没有作用,代码如下:
/*
* @Author: wphuicctv
* @Date: 2022-06-06 11:18:38
* @LastEditors: wphuicctv
* @LastEditTime: 2022-06-10 19:14:30
* @FilePath: /imx6ullirq/ledkeyirq.c
* @Description:
*
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/of_gpio.h>
#include <linux/timer.h>
#include <linux/of_irq.h>
#include <linux/semaphore.h>

#define KEYIRQ_NUM         1
#define KEYIRQ_NAME "ledkeyirq"
#define LEDON       1
#define LEDOFF      0

struct keyirq_dev {
        dev_t devid;
        struct cdev cdev;
        struct class *class;
        struct device *device;
        struct timer_list timer;
        struct device_node *node;
        int major;
        int minor;
        int led_gpio;
        int key_gpio;
};

struct keyirq_dev keyirq;

static int led_gpio_init(void)
{
        int ret;

        keyirq.node = of_find_node_by_path("/gpioled");
        if(keyirq.node == NULL)
        {
                printk("node find failed!\r\n");
                return -EINVAL;
        }

        keyirq.led_gpio = of_get_named_gpio(keyirq.node, "led-gpio", 0);
        if(keyirq.led_gpio < 0)
        {
                printk("gpio get failed!\r\n");
                return -EINVAL;
        }
       
        gpio_request(keyirq.led_gpio, "led");
        ret = gpio_direction_output(keyirq.led_gpio, 1);
        if(ret < 0)
        {
                printk("gpio direction set failed!\r\n");
        }

        printk("led gpio set successfull\r\n");
        return 0;
}

void led_timer_function(unsigned long arg)
{
        struct keyirq_dev *dev = (struct keyirq_dev *)arg;

        mod_timer(&keyirq.timer, (jiffies + msecs_to_jiffies(3000)));
}

/*static int led_timer_init(void)
{
        init_timer(&keyirq.timer);
        keyirq.timer.function = &led_timer_function;
        keyirq.timer.data = (unsigned long)&keyirq;
        keyirq.timer.expires = jiffies + msecs_to_jiffies(2000);
        //add_timer(&keyirq.timer);
        printk("timer set successfull\r\n");
}*/



static int keyirq_open(struct inode *inode, struct file *filp)
{
        //int ret;
        filp->private_data = &keyirq;

        init_timer(&keyirq.timer);
        keyirq.timer.function = led_timer_function;
        keyirq.timer.data = (unsigned long)&keyirq;
        keyirq.timer.expires = (jiffies + msecs_to_jiffies(3000));
        //add_timer(&keyirq.timer);
        printk("timer set successfull\r\n");

        return 0;
}

static ssize_t keyirq_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
{
        return 0;
}

static ssize_t keyirq_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{
        int retvalue;
        //int ret = 0;
        unsigned char databuf[1];
        unsigned char ledstatus;
        struct keyirq_dev *dev = filp->private_data;

        retvalue = copy_from_user(databuf, buf, cnt);
        if(retvalue < 0)
        {
                printk("kernel write err\r\n");
                return -EFAULT;
        }

        ledstatus = databuf[0];
        //ret = led_timer_init();
        if(ledstatus == LEDOFF)
        {
                gpio_set_value(dev->led_gpio, 1);
                printk("LEDOFF\r\n");
        }
        else if(ledstatus = LEDON)
        {
                printk("LEDON\r\n");
                gpio_set_value(dev->led_gpio, 0);
        }
        return 0;
}

static int keyirq_release(struct inode *inode, struct file *filp)
{
        del_timer_sync(&keyirq.timer);
        return 0;
}

static struct file_operations keyirq_fops = {
        .owner = THIS_MODULE,
        .open = keyirq_open,
        .read = keyirq_read,
        .write = keyirq_write,
        .release = keyirq_release,
};

static int __init keyirq_init(void)
{

        if(keyirq.major)
        {
                keyirq.devid = MKDEV(keyirq.major, 0);
                register_chrdev_region(keyirq.devid, KEYIRQ_NUM, KEYIRQ_NAME);
        }
        else
        {
                alloc_chrdev_region(&keyirq.devid, 0, KEYIRQ_NUM, KEYIRQ_NAME);
                keyirq.major = MAJOR(keyirq.devid);
                keyirq.minor = MINOR(keyirq.devid);
        }
        printk("major = %d, minor = %d\r\n", keyirq.major, keyirq.minor);

        keyirq.cdev.owner = THIS_MODULE;
        cdev_init(&keyirq.cdev, &keyirq_fops);

        cdev_add(&keyirq.cdev, keyirq.devid, KEYIRQ_NUM);

        keyirq.class = class_create(THIS_MODULE, KEYIRQ_NAME);
        if(IS_ERR(keyirq.class))
        {
                printk("class create failed!\r\n");
                return PTR_ERR(keyirq.class);
        }

        keyirq.device = device_create(keyirq.class, NULL, keyirq.devid, NULL, KEYIRQ_NAME);
        if(IS_ERR(keyirq.device))
        {
                printk("device create failed!\r\n");
                return PTR_ERR(keyirq.device);
        }
        led_gpio_init();


        return 0;
}


static void __exit keyirq_exit(void)
{
        gpio_set_value(keyirq.led_gpio, 1);
       
        cdev_del(&keyirq.cdev);

        unregister_chrdev_region(keyirq.devid, KEYIRQ_NUM);

        device_destroy(keyirq.class, keyirq.devid);

        class_destroy(keyirq.class);

        gpio_free(keyirq.led_gpio);



        printk("module removed\r\n");
       
}

module_init(keyirq_init);
module_exit(keyirq_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("WPHUICCTV");

麻烦帮忙看看为什么







正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

200

帖子

0

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
1063
金钱
1063
注册时间
2019-9-19
在线时间
194 小时
发表于 2022-6-11 10:06:36 | 显示全部楼层
直接用例程源码测试下,基于自己移植的内核来做教程实验,不能在默认出厂系统去加载实验的驱动,因为设备树写法不一样,也可能引脚被占用了;对比例程,检查代码是否有问题,驱动是否加载成功
=======================
出征,嗒嗒嗒——
快点上车!
=======================
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 10:54

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表