Linux下实现流水灯等功能的LED驱动代码及测试实例
驱动代码:
#include <linux/errno.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/input.h> #include <linux/init.h> #include <linux/serio.h> #include <linux/delay.h> #include <linux/clk.h> #include <linux/miscdevice.h> #include <linux/gpio.h>#include <asm/io.h> #include <asm/irq.h> #include <asm/uaccess.h> #include <mach/regs-clock.h> #include <plat/regs-timer.h>#include <mach/regs-gpio.h> #include <linux/cdev.h> //-------------class_create,device_create------ #include <linux/device.h>/*用udev机制自动添加设备节点*/ struct class *led_class;static int led_major = 0; /* 主设备号 */ static struct cdev LedDevs;/* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */ #define LED_MAGIC 'k' #define IOCTL_LED_ON _IOW (LED_MAGIC, 1, int) #define IOCTL_LED_OFF _IOW (LED_MAGIC, 2, int) #define IOCTL_LED_RUN _IOW (LED_MAGIC, 3, int) #define IOCTL_LED_SHINE _IOW (LED_MAGIC, 4, int) #define IOCTL_LED_ALLON _IOW (LED_MAGIC, 5, int) #define IOCTL_LED_ALLOFF _IOW (LED_MAGIC, 6, int)/* 用来指定LED所用的GPIO引脚 */ static unsigned long led_table [] = {S5PV210_MP04(4),S5PV210_MP04(5),S5PV210_MP04(6),S5PV210_MP04(7),}; #define LED_NUM ARRAY_SIZE(led_table)/* 应用程序对设备文件/dev/led执行open(...)时,* 就会调用leds_open函数*/ static int leds_open(struct inode *inode, struct file *file) {int i; for (i = 0; i < 4; i++) {// 设置GPIO引脚的功能:本驱动中LED所涉及的GPIO引脚设为输出功能 s3c_gpio_cfgpin(led_table[i], S3C_GPIO_OUTPUT);}return 0; }//LEDS all light on static void leds_all_on() {int i;for (i=0; i<4; i++) {gpio_set_value(led_table[i], 0);} }//LEDs all light off static void leds_all_off() {int i;for (i=0; i<4; i++) {gpio_set_value(led_table[i], 1);} }/* 应用程序对设备文件/dev/leds执行ioctl(...)时,* 就会调用leds_ioctl函数*/ static int leds_ioctl(struct file *file, unsigned int cmd, unsigned long arg)//没有inode,用邋unlocked_ioctl {printk("in the leds_ioctl!!\n");// if (__get_user(data, (unsigned int __user *)arg)) //方法二:指针参数传递// return -EFAULT;printk("arg is %d!!\n",arg);switch(cmd) {case IOCTL_LED_ON:printk("in the IOCTL_LED_ON!!\n");// 设置指定引脚的输出电平为0gpio_set_value(led_table[arg], 0);break;case IOCTL_LED_OFF:printk("in the IOCTL_LED_OFF!!\n");// 设置指定引脚的输出电平为1gpio_set_value(led_table[arg], 1);break;case IOCTL_LED_RUN:// 跑马灯 {printk("in the IOCTL_LED_RUN!!\n");int i,j;leds_all_off(); //printk("IOCTL_LED_RUN");for (i=0;i<arg;i++)for (j=0;j<4;j++) {gpio_set_value(led_table[j], 0);mdelay(400); //delay 400msgpio_set_value(led_table[j], 1);mdelay(400); //delay 400ms } break;}case IOCTL_LED_SHINE:// LED 闪烁 {printk("in the IOCTL_LED_SHINE!!\n");int i,j;leds_all_off();printk("IOCTL_LED_SHINE\n");for (i=0;i<arg;i++) {for (j=0;j<4;j++)gpio_set_value(led_table[j], 0);mdelay(400); //delay 400msfor (j=0;j<4;j++)gpio_set_value(led_table[j], 1);mdelay(400);}break ;}case IOCTL_LED_ALLON:printk("in the IOCTL_LED_ALLON!!\n");// 设置指定引脚的输出电平为0 leds_all_on();break;case IOCTL_LED_ALLOFF:printk("in the IOCTL_LED_ALLOFF!!\n");// 设置指定引脚的输出电平为1 leds_all_off();break;default:printk("in the default!!\n");return -EINVAL;}return 0; }/* 这个结构是字符设备驱动程序的核心* 当应用程序操作设备文件时所调用的open、read、write等函数,* 最终会调用这个结构中指定的对应函数*/ static struct file_operations leds_fops = {.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */.open = leds_open, .unlocked_ioctl = leds_ioctl, };/** Set up the cdev structure for a device.*/ static void led_setup_cdev(struct cdev *dev, int minor,struct file_operations *fops) {int err, devno = MKDEV(led_major, minor);cdev_init(dev, fops);dev->owner = THIS_MODULE;dev->ops = fops;err = cdev_add (dev, devno, 1);/* Fail gracefully if need be */if (err)printk (KERN_NOTICE "Error %d adding Led%d", err, minor); }/** 执行“insmod leds.ko”命令时就会调用这个函数*/static int __init leds_init(void){int result;dev_t dev = MKDEV(led_major, 0);char dev_name[]="led"; /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 *//*gpio_request*/int i,ret;for (i = 0; i < LED_NUM; i++){ret=gpio_request(led_table[i],"LED");if(ret)//注意,是ret {printk("%s:request GPIO %d for LED failed,ret= %d\n",dev_name,led_table[i],ret);return ret;}s3c_gpio_cfgpin(led_table[i],S3C_GPIO_SFN(1));//outputgpio_set_value(led_table[i],1);}/* Figure out our device number. */if (led_major)result = register_chrdev_region(dev, 1, dev_name);else {result = alloc_chrdev_region(&dev, 0, 1, dev_name);led_major = MAJOR(dev);}if (result < 0) {printk(KERN_WARNING "leds: unable to get major %d\n", led_major);return result;}if (led_major == 0)led_major = result;/* Now set up cdev. */led_setup_cdev(&LedDevs, 0, &leds_fops);/*udev机制可以自动添加设备节点,只需要添加xxx_class这个类,以及device_create()*/led_class = class_create(THIS_MODULE, "led_class");/*在sys目录下创建xx_class这个类,/sys/class/~*/device_create(led_class, NULL, LedDevs.dev, dev_name, dev_name);/*自动创建设备/dev/$DEVICE_NAME*/printk("Led device installed, with major %d\n", led_major);printk("The device name is: %s\n", dev_name);return 0;}/** 执行”rmmod leds”命令时就会调用这个函数 */ static void __exit leds_exit(void) {/*gpio_free*/int i;for (i = 0; i < LED_NUM; i++){gpio_free(led_table[i]);}/* 卸载驱动程序 */cdev_del(&LedDevs);unregister_chrdev_region(MKDEV(led_major, 0), 1);printk("Led device uninstalled\n"); }/* 这两行指定驱动程序的初始化函数和卸载函数 */ module_init(leds_init); module_exit(leds_exit);/* 描述驱动程序的一些信息,不是必须的 */ MODULE_AUTHOR(""); // 驱动程序的作者 MODULE_DESCRIPTION("LED Driver"); // 一些描述信息 MODULE_LICENSE("Dual BSD/GPL"); // 遵循的协议
测试代码:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h>#define LED_MAGIC 'k' #define IOCTL_LED_ON _IOW (LED_MAGIC, 1, int) #define IOCTL_LED_OFF _IOW (LED_MAGIC, 2, int) #define IOCTL_LED_RUN _IOW (LED_MAGIC, 3, int) #define IOCTL_LED_SHINE _IOW (LED_MAGIC, 4, int) #define IOCTL_LED_ALLON _IOW (LED_MAGIC, 5, int) #define IOCTL_LED_ALLOFF _IOW (LED_MAGIC, 6, int)/* led_test on //对应四个LED全亮 led_test off // 对应四个LED全灭 led_test run // 运行跑马灯实验 led_test shine //4个LED灯全灭、全亮交替闪烁led_test 1 on //对应LED1点亮 led_test 1 off // 对应LED1熄灭 ... led_test 4 on //对应LED4点亮 led_test 4 off // 对应LED4熄灭*/ void usage(char *exename) {printf("Usage:\n");printf(" %s <led_no> <on/off>\n", exename);printf(" led_no = 1, 2, 3 or 4\n"); }int main(int argc, char **argv) {unsigned int led_no;int fd = -1;unsigned int count=10;if (argc > 3 || argc == 1)goto err;fd = open("/dev/led", 0); // 打开设备if (fd < 0) {printf("Can't open /dev/led\n");return -1; } if (argc == 2) {if (!strcmp(argv[1], "on")) {ioctl(fd, IOCTL_LED_ALLON, count); // 点亮它} else if (!strcmp(argv[1], "off")) {ioctl(fd, IOCTL_LED_ALLOFF, count); // 熄灭它} else if (!strcmp(argv[1], "run")) {ioctl(fd, IOCTL_LED_RUN, count); //运行跑马灯} else if (!strcmp(argv[1], "shine")) {ioctl(fd, IOCTL_LED_SHINE, count); //闪烁} else {goto err;}}if (argc == 3) {led_no = atoi(argv[1]); // 操作哪个LED?if (led_no > 3)goto err; if (!strcmp(argv[2], "on")) {ioctl(fd, IOCTL_LED_ON, led_no); // 点亮} else if (!strcmp(argv[2], "off")) {ioctl(fd, IOCTL_LED_OFF, led_no); // 熄灭} else {goto err;}}close(fd);return 0;err:if (fd > 0) close(fd);usage(argv[0]);return -1;}
转载于:https://www.cnblogs.com/hello2mhb/p/3282698.html
Linux下实现流水灯等功能的LED驱动代码及测试实例相关推荐
- 学号20175313 《实现Linux下cp XXX1 XXX2的功能(一)》第九周
目录 MyCP 一.题目要求 二.题目理解 三.需求分析 四.设计思路 五.伪代码分析 六.代码链接 七.代码实现过程中遇到的问题 八.运行结果截图 九.参考资料 MyCP 一.题目要求 编写MyCP ...
- linux java -cp lt; .txt_补交 20155202 蓝墨云班课 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能...
蓝墨云班课 编写MyCP.java 要求: 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能,要求MyCP支持两个参数: java MyCP -tx XXX1.txt XXX ...
- linux怎么设置自动缩进,配置Linux下vim自动缩进等功能
从终端打开配置文件: vim ~/.vimrc 添加如下代码: set tabstop=4 set softtabstop=4 set shiftwidth=4 set autoindent set ...
- linux按照学号对文件进行排序,学号20175313 《实现Linux下Sort -t : -k 2功能》第十二周...
一.题目要求 实现Linux下Sort -t : -k 2的功能 二.题目理解 -t 分隔符,将每一行数据按照该选项指定的分隔符分成多个域.默认情况下是使用tab键或者空格符来分割的. -k 指定用哪 ...
- Linux下qt实现个人资源管理功能:记事本,图片浏览,网络聊天,数据库管理
Linux下qt实现个人资源管理功能:记事本,图片浏览,网络聊天,数据库管理 实验内容和环境:(包括软件平台和硬件平台) QT5.14.1 Ubuntu操作系统 实验内容及步骤 (含源程序): 用QT ...
- linux网卡驱动rtl8188cu,linux下编译基于rtl8188cu控制芯片的USB无线网卡驱动 -电脑资料...
本人因为实验的需要,需要在嵌入式linux环境下添加wifi功能,通过在网上调研,选择基于rtl8188cu控制芯片的水星NW150UM无线USB网卡,现简单记录下配置过程, 1.下载最新的rtl81 ...
- linux下的CPU、内存、IO、网络的压力测试
linux下的CPU.内存.IO.网络的压力测试 要远程测试其实很简单了,把结果放到一个微服务里直接在web里查看就可以了,或者同步到其他服务器上 一.对CPU进行简单测试: 1.通过bc命令计算特别 ...
- 51单片机实验——用定时器0实现流水灯,要求每个led轮流显示1s。
1.实验题目: 用定时器0实现流水灯,要求每个led轮流显示1s. 2.KEIL代码 #include<reg51.h> void main() {TMOD &=0X0F;TMOD ...
- linux下GTK图形界面取消关闭按钮和最大化按钮代码
linux下GTK图形界面取消关闭按钮和最大化按钮代码 由于项目需要,需要将GTK图形界面的关闭按钮和最大化按钮去掉,查阅很多资料终于解决.先分享出来,方便大家学习. 首先创建一个GTK小窗口(代码不 ...
最新文章
- 从0到1,Airbnb的深度学习实践经验总结
- optee中关于异常向量表、中断等的深入思考
- 14行代码AC_Zero Array(思维)
- java运行时参数_运行时的Java 8参数名称
- Spring Cloud项目MVN编译 -- Non-resolvable import POM
- ipsec *** 的总结性谈论
- 50道 JavaScript 经典面试题汇总篇
- css3弹性盒子、媒体查询、多列布局
- 雪城大学信息安全讲义 七、格式化字符串漏洞
- spark算子_Spark算子总结
- 关于UIText换行
- javaweb项目静态资源被拦截的解决方法
- 中古调式(调式音阶) 二
- Java多线程编程模式实战指南(一):Active Object模式--转载
- 向量ab怎么用计算机打出来,向量怎么用wps打出来
- 解决百度云离线文件因含有违规内容被系统屏蔽无法下载问题
- 【笨木头Cocos2dx 038】战争迷雾效果 第01章_要探索,不要地图全开!
- android11原生录屏,终于把安卓这项功能实现了!iOS 11录屏功能演示:超好用
- maya2018自带模型的打开
- Bootstrap 实例1