#define LED_ON _IOW('l',1,int *) #define LED_OFF _IOW('l',0,int *)
text.c
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include "head.h" int main(int argc,const char * argv[]) { int a; int b; while(1) { int fd; //Get the function we want to implement from the interrupt printf("Please select the lights to be controlled: 1-LED1, 2-LED2, 3-LED3\\ "); scanf("%d", & amp;a); switch(a) { case 1: fd = open("/dev/mycdev0",O_RDWR); break; case 2: fd = open("/dev/mycdev1",O_RDWR); break; case 3: fd = open("/dev/mycdev2",O_RDWR); break; } if(fd<0) { printf("Failed to open device file\\ "); return -1; } printf("Open device file successfully\\ "); printf("Please enter the function you want to implement"); printf("0(lights off)1(lights on)\\ "); printf("Please enter:"); scanf("%d", & amp;b); switch (b) { case 1: ioctl(fd,LED_ON, & amp;b); break; case 0: ioctl(fd,LED_OFF, & amp;b); break; } close(fd); } return 0; }
pdrv.c
#include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/mod_devicetable.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/gpio.h> #include "head.h" #include <linux/device.h> #include <linux/cdev.h> #include <linux/slab.h> #include <linux/kdev_t.h> #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/io.h> struct cdev* cdev; unsigned int major=0; unsigned int minor=0; dev_t devno; struct class* cls; struct device *dev; struct resource *res; struct gpio_desc *gpiono[3]; //Build device tree matching table struct of_device_id oftable[]={ {.compatible="Yuki,myplatform",}, {.compatible="Yuki,myplatform1",}, {},//Prevent crossing the boundary }; struct platform_device_id idtable[]= { {"aaaaa",0}, {"bbbbb",1}, {"ccccc",2}, {"dddd",3}, {}, }; /************************************************/ int mycdev_open(struct inode * inode,struct file* file) { unsigned int min=MINOR(inode->i_rdev);//Get the minor device number of the opened file file->private_data=(void *)min; printk("%s:%s:%d\\ ",__FILE__,__func__,__LINE__); return 0; } int mycdev_close(struct inode * indode,struct file* file) { printk("%s:%s:%d\\ ",__FILE__,__func__,__LINE__); return 0; } long mycdev_ioctl(struct file *file,unsigned int cmd,unsigned long arg) { int min=(int)file->private_data;//Get the minor device number of the file switch(min) { case 0://LED1 switch(cmd) { case LED_ON://turn on the light gpiod_set_value(gpiono[0],1); break; case LED_OFF://turn off the light gpiod_set_value(gpiono[0],0); break; } break; case 1://LED2 switch(cmd) { case LED_ON://turn on the light gpiod_set_value(gpiono[1],1); break; case LED_OFF://turn off the light gpiod_set_value(gpiono[1],0); break; } break; case 2://LED3 switch(cmd) { case LED_ON://turn on the light gpiod_set_value(gpiono[2],1); break; case LED_OFF://turn off the light gpiod_set_value(gpiono[2],0); break; } break; } printk("%s:%s:%d\\ ",__FILE__,__func__,__LINE__); return 0; } struct file_operations fops = { .open=mycdev_open, .unlocked_ioctl = mycdev_ioctl, .release=mycdev_close, }; //Executed when the driver and device are successfully matched int pdrv_probe(struct platform_device *pdev) { int i; /******************************************/ //1. Apply for an object space cdev_alloc int ret; cdev=cdev_alloc(); if(cdev==NULL) { printk("Failed to apply for character device driver object space\\ "); ret =-EFAULT; goto out1; } printk("Application for character device driver object space successful\\ "); //2.Initialize object cdev_init cdev_init(cdev, & amp;fops); //3. Apply for device number register_chrdev_region()/alloc_chrdev_region() if(major==0)//Dynamic application { ret=alloc_chrdev_region( & amp;devno,minor,3,"mychrdev"); if(ret) { printk("Dynamic application for device number failed\\ "); goto out2; } major=MAJOR(devno);//Get the major device number based on the device number minor=MINOR(devno);//Get the minor device number based on the device number } else//static application { ret=register_chrdev_region(MKDEV(major,minor),3,"mychrdev"); if(ret) { printk("Static application for device number failed\\ "); goto out2; } } printk("Device number application successful\\ "); //4. Register driver object cdev_add ret=cdev_add(cdev,MKDEV(major,minor),3); if(ret) { printk("Failed to register character device driver object\\ "); goto out3; } printk("Registration of character device driver object successful\\ "); //5. Submit the directory upward class_create cls=class_create(THIS_MODULE,"mychrdev"); if(IS_ERR(cls)) { printk("Failed to access the submission directory\\ "); goto out4; } printk("I want to upload the submission directory successfully\\ "); //6. Submit device node information upward device_create for(i=0;i<3;i + + ) { dev=device_create(cls,NULL,MKDEV(major,i),NULL,"mycdev%d",i); if(IS_ERR(dev)) { printk("Failed to submit device node\\ "); goto out5; } } printk("I want to submit the device node successfully\\ "); /************************************************/ //Get gpio information for(i=0;i<3;i + + ) { gpiono[i]=gpiod_get_from_of_node(pdev->dev.of_node,"led-gpios",i,GPIOD_OUT_HIGH,NULL); if(IS_ERR(gpiono[i])) { printk("Failed to parse gpio information\\ "); return -PTR_ERR(gpiono[i]); } printk("Parsing gpio information successfully\\ "); //Initialize to 0 gpiod_set_value(gpiono[i],0); } return 0; /****************************************************** ***/ out5: //When submitting the device node fails, the successfully submitted node will be released. for(i--;i>=0;i--) { device_destroy(cls,MKDEV(major,i)); } //Destroy directory class_destroy(cls); out4: cdev_del(cdev); out3: unregister_chrdev_region(MKDEV(major,minor),3); out2: kfree(cdev); out1: return ret; } int pdrv_remove(struct platform_device *pdev) { int i; //1. Destroy device node information for(i=0;i<3;i + + ) { device_destroy(cls,MKDEV(major,i)); } //2. Destroy the directory class_destroy(cls); //3. Unregister the character device driver object cdev_del(cdev); //4. Release the device number unregister_chrdev_region(MKDEV(major,minor),3); //5. Release the applied character device driver object space kfree(cdev); //Release gpio information for(i=0;i<3;i + + ) { gpiod_set_value(gpiono[i],0); gpiod_put(gpiono[i]); } return 0; } //1. Allocate driver information object struct platform_driver pdrv={ .probe=pdrv_probe, .remove=pdrv_remove, .driver={ .name="aaaaa",//Driver name, corresponding to the device .of_match_table=oftable, }, .id_table=idtable, }; //Register macro with one click module_platform_driver(pdrv); MODULE_LICENSE("GPL");
Platform-based button external interrupt control LED
#include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/mod_devicetable.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/gpio.h> #include <linux/interrupt.h> struct resource *res; unsigned int irqno[3]; bool a=0,b=0,c=0; struct gpio_desc *gpiono[3]; //Build device tree matching table struct of_device_id oftable[]={ {.compatible="Yuki,myplatform",}, {.compatible="Yuki,myplatform1",}, {},//Prevent crossing the boundary }; struct platform_device_id idtable[]= { {"aaaaa",0}, {"bbbbb",1}, {"ccccc",2}, {"dddd",3}, {}, }; irqreturn_t key_handler(int irq,void *dev) { switch ((unsigned int)dev) { case 0: gpiod_set_value(gpiono[0],!a); a=!a; break; case 1: gpiod_set_value(gpiono[1],!b); b=!b; break; case 2: gpiod_set_value(gpiono[2],!c); c=!c; break; } return IRQ_HANDLED; } //Executed when the driver and device are successfully matched int pdrv_probe(struct platform_device *pdev) { int i; int ret; //Get gpio information for(i=0;i<3;i + + ) { //Get interrupt type resources irqno[i]=platform_get_irq(pdev,i); if(irqno[i]<0) { printk("Failed to obtain interrupt type resource\\ "); } //Registration interrupted ret=request_irq(irqno[i],key_handler,IRQF_TRIGGER_FALLING,"keyi",(void *)i); if(ret<0) { printk("Registration interruption failed\\ "); } printk("Registration interrupt %d successful\\ ",i); gpiono[i]=gpiod_get_from_of_node(pdev->dev.of_node,"led-gpios",i,GPIOD_OUT_HIGH,NULL); if(IS_ERR(gpiono[i])) { printk("Failed to parse gpio information\\ "); return -PTR_ERR(gpiono[i]); } printk("Parsing gpio information successfully\\ "); //Initialize to 0 gpiod_set_value(gpiono[i],0); } return 0; } int pdrv_remove(struct platform_device *pdev) { int i; for(i=0;i<3;i + + ) { gpiod_set_value(gpiono[i],0); gpiod_put(gpiono[i]); } return 0; } //1. Allocate driver information object struct platform_driver pdrv={ .probe=pdrv_probe, .remove=pdrv_remove, .driver={ .name="aaaaa",//Driver name, corresponding to the device .of_match_table=oftable, }, .id_table=idtable, }; //Register macro with one click module_platform_driver(pdrv); MODULE_LICENSE("GPL");
The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. C Skill Tree Home Page Overview 193774 people are learning the system