IMX6ULL开发板Linux C语言 timer学习笔记

IMX6ULL开发板Linux C语言 timer学习笔记

解决方案goocz2025-05-30 12:24:066A+A-

#define TIMER_CNT 1 /*设备号个数*/

#define TIMER_NAME "timer" /*名字*/

/*3.1:设备结构体*/

struct timerdev_dev{

dev_t devid; /*设备号*/

int major; /*主设备号*/

int minor;

struct cdev cdev;/*3.3.1结构体里先定义字符设备*/

struct class *class; /*4.1:类*/

struct device *device; /*4.1:设备*/

struct device_node *nd; /*5.1设备节点*/

struct timer_list timer; /*定时器*/

int led_gpio;

};

struct timerdev_dev timerdev; /*3.2:led设备*/

static int timer_open(struct inode *inode, struct file *filp)

{


filp->private_data = &timerdev;

return 0;

}

static ssize_t timer_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)

{

return 0;

}

static ssize_t timer_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)

{

int ret;


return 0;

}

static int timer_release(struct inode *inode, struct file *filp)

{


return 0;

}

static const struct file_operations timerdev_fops = { /*3.4.1:定义字符设备操作集*/

.owner = THIS_MODULE,

.write = timer_write,

.open = timer_open,

.release = timer_release,

};

/*定时器处理函数*/

static void timer_func(unsigned long arg)

{


struct timer_dev *dev = (struct timer_dev*)arg;

static int sta = 1;

sta = !sta;

gpio_set_value(timerdev.led_gpio, sta);


mod_timer(&timerdev.timer, jiffies + msecs_to_jiffies(500));

}

/*初始化LED灯*/

int led_init(struct timer_dev *dev)

{


int ret = 0;

timerdev.nd = of_find_node_by_path("/gpioled");

if(timerdev.nd == NULL){

ret = -EINVAL;

goto fail_fd;

}

timerdev.led_gpio = of_get_named_gpio(timerdev.nd, "led-gpios", 0);

if(timerdev.led_gpio < 0){

ret = -EINVAL;

goto fail_gpio;

}


ret = gpio_request(timerdev.led_gpio, "led");

if(ret) {

ret = -EBUSY;

printk("IO %d can't request!\r\n", timerdev.led_gpio);

goto fail_request;

}

ret = gpio_direction_output(timerdev.led_gpio, 1);/*默认电平高关灯*/

if(ret < 0) {

ret = -EINVAL;

goto fail_gpioset;

}

return 0;

fail_gpioset:

gpio_free(timerdev.led_gpio);

fail_request:

fail_gpio:

fail_fd:

return ret;

}

/*2.入口函数*/

static int __init timer_init(void)

{

int ret = 0;

/*初始化信号量*/

/*3:注册字符设备*/

/*3.0:注册字符设备号*/

timerdev.major = 0;/*3.2:表示设备号由内核分配*/

if(timerdev.major){ /*如果分配了设备号*/

timerdev.devid = MKDEV(timerdev.major, 0);/*那么主设备号和次设备号进行拼凑*/

ret = register_chrdev_region(timerdev.devid, TIMER_CNT, TIMER_NAME);

}else { /*如果没有分配了设备号,那么要申请一个设备号*/

ret = alloc_chrdev_region(&timerdev.devid, 0, TIMER_CNT, TIMER_NAME);

timerdev.major = MAJOR(timerdev.devid);

timerdev.minor = MINOR(timerdev.devid);

}

printk("timerdev major = %d, minor =%d\r\n", timerdev.major, timerdev.minor);

if (ret < 0){

goto fail_devid;

}

/*3.3:添加字符设备*/

timerdev.cdev.owner = THIS_MODULE;

cdev_init(&timerdev.cdev, &timerdev_fops); /*3.4初始化cdev()里第二个参数就是字符设备的操作集见3.4.1*/

ret = cdev_add(&timerdev.cdev, timerdev.devid, TIMER_CNT);

if (ret < 0){

goto fail_cdevadd;

}

/*4:自动创建设备节点*/

timerdev.class = class_create(THIS_MODULE, TIMER_NAME);

if(IS_ERR(timerdev.class)){

ret = PTR_ERR(timerdev.class);

goto fail_class;

}

timerdev.device = device_create(timerdev.class, NULL, timerdev.devid, NULL, TIMER_NAME);

if(IS_ERR(timerdev.device)){

ret = PTR_ERR(timerdev.device);

goto fail_device;

}

/*初始化led灯*/

ret = led_init(&timerdev.timer);

if(ret <0){

goto fail_ledinit;

}

/*初始化定时器*/

init_timer(&timerdev.timer);

timerdev.timer.function = timer_func;

timerdev.timer.expires = jiffies + msecs_to_jiffies(500); /*定时500毫秒*/

timerdev.timer.data = (unsigned long)&timerdev;

add_timer(&timerdev.timer);/*添加到系统*/

return 0;

fail_ledinit:

fail_device:

class_destroy(timerdev.class);

fail_class:

cdev_del(&timerdev.cdev);

fail_cdevadd:

unregister_chrdev_region(timerdev.devid, TIMER_CNT);

fail_devid:

return ret;

}

static void __exit timer_exit(void)

{

gpio_set_value(timerdev.led_gpio, 1);

del_timer(&timerdev.timer);

/*3.5删除字符设备*/

cdev_del(&timerdev.cdev);

/*3.5.1释放设备号*/

unregister_chrdev_region(timerdev.devid, TIMER_CNT);

device_destroy(timerdev.class, timerdev.devid);

/*摧毁类*/

class_destroy(timerdev.class);

gpio_free(timerdev.led_gpio);

}

/*1.注册驱动和卸载驱动*/

module_init(timer_init);

module_exit(timer_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("ZXL");

点击这里复制本文地址 以上内容由goocz整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

果子教程网 © All Rights Reserved.  蜀ICP备2024111239号-5