Articles
4
Home
文本处理工具
代码生成器
bes
Arduino
python
freertos
zklx
C#
xilinx
3D打印实用工具
Archives
找到我
Fun
Home
文本处理工具
代码生成器
bes
Arduino
python
freertos
zklx
C#
xilinx
3D打印实用工具
Archives
找到我
Fun
复制粘贴工程师专用工具
PS GPIO操作
#include "platform.h" #include "xgpiops.h" #define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID #define PS_KEY_MIO 26 #define PS_LED_MIO 40 #define GPIO_INPUT 0 #define GPIO_OUTPUT 1 XGpioPs xx_ps_Gpio; void xx_ps_gpio_init() { XGpioPs_Config *ConfigPtr; ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID); XGpioPs_CfgInitialize(&xx_ps_Gpio, ConfigPtr,ConfigPtr->BaseAddr); XGpioPs_SetDirectionPin(&xx_ps_Gpio, PS_LED_MIO, 1);//set dir XGpioPs_SetOutputEnablePin(&xx_ps_Gpio, PS_LED_MIO, 1);//enable output } void xx_ps_gpio_write(int val) { XGpioPs_SetDirectionPin(&xx_ps_Gpio, PS_LED_MIO, 1);//set dir XGpioPs_SetOutputEnablePin(&xx_ps_Gpio, PS_LED_MIO, 1);//enable output if(val) { XGpioPs_WritePin(&xx_ps_Gpio, PS_LED_MIO, 0x0); } else { XGpioPs_WritePin(&xx_ps_Gpio, PS_LED_MIO, 0x1); } } int xx_ps_gpio_read() { XGpioPs_SetDirectionPin(&xx_ps_Gpio, PS_KEY_MIO, GPIO_INPUT);//set dir return XGpioPs_ReadPin(&xx_ps_Gpio, PS_KEY_MIO); }
PL GPIO操作
写死设备号直接写寄存器点灯
#include
#include
#include
#include
#include
#include
/* 驱动名称 */ #define DEVICE_NAME "gpio_leds" /* 驱动主设备号 */ #define GPIO_LED_MAJOR 200 /* gpio 寄存器虚拟地址 */ static unsigned long gpio_add_minor; /* gpio 寄存器物理基地址 */ #define GPIO_BASE 0xFF0A0000 /* gpio 寄存器所占空间大小 */ #define GPIO_SIZE 0x1000 /* gpio 方向寄存器 */ #define GPIO_DIRM_1 (unsigned int *)(0x0000000000000244 + (unsigned long)gpio_add_minor) /* gpio 使能寄存器 */ #define GPIO_OEN_1 (unsigned int *)(0x0000000000000248 + (unsigned long)gpio_add_minor) /* gpio 控制寄存器 */ #define GPIO_DATA_1 (unsigned int *)(0x0000000000000044 + (unsigned long)gpio_add_minor) /* open 函数实现, 对应到 Linux 系统调用函数的 open 函数 */ static int gpio_leds_open(struct inode *inode_p, struct file *file_p) { printk("gpio_test module open\n"); return 0; } /* write 函数实现, 对应到 Linux 系统调用函数的 write 函数 */ static ssize_t gpio_leds_write(struct file *file_p, const char __user *buf, size_t len, loff_t * _t_p) { int rst; char writeBuf[5] = {0}; printk("gpio_test module write\n"); rst = copy_from_user(writeBuf, buf, len); if(0 != rst) { return -1; } if(1 != len) { printk("gpio_test len err\n"); return -2; } if(1 == writeBuf[0]) { *GPIO_DATA_1 |= 0x00004000; printk("gpio_test ON *GPIO_DATA_1 = 0x%X\r\n", *GPIO_DATA_1); } else if(0 == writeBuf[0]) { *GPIO_DATA_1 &= 0xFFFFBFFF; printk("gpio_test OFF *GPIO_DATA_1 = 0x%X\r\n", *GPIO_DATA_1); } else { printk("gpio_test para err\n"); return -3; } return 0; } /* release 函数实现, 对应到 Linux 系统调用函数的 close 函数 */ static int gpio_leds_release(struct inode *inode_p, struct file *file_p) { printk("gpio_test module release\n"); return 0; } /* file_operations 结构体声明, 是上面 open、write 实现函数与系统调用函数对应的关键 */ static struct file_operations gpio_leds_fops = { .owner = THIS_MODULE, .open = gpio_leds_open, .write = gpio_leds_write, .release = gpio_leds_release, }; /* 模块加载时会调用的函数 */ static int __init gpio_led_init(void) { int ret; /* 通过模块主设备号、名称、模块带有的功能函数(及 file_operations 结构体)来注册模块 */ ret = register_chrdev(GPIO_LED_MAJOR, DEVICE_NAME, &gpio_leds_fops); if (ret < 0) { printk("gpio_led_dev_init_ng\n"); return ret; } else { /* 注册成功 */ printk("gpio_led_dev_init_ok\n"); /* 把需要修改的物理地址映射到虚拟地址 */ gpio_add_minor = ioremap_wc(GPIO_BASE, GPIO_SIZE); printk("gpio_add_minor = 0x%lX\n", gpio_add_minor); printk("GPIO_DIRM_1 = 0x%lX\n", (unsigned long)GPIO_DIRM_1); printk("GPIO_OEN_1 = 0x%lX\n", (unsigned long)GPIO_OEN_1); /* MIO_0 设置成输出 */ *GPIO_DIRM_1 |= 0x00004000; /* MIO_0 使能 */ *GPIO_OEN_1 |= 0x00004000; printk("*GPIO_DIRM_1 = 0x%X\n", *GPIO_DIRM_1); printk("*GPIO_OEN_1 = 0x%X\n", *GPIO_OEN_1); } return 0; } /* 卸载模块 */ static void __exit gpio_led_exit(void) { *GPIO_OEN_1 &= 0xFFFFBFFF; /* 释放对虚拟地址的占用 */ iounmap(gpio_add_minor); /* 注销模块, 释放模块对这个设备号和名称的占用 */ unregister_chrdev(GPIO_LED_MAJOR, DEVICE_NAME); printk("gpio_led_dev_exit_ok\n"); } /* 标记加载、卸载函数 */ module_init(gpio_led_init); module_exit(gpio_led_exit); /* 驱动描述信息 */ MODULE_AUTHOR("Alinx"); MODULE_ALIAS("gpio_led"); MODULE_DESCRIPTION("GPIO LED driver"); MODULE_VERSION("v1.0"); MODULE_LICENSE("GPL");
自动分配设备号点灯
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* 设备节点名称 */ #define DEVICE_NAME "gpio_leds" /* 设备号个数 */ #define DEVID_COUNT 1 /* 驱动个数 */ #define DRIVE_COUNT 1 /* 主设备号 */ #define MAJOR /* 次设备号 */ #define MINOR 0 /* gpio 寄存器虚拟地址 */ static unsigned long gpio_add_minor; /* gpio 寄存器物理基地址 */ #define GPIO_BASE 0xFF0A0000 /* gpio 寄存器所占空间大小 */ #define GPIO_SIZE 0x1000 /* gpio 方向寄存器 */ #define GPIO_DIRM_1 (unsigned int *)(0x0000000000000244 + (unsigned long)gpio_add_minor) /* gpio 使能寄存器 */ #define GPIO_OEN_1 (unsigned int *)(0x0000000000000248 + (unsigned long)gpio_add_minor) /* gpio 控制寄存器 */ #define GPIO_DATA_1 (unsigned int *)(0x0000000000000044 + (unsigned long)gpio_add_minor) /* 把驱动代码中会用到的数据打包进设备结构体 */ struct alinx_char_dev{ dev_t devid; //设备号 struct cdev cdev; //字符设备 struct class *class; //类 struct device *device; //设备节点 }; /* 声明设备结构体 */ static struct alinx_char_dev alinx_char = { .cdev = { .owner = THIS_MODULE, }, }; /* open 函数实现, 对应到 Linux 系统调用函数的 open 函数 */ static int gpio_leds_open(struct inode *inode_p, struct file *file_p) { printk("gpio_test module open\n"); return 0; } /* write 函数实现, 对应到 Linux 系统调用函数的 write 函数 */ static ssize_t gpio_leds_write(struct file *file_p, const char __user *buf, size_t len, loff_t * f_t_p) { int rst; char writeBuf[5] = {0}; printk("gpio_test module write\n"); rst = copy_from_user(writeBuf, buf, len); if(0 != rst) { return -1; } if(1 != len) { printk("gpio_test len err\n"); return -2; } if(1 == writeBuf[0]) { *GPIO_DATA_1 |= 0x00004000; printk("gpio_test ON\n"); } else if(0 == writeBuf[0]) { *GPIO_DATA_1 &= 0xFFFFBFFF; printk("gpio_test OFF\n"); } else { printk("gpio_test para err\n"); return -3; } return 0; } /* release 函数实现, 对应到 Linux 系统调用函数的 close 函数 */ static int gpio_leds_release(struct inode *inode_p, struct file *file_p) { printk("gpio_test module release\n"); return 0; } /* file_operations 结构体声明, 是上面 open、write 实现函数与系统调用函数对应的关键 */ static struct file_operations ax_char_fops = { .owner = THIS_MODULE, .open = gpio_leds_open, .write = gpio_leds_write, .release = gpio_leds_release, }; /* 模块加载时会调用的函数 */ static int __init gpio_led_init(void) { /* 注册设备号 */ alloc_chrdev_region(&alinx_char.devid, MINOR, DEVID_COUNT, DEVICE_NAME); /* 初始化字符设备结构体 */ cdev_init(&alinx_char.cdev, &ax_char_fops); /* 注册字符设备 */ cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); /* 创建类 */ alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); if(IS_ERR(alinx_char.class)) { return PTR_ERR(alinx_char.class); } /* 创建设备节点 */ alinx_char.device = device_create(alinx_char.class, NULL, alinx_char.devid, NULL, DEVICE_NAME); if (IS_ERR(alinx_char.device)) { return PTR_ERR(alinx_char.device); } /* 把需要修改的物理地址映射到虚拟地址 */ gpio_add_minor = ioremap_wc(GPIO_BASE, GPIO_SIZE); /* MIO_0 设置成输出 */ *GPIO_DIRM_1 |= 0x00004000; /* MIO_0 使能 */ *GPIO_OEN_1 |= 0x00004000; return 0; } /* 卸载模块 */ static void __exit gpio_led_exit(void) { /* 释放对虚拟地址的占用 */ iounmap(gpio_add_minor); /* 注销字符设备 */ cdev_del(&alinx_char.cdev); /* 注销设备号 */ unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); /* 删除设备节点 */ device_destroy(alinx_char.class, alinx_char.devid); /* 删除类 */ class_destroy(alinx_char.class); printk("gpio_led_dev_exit_ok\n"); } /* 标记加载、卸载函数 */ module_init(gpio_led_init); module_exit(gpio_led_exit); /* 驱动描述信息 */ MODULE_AUTHOR("Alinx"); MODULE_ALIAS("gpio_led"); MODULE_DESCRIPTION("NEW GPIO LED driver"); MODULE_VERSION("v1.0"); MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
设备树传参(GPIO寄存器地址)点灯
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* 设备节点名称 */ #define DEVICE_NAME "gpio_leds" /* 设备号个数 */ #define DEVID_COUNT 1 /* 驱动个数 */ #define DRIVE_COUNT 1 /* 主设备号 */ #define MAJOR /* 次设备号 */ #define MINOR 0 #if 0 /* gpio 寄存器虚拟地址 */ static unsigned long gpio_add_minor; /* gpio 寄存器物理基地址 */ #define GPIO_BASE 0xFF0A0000 /* gpio 寄存器所占空间大小 */ #define GPIO_SIZE 0x1000 /* gpio 方向寄存器 */ #define GPIO_DIRM_1 (unsigned int *)(0x0000000000000244 + (unsigned long)gpio_add_minor) /* gpio 使能寄存器 */ #define GPIO_OEN_1 (unsigned int *)(0x0000000000000248 + (unsigned long)gpio_add_minor) /* gpio 控制寄存器 */ #define GPIO_DATA_1 (unsigned int *)(0x0000000000000044 + (unsigned long)gpio_add_minor) #endif static u32 *GPIO_DIRM_1; static u32 *GPIO_OEN_1; static u32 *GPIO_DATA_1; /* 把驱动代码中会用到的数据打包进设备结构体 */ struct alinx_char_dev{ dev_t devid; //设备号 struct cdev cdev; //字符设备 struct class *class; //类 struct device *device; //设备节点 struct device_node *nd; //设备树的设备节点 }; /* 声明设备结构体 */ static struct alinx_char_dev alinx_char = { .cdev = { .owner = THIS_MODULE, }, }; /* open 函数实现, 对应到 Linux 系统调用函数的 open 函数 */ static int gpio_leds_open(struct inode *inode_p, struct file *file_p) { printk("gpio_test module open\n"); return 0; } /* write 函数实现, 对应到 Linux 系统调用函数的 write 函数 */ static ssize_t gpio_leds_write(struct file *file_p, const char __user *buf, size_t len, loff_t * f_t_p) { int rst; char writeBuf[5] = {0}; printk("gpio_test module write\n"); rst = copy_from_user(writeBuf, buf, len); if(0 != rst) { return -1; } if(1 != len) { printk("gpio_test len err\n"); return -2; } if(1 == writeBuf[0]) { *GPIO_DATA_1 |= 0x00004000; printk("gpio_test ON\n"); } else if(0 == writeBuf[0]) { *GPIO_DATA_1 &= 0xFFFFBFFF; printk("gpio_test OFF\n"); } else { printk("gpio_test para err\n"); return -3; } return 0; } /* release 函数实现, 对应到 Linux 系统调用函数的 close 函数 */ static int gpio_leds_release(struct inode *inode_p, struct file *file_p) { printk("gpio_test module release\n"); return 0; } /* file_operations 结构体声明, 是上面 open、write 实现函数与系统调用函数对应的关键 */ static struct file_operations ax_char_fops = { .owner = THIS_MODULE, .open = gpio_leds_open, .write = gpio_leds_write, .release = gpio_leds_release, }; /* 模块加载时会调用的函数 */ static int __init gpio_led_init(void) { /* 用于接受返回值 */ u32 ret = 0; /* 存放 reg 数据的数组 */ u32 reg_data[10]; /* 通过节点名称获取节点 */ alinx_char.nd = of_find_node_by_name(NULL, "alinxled"); /* 4、获取 reg 属性内容 */ ret = of_property_read_u32_array(alinx_char.nd, "reg", reg_data, 6); if(ret < 0) { printk("get reg failed!\r\n"); return -1; } else { /* do nothing */ } printk("reg_data[0]=%x",reg_data[0]); printk("reg_data[1]=%x",reg_data[1]); printk("reg_data[2]=%x",reg_data[2]); printk("reg_data[3]=%x",reg_data[3]); printk("reg_data[4]=%x",reg_data[4]); printk("reg_data[5]=%x",reg_data[5]); GPIO_DIRM_1 = ioremap_wc(reg_data[0], reg_data[1]); GPIO_OEN_1 = ioremap_wc(reg_data[2], reg_data[3]); GPIO_DATA_1 = ioremap_wc(reg_data[4], reg_data[5]); printk("GPIO_DIRM_1=%x",GPIO_DIRM_1); printk("GPIO_OEN_1=%x",GPIO_OEN_1); printk("GPIO_DATA_1=%x",GPIO_DATA_1); /* 注册设备号 */ alloc_chrdev_region(&alinx_char.devid, MINOR, DEVID_COUNT, DEVICE_NAME); /* 初始化字符设备结构体 */ cdev_init(&alinx_char.cdev, &ax_char_fops); /* 注册字符设备 */ cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); /* 创建类 */ alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); if(IS_ERR(alinx_char.class)) { return PTR_ERR(alinx_char.class); } /* 创建设备节点 */ alinx_char.device = device_create(alinx_char.class, NULL, alinx_char.devid, NULL, DEVICE_NAME); if (IS_ERR(alinx_char.device)) { return PTR_ERR(alinx_char.device); } /* MIO_0 设置成输出 */ *GPIO_DIRM_1 |= 0x00004000; /* MIO_0 使能 */ *GPIO_OEN_1 |= 0x00004000; return 0; } /* 卸载模块 */ static void __exit gpio_led_exit(void) { /* 注销字符设备 */ cdev_del(&alinx_char.cdev); /* 注销设备号 */ unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); /* 删除设备节点 */ device_destroy(alinx_char.class, alinx_char.devid); /* 删除类 */ class_destroy(alinx_char.class); /* 释放对虚拟地址的占用 */ iounmap(GPIO_DIRM_1); iounmap(GPIO_OEN_1); iounmap(GPIO_DATA_1); printk("gpio_led_dev_exit_ok\n"); } /* 标记加载、卸载函数 */ module_init(gpio_led_init); module_exit(gpio_led_exit); /* 驱动描述信息 */ MODULE_AUTHOR("Alinx"); MODULE_ALIAS("gpio_led"); MODULE_DESCRIPTION("DEVICE TREE LED driver"); MODULE_VERSION("v1.0"); MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
pin control 点灯
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* 设备节点名称 */ #define DEVICE_NAME "gpio_leds" /* 设备号个数 */ #define DEVID_COUNT 1 /* 驱动个数 */ #define DRIVE_COUNT 1 /* 主设备号 */ #define MAJOR1 /* 次设备号 */ #define MINOR1 0 /* LED 点亮时输入的值 */ #define ALINX_LED_ON 1 /* LED 熄灭时输入的值 */ #define ALINX_LED_OFF 0 /* 把驱动代码中会用到的数据打包进设备结构体 */ struct alinx_char_dev{ dev_t devid; //设备号 struct cdev cdev; //字符设备 struct class *class; //类 struct device *device; //设备 struct device_node *nd; //设备树的设备节点 int alinx_led_gpio; //gpio 号 }; /* 声明设备结构体 */ static struct alinx_char_dev alinx_char = { .cdev = { .owner = THIS_MODULE, }, }; /* open 函数实现, 对应到 Linux 系统调用函数的 open 函数 */ static int gpio_leds_open(struct inode *inode_p, struct file *file_p) { /* 设置私有数据 */ file_p->private_data = &alinx_char; printk("gpio_test module open\n"); return 0; } /* write 函数实现, 对应到 Linux 系统调用函数的 write 函数 */ static ssize_t gpio_leds_write(struct file *file_p, const char __user *buf, size_t len, loff_t *loff_t_p) { int retvalue; unsigned char databuf[1]; /* 获取私有数据 */ struct alinx_char_dev *dev = file_p->private_data; retvalue = copy_from_user(databuf, buf, len); if(retvalue < 0) { printk("alinx led write failed\r\n"); return -EFAULT; } if(databuf[0] == ALINX_LED_ON) { gpio_set_value(dev->alinx_led_gpio, !!1); } else if(databuf[0] == ALINX_LED_OFF) { gpio_set_value(dev->alinx_led_gpio, !!0); } else { printk("gpio_test para err\n"); } return 0; } /* release 函数实现, 对应到 Linux 系统调用函数的 close 函数 */ static int gpio_leds_release(struct inode *inode_p, struct file *file_p) { printk("gpio_test module release\n"); return 0; } /* file_operations 结构体声明, 是上面 open、write 实现函数与系统调用函数对应的关 键 */ static struct file_operations ax_char_fops = { .owner = THIS_MODULE, .open = gpio_leds_open, .write = gpio_leds_write, .release = gpio_leds_release, }; /* 模块加载时会调用的函数 */ static int __init gpio_led_init(void) { /* 用于接受返回值 */ u32 ret = 0; /* 获取设备节点 */ alinx_char.nd = of_find_node_by_path("/alinxled"); if(alinx_char.nd == NULL) { printk("alinx_char node not find\r\n"); return -EINVAL; } else { printk("alinx_char node find\r\n"); } /* 获取节点中 gpio 标号 */ alinx_char.alinx_led_gpio = of_get_named_gpio(alinx_char.nd, "alinxled-gpios", 0); printk("alinx_char.alinx_led_gpio = %d",alinx_char.alinx_led_gpio); if(alinx_char.alinx_led_gpio < 0) { printk("can not get alinxled-gpios"); return -EINVAL; } printk("alinxled-gpio num = %d\r\n", alinx_char.alinx_led_gpio); /* 申请 gpio 标号对应的引脚 */ ret = gpio_request(alinx_char.alinx_led_gpio, "alinxled-pin");//where is this name? if(ret != 0) { printk("can not request gpio\r\n"); } /* 把这个 io 设置为输出 */ ret = gpio_direction_output(alinx_char.alinx_led_gpio, 1); if(ret < 0) { printk("can not set gpio\r\n"); } /* 注册设备号 */ alloc_chrdev_region(&alinx_char.devid, MINOR1, DEVID_COUNT, DEVICE_NAME); /* 初始化字符设备结构体 */ cdev_init(&alinx_char.cdev, &ax_char_fops); /* 注册字符设备 */ cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); /* 创建类 */ alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); if(IS_ERR(alinx_char.class)) { return PTR_ERR(alinx_char.class); } /* 创建设备节点 */ alinx_char.device = device_create(alinx_char.class, NULL, alinx_char.devid, NULL, DEVICE_NAME); if (IS_ERR(alinx_char.device)) { return PTR_ERR(alinx_char.device); } return 0; } /* 卸载模块 */ static void __exit gpio_led_exit(void) { /* 释放 gpio */ gpio_free(alinx_char.alinx_led_gpio); /* 注销字符设备 */ cdev_del(&alinx_char.cdev); /* 注销设备号 */ unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); /* 删除设备节点 */ device_destroy(alinx_char.class, alinx_char.devid); /* 删除类 */ class_destroy(alinx_char.class); printk("gpio_led_dev_exit_ok\n"); } /* 标记加载、卸载函数 */ module_init(gpio_led_init); module_exit(gpio_led_exit); /* 驱动描述信息 */ MODULE_AUTHOR("Alinx"); MODULE_ALIAS("gpio_led"); MODULE_DESCRIPTION("PINCTRL AND GPIO LED driver"); MODULE_VERSION("v1.0"); MODULE_LICENSE("GPL");
内核定时器
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* 设备节点名称 */ #define DEVICE_NAME "timer_led" /* 设备号个数 */ #define DEVID_COUNT 1 /* 驱动个数 */ #define DRIVE_COUNT 1 /* 主设备号 */ #define MAJOR_U /* 次设备号 */ #define MINOR_U 0 /* 把驱动代码中会用到的数据打包进设备结构体 */ struct alinx_char_dev{ dev_t devid; //设备号 struct cdev cdev; //字符设备 struct class *class; //类 struct device *device; //设备 struct device_node *nd; //设备树的设备节点 int alinx_led_gpio; //gpio 号 char led_status; //gpio 状态 unsigned int time_count; //定时器时间 struct timer_list timer; //定时器 }; /* 声明设备结构体 */ static struct alinx_char_dev alinx_char = { .cdev = { .owner = THIS_MODULE, }, }; void timer_function(struct timer_list *timer) { /* 反转 led 状态 */ alinx_char.led_status = !alinx_char.led_status; /* 设置 led */ gpio_set_value(alinx_char.alinx_led_gpio, alinx_char.led_status); /* 重新开始计时 */ mod_timer(timer, jiffies + msecs_to_jiffies(alinx_char.time_count)); } /* open 函数实现, 对应到 Linux 系统调用函数的 open 函数 */ static int timer_led_open(struct inode *inode_p, struct file *file_p) { printk("gpio_test module open\n"); return 0; } /* write 函数实现, 对应到 Linux 系统调用函数的 write 函数 */ static ssize_t timer_led_write(struct file *file_p, const char __user *buf, size_t len, loff_t *loff_t_p) { int retvalue; /* 获取用户数据 */ retvalue = copy_from_user(&alinx_char.time_count, buf, len); /* 设置好 timer 后先点亮 led */ alinx_char.led_status = 1; gpio_set_value(alinx_char.alinx_led_gpio, alinx_char.led_status); /* 开启 timer */ mod_timer(&alinx_char.timer, jiffies + msecs_to_jiffies(alinx_char.time_count)); return 0; } /* release 函数实现, 对应到 Linux 系统调用函数的 close 函数 */ static int timer_led_release(struct inode *inode_p, struct file *file_p) { printk("gpio_test module release\n"); /* 删除定时器 */ del_timer_sync(&alinx_char.timer); return 0; } /* file_operations 结构体声明, 是上面 open、write 实现函数与系统调用函数对应的关键 */ static struct file_operations ax_char_fops = { .owner = THIS_MODULE, .open = timer_led_open, .write = timer_led_write, .release = timer_led_release, }; /* 模块加载时会调用的函数 */ static int __init timer_led_init(void) { /* 用于接受返回值 */ u32 ret = 0; /* 获取 led 设备节点 */ alinx_char.nd = of_find_node_by_path("/alinxled"); if(alinx_char.nd == NULL) { printk("alinx_char node not find\r\n"); return -EINVAL; } else { printk("alinx_char node find\r\n"); } /* 获取节点中 gpio 标号 */ alinx_char.alinx_led_gpio = of_get_named_gpio(alinx_char.nd, "alinxled-gpios", 0); if(alinx_char.alinx_led_gpio < 0) { printk("can not get alinxled-gpios"); return -EINVAL; } printk("alinxled-gpio num = %d\r\n", alinx_char.alinx_led_gpio); /* 申请 gpio 标号对应的引脚 */ ret = gpio_request(alinx_char.alinx_led_gpio, "alinxled"); if(ret != 0) { printk("can not request gpio\r\n"); } /* 把这个 io 设置为输出 */ ret = gpio_direction_output(alinx_char.alinx_led_gpio, 1); if(ret < 0) { printk("can not set gpio\r\n"); } /* 注册设备号 */ alloc_chrdev_region(&alinx_char.devid, MINOR_U, DEVID_COUNT, DEVICE_NAME); /* 初始化字符设备结构体 */ cdev_init(&alinx_char.cdev, &ax_char_fops); /* 注册字符设备 */ cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); /* 创建类 */ alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); if(IS_ERR(alinx_char.class)) { return PTR_ERR(alinx_char.class); } /* 创建设备节点 */ alinx_char.device = device_create(alinx_char.class, NULL, alinx_char.devid, NULL, DEVICE_NAME); if (IS_ERR(alinx_char.device)) { return PTR_ERR(alinx_char.device); } /* 设置定时器回掉函数&初始化定时器 */ timer_setup(&alinx_char.timer, timer_function, NULL); return 0; } /* 卸载模块 */ static void __exit timer_led_exit(void) { /* 释放 gpio */ gpio_free(alinx_char.alinx_led_gpio); /* 注销字符设备 */ cdev_del(&alinx_char.cdev); /* 注销设备号 */ unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); /* 删除设备节点 */ device_destroy(alinx_char.class, alinx_char.devid); /* 删除类 */ class_destroy(alinx_char.class); printk("timer_led_dev_exit_ok\n"); } /* 标记加载、卸载函数 */ module_init(timer_led_init); module_exit(timer_led_exit); /* 驱动描述信息 */ MODULE_AUTHOR("Alinx"); MODULE_ALIAS("gpio_led"); MODULE_DESCRIPTION("TIMER LED driver"); MODULE_VERSION("v1.0"); MODULE_LICENSE("GPL");
按键驱动
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* 设备节点名称 */ #define DEVICE_NAME "gpio_key" /* 设备号个数 */ #define DEVID_COUNT 1 /* 驱动个数 */ #define DRIVE_COUNT 1 /* 主设备号 */ #define MAJOR1 /* 次设备号 */ #define MINOR1 0 /* 把驱动代码中会用到的数据打包进设备结构体 */ struct alinx_char_dev{ dev_t devid; //设备号 struct cdev cdev; //字符设备 struct class *class; //类 struct device *device; //设备 struct device_node *nd; //设备树的设备节点 int alinx_key_gpio; //gpio 号 }; /* 声明设备结构体 */ static struct alinx_char_dev alinx_char = { .cdev = { .owner = THIS_MODULE, }, }; /* open 函数实现, 对应到 Linux 系统调用函数的 open 函数 */ static int gpio_key_open(struct inode *inode_p, struct file *file_p) { /* 设置私有数据 */ file_p->private_data = &alinx_char; printk("gpio_test module open\n"); return 0; } /* write 函数实现, 对应到 Linux 系统调用函数的 write 函数 */ static ssize_t gpio_key_read(struct file *file_p, char __user *buf, size_t len, loff_t *loff_t_p) { int ret = 0; /* 返回按键的值 */ unsigned int key_value = 0; /* 获取私有数据 */ struct alinx_char_dev *dev = file_p->private_data; /* 检查按键是否被按下 */ if(0 == gpio_get_value(dev->alinx_key_gpio)) { /* 按键被按下 */ /* 防抖 */ mdelay(50); /* 等待按键抬起 */ while(!gpio_get_value(dev->alinx_key_gpio)); key_value = 1; } else { /* 按键未被按下 */ } /* 返回按键状态 */ ret = copy_to_user(buf, &key_value, sizeof(key_value)); return ret; } /* release 函数实现, 对应到 Linux 系统调用函数的 close 函数 */ static int gpio_key_release(struct inode *inode_p, struct file *file_p) { printk("gpio_test module release\n"); return 0; } /* file_operations 结构体声明, 是上面 open、write 实现函数与系统调用函数对应的关键 */ static struct file_operations ax_char_fops = { .owner = THIS_MODULE, .open = gpio_key_open, .read = gpio_key_read, .release = gpio_key_release, }; /* 模块加载时会调用的函数 */ static int __init gpio_key_init(void) { /* 用于接受返回值 */ u32 ret = 0; /* 获取设备节点 */ alinx_char.nd = of_find_node_by_path("/alinxkey"); if(alinx_char.nd == NULL) { printk("alinx_char node not find\r\n"); return -EINVAL; } else { printk("alinx_char node find\r\n"); } /* 获取节点中 gpio 标号 */ alinx_char.alinx_key_gpio = of_get_named_gpio(alinx_char.nd, "alinxkey-gpios", 0); if(alinx_char.alinx_key_gpio < 0) { printk("can not get alinxkey-gpios"); return -EINVAL; } printk("alinxkey-gpio num = %d\r\n", alinx_char.alinx_key_gpio); /* 申请 gpio 标号对应的引脚 */ ret = gpio_request(alinx_char.alinx_key_gpio, "alinxkey"); if(ret != 0) { printk("can not request gpio\r\n"); return -EINVAL; } /* 把这个 io 设置为输入 */ ret = gpio_direction_input(alinx_char.alinx_key_gpio); if(ret < 0) { printk("can not set gpio\r\n"); return -EINVAL; } /* 注册设备号 */ alloc_chrdev_region(&alinx_char.devid, MINOR1, DEVID_COUNT, DEVICE_NAME); /* 初始化字符设备结构体 */ cdev_init(&alinx_char.cdev, &ax_char_fops); /* 注册字符设备 */ cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT); /* 创建类 */ alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME); if(IS_ERR(alinx_char.class)) { return PTR_ERR(alinx_char.class); } /* 创建设备节点 */ alinx_char.device = device_create(alinx_char.class, NULL, alinx_char.devid, NULL, DEVICE_NAME); if (IS_ERR(alinx_char.device)) { return PTR_ERR(alinx_char.device); } return 0; } /* 卸载模块 */ static void __exit gpio_key_exit(void) { /* 释放 gpio */ gpio_free(alinx_char.alinx_key_gpio); /* 注销字符设备 */ cdev_del(&alinx_char.cdev); /* 注销设备号 */ unregister_chrdev_region(alinx_char.devid, DEVID_COUNT); /* 删除设备节点 */ device_destroy(alinx_char.class, alinx_char.devid); /* 删除类 */ class_destroy(alinx_char.class); printk("gpio_key_dev_exit_ok\n"); } /* 标记加载、卸载函数 */ module_init(gpio_key_init); module_exit(gpio_key_exit); /* 驱动描述信息 */ MODULE_AUTHOR("Alinx"); MODULE_ALIAS("gpio_key"); MODULE_DESCRIPTION("GPIO OUT driver"); MODULE_VERSION("v1.0"); MODULE_LICENSE("GPL");
i2c
i2c
i2c
zhoushenglin
Articles
4
Bookmark
Announcement
Hello!
Recent Post
WSL下安装petalinux
2022-08-19
video
2020-08-14
关于这个网站
2020-08-10
更新记录
2020-08-10
Archives
August 2022
1
August 2020
3
Info
Article :
4
UV :
PV :
2