/* * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git * @Date: 2023-08-19 09:31:52 * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git * @LastEditTime: 2023-09-16 17:08:09 * @FilePath: /3-new-led/led.c * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE */ #include #include #include #include #include #include #include #include #include #include #include #include #include /*** * configuration */ // DEV_NAME #define dev_name "newchr" // DEV_ID配置 #define DEV_ID_STATIC 1 #if DEV_ID_STATIC #define DEV_ID_MAJOR 80 #define DEV_ID_MINOR 0 #endif /** * GPIO Control Code */ /* 映射后的寄存器虚拟地址指针 */ static void __iomem *MPU_AHB4_PERIPH_RCC_PI; static void __iomem *GPIOI_MODER_PI; static void __iomem *GPIOI_OTYPER_PI; static void __iomem *GPIOI_OSPEEDR_PI; static void __iomem *GPIOI_PUPDR_PI; static void __iomem *GPIOI_BSRR_PI; void led_unmap(void) { /* 取消映射 */ iounmap(MPU_AHB4_PERIPH_RCC_PI); iounmap(GPIOI_MODER_PI); iounmap(GPIOI_OTYPER_PI); iounmap(GPIOI_OSPEEDR_PI); iounmap(GPIOI_PUPDR_PI); iounmap(GPIOI_BSRR_PI); } void led_switch(u8 sta) { u32 val = 0; if(sta == '1') { val = readl(GPIOI_BSRR_PI); val |= (1 << 16); writel(val, GPIOI_BSRR_PI); }else if(sta == '0') { val = readl(GPIOI_BSRR_PI); val|= (1 << 0); writel(val, GPIOI_BSRR_PI); } } struct _dev_info { dev_t dev_id; struct cdev cdev; struct class *class; struct device *device; } dev_info = {0}; /*** * code */ static ssize_t tis_module_read(struct file *file, char __user *out, size_t size, loff_t *offt) { printk("%s: module read\n", dev_name); return 0; } static ssize_t tis_module_write(struct file *file, const char __user *in, size_t size, loff_t *offt) { // printk("%s: module write\n", dev_name); char ch[1]; copy_from_user(ch,in,1); printk("get data:%d",ch[0]); led_switch(ch[0]); return 0; } static int tis_module_open(struct inode *inode, struct file *file) { printk("%s: module open\n", dev_name); return 0; } static int tis_module_release(struct inode *inode, struct file *file) { printk("%s: module release\n", dev_name); return 0; } static struct file_operations tis_module_f = { .owner = THIS_MODULE, .write = tis_module_write, .read = tis_module_read, .open = tis_module_open, .release = tis_module_release, }; void device_tree_test(void){ struct device_node *node; node = of_find_node_by_path("/tree-test"); if(node == NULL){ printk(" device no find tree-test\n"); } printk("this node is %s\n",node->full_name); node = of_find_node_by_path("/tree-test/dev1"); if(node == NULL){ printk(" device no find tree-test/device1\n"); } struct property *prop ; prop = of_find_property(node, "compatible", NULL); if(prop == NULL){ printk("no find property\n"); return ; } printk(" device1 compatible is %s\n",(char *)prop->value); node = of_find_node_by_path("/tree-test/dev2@1122"); if(node == NULL){ printk(" device no find tree-test/device2\n"); } printk("device found dev2:%s\n",node->name); } static int __init tis_module_init(void) { int ret; device_tree_test(); return 0; // 申请dev id #if (DEV_ID_STATIC) dev_info.dev_id = MKDEV(DEV_ID_MAJOR, DEV_ID_MINOR); ret = register_chrdev_region(dev_info.dev_id, 1, dev_name); if (ret < 0) { printk("[%s] dev_id get failed\n",dev_name); return ret; } #else ret = alloc_chrdev_region(&dev_info.dev_id, 0, 1, dev_name); if (ret) { printk("[%s] dev_id get failed\n"); return ret; } #endif // 注册设备 dev_info.cdev.owner = THIS_MODULE; cdev_init(&dev_info.cdev, &tis_module_f); ret = cdev_add(&dev_info.cdev, dev_info.dev_id, 1); if (ret < 0) { printk("[%s] cdev_add failed\n", dev_name); goto del_unregister; } // 创建设备 dev_info.class = class_create(THIS_MODULE, dev_name); if (IS_ERR(dev_info.class)) { printk("[%s] class create failed\n", dev_name); goto del_cdev; } dev_info.device = device_create(dev_info.class, NULL, dev_info.dev_id, NULL, dev_name); if (IS_ERR(dev_info.device)) { printk("[%s] dev create failed\n", dev_name); goto destroy_class; } printk("[%s] init success\n", dev_name); return 0; destroy_class: class_destroy(dev_info.class); del_cdev: cdev_del(&dev_info.cdev); del_unregister: unregister_chrdev_region(dev_info.dev_id, 1); return -EIO; } static void __exit tis_module_exit(void) { return; /* 注销字符设备驱动 */ cdev_del(&dev_info.cdev); /* 删除cdev */ unregister_chrdev_region(dev_info.dev_id, 1); /* 注销设备号 */ device_destroy(dev_info.class, dev_info.dev_id); class_destroy(dev_info.class); printk("[%s] exit success\n", dev_name); } module_init(tis_module_init); module_exit(tis_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("chenyf"); MODULE_INFO(intree, "Y");