基于GPIO子系统编写LED驱动,编写应用程序进行测试,设置定时器,5秒钟打印一次hello world
驱动代码
- #include
- #include
- #include
- #include
- #include
- #include
-
- struct device_node *dnode;
- struct gpio_desc *gpiono1;
- struct gpio_desc *gpiono2;
- struct gpio_desc *gpiono3;
- struct timer_list mytimer;
-
- struct class *cls;
- struct device *dev;
- int major;
- char kbuf[128]={0};
-
- //定时器处理函数
- void mytimer_funtion(struct timer_list *timer)
- {
- printk("hello world");
- mod_timer(timer,jiffies+5*HZ);
- }
-
- int mycdev_open(struct inode *inode,struct file *file)
- {
- printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
- return 0;
- }
- ssize_t mycdev_read(struct file *file,char *ubuf,size_t size,loff_t *lof)
- {
- printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
- int ret=copy_to_user(ubuf,kbuf,size);
- if(ret)
- {
- printk("copy_to_user filed\n");
- return -EIO;
- }
- return 0;
- }
-
- ssize_t mycdev_write(struct file *file,const char *ubuf,size_t size,loff_t *lof)
- {
- printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
- int ret=copy_from_user(kbuf,ubuf,size);
- if(ret)
- {
- printk("copy_from_user filed\n");
- return -EIO;
- }
- //设定该GPIO管脚的输出值
- if(kbuf[0]=='0')
- {
- gpiod_set_value(gpiono1,0);
- gpiod_set_value(gpiono2,0);
- gpiod_set_value(gpiono3,0);
- }
- else if(kbuf[0]=='1')
- {
- gpiod_set_value(gpiono1,1);
- gpiod_set_value(gpiono2,1);
- gpiod_set_value(gpiono3,1);
- }
- return 0;
- }
-
- int mycdev_close(struct inode *inode,struct file *file)
- {
- printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
- return 0;
- }
-
- struct file_operations fops ={
- .open=mycdev_open,
- .read=mycdev_read,
- .write=mycdev_write,
- .release=mycdev_close,
- };
-
- static int __init mycdev_init(void)
- {
-
- // 字符设备驱动注册
- major = register_chrdev(0, "mychrdev", &fops);
- if (major < 0)
- {
- printk("字符设备驱动注册失败\n");
- return major;
- }
- printk("字符设备驱动注册成功:major=%d\n", major);
- // 向上提交目录
- cls = class_create(THIS_MODULE, "mychrdev");
- if (IS_ERR(cls))
- {
- printk("向上提交目录失败\n");
- return -PTR_ERR(cls);
- }
- printk("向上提交目录成功\n");
- // 向上提交设备节点信息
- int i; // 向上提交三次设备节点信息
- for (i = 0; i < 3; i++)
- {
- dev = device_create(cls, NULL, MKDEV(major, i), NULL, "myled%d", i);
- if (IS_ERR(dev))
- {
- printk("向上提交设备节点失败\n");
- return -PTR_ERR(dev);
- }
- }
- printk("向上提交设备节点成功\n");
-
- //解析设备树节点信息
- dnode=of_find_node_by_path("/myled");
- if(dnode==NULL)
- {
- printk("解析设备树节点失败\n");
- return -ENXIO;
- }
- //获取LED1 GPIO编号
- gpiono1=gpiod_get_from_of_node(dnode,"led1-gpio",0,GPIOD_OUT_LOW,NULL);
- if(IS_ERR(gpiono1))
- {
- printk("申请gpiono1信息失败\n");
- return -PTR_ERR(gpiono1);
- }
- gpiono2=gpiod_get_from_of_node(dnode,"led2-gpio",0,GPIOD_OUT_LOW,NULL);
- if(IS_ERR(gpiono2))
- {
- printk("申请gpiono3信息失败\n");
- return -PTR_ERR(gpiono2);
- }
- gpiono3=gpiod_get_from_of_node(dnode,"led3-gpio",0,GPIOD_OUT_LOW,NULL);
- if(IS_ERR(gpiono3))
- {
- printk("申请gpiono3信息失败\n");
- return -PTR_ERR(gpiono3);
- }
-
- //初始化定时器对象
- timer_setup(&mytimer,mytimer_funtion,0);
- mytimer.expires=jiffies+HZ;
-
- //注册定时器
- add_timer(&mytimer);
-
- return 0;
- }
- static void __exit mycdev_exit(void)
- {
- del_timer(&mytimer);
- gpiod_set_value(gpiono3,0);
- gpiod_put(gpiono3);
- gpiod_set_value(gpiono3,0);
- gpiod_put(gpiono3);
- gpiod_set_value(gpiono3,0);
- gpiod_put(gpiono3);
-
- // 销毁设备节点信息
- int i;
- for (i = 0; i < 3; i++)
- {
- device_destroy(cls, MKDEV(major, i));
- }
- // 销毁目录
- class_destroy(cls);
- // 注销字符设备驱动
- unregister_chrdev(major, "mychrdev");
-
- }
- module_init(mycdev_init);
- module_exit(mycdev_exit);
- MODULE_LICENSE("GPL");
应用代码
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- /* According to earlier standards */
- #include
- int fd1,fd2,fd3;
- char buf[128] ={0};
- int main(int argc, char const *argv[])
- {
- fd1 = open("/dev/myled0", O_RDWR);
- if (fd1 < 0)
- {
- printf("打开设备文件失败\n");
- exit(-1);
- }
- while (1)
- {
- printf("请输入0(关灯),1(开灯):");
- fgets(buf,sizeof(buf),stdin);
- //write(fd2,buf,1);
- //write(fd3,buf,1);
- buf[strlen(buf)-1]='\0';
- write(fd1,buf,sizeof(buf));
- }
- close(fd1);
-
- return 0;
- }
现象:

