【原创】Tiny6410简单驱动 --- LED控制
2014-07-07 20:29
405 查看
【原创】Tiny6410简单驱动 --- LED灯控制
编写驱动之前记住一个原则:驱动程序提供机制而不提供策略,即驱动只管做什么,怎么做的问题交给应用程序。
依据上述原则,此文的简单驱动只实现四个LED的开和关,而要怎样用这开和关就交给应用程序。
编写驱动之前记住一个原则:驱动程序提供机制而不提供策略,即驱动只管做什么,怎么做的问题交给应用程序。
依据上述原则,此文的简单驱动只实现四个LED的开和关,而要怎样用这开和关就交给应用程序。
LED硬件结构和相关寄存器
如下图,应设置输出模式(即cpu向LED管脚输出信号),低电平点亮,高电平熄灭。my_led_module.c源代码(驱动程序)
驱动程序的构建方式和其Makefile文件参考链接http://blog.csdn.net/geng823/article/details/37355109#t4<span style="font-size:18px;"><span style="font-size:18px;">#include <linux/miscdevice.h> #include <linux/delay.h> #include <asm/irq.h> #include <mach/hardware.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/fs.h> #include <linux/types.h> #include <linux/delay.h> #include <linux/moduleparam.h> #include <linux/slab.h> #include <linux/errno.h> #include <linux/ioctl.h> #include <linux/cdev.h> #include <linux/string.h> #include <linux/list.h> #include <linux/pci.h> #include <asm/uaccess.h> #include <asm/atomic.h> #include <asm/unistd.h> #include <mach/map.h> #include <mach/regs-clock.h> #include <mach/regs-gpio.h> #include <plat/gpio-cfg.h> #include <mach/gpio-bank-e.h> #include <mach/gpio-bank-k.h> #define DEVICE_NAME "my_led" //设备名称设为 my_led #define ALL_LED_ON 0<span style="white-space:pre"> </span>//四个灯全点亮 #define ALL_LED_OFF 1<span style="white-space:pre"> </span>//四个灯全熄灭 static long s3c6410_leds_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { switch(cmd) { unsigned tmp; case ALL_LED_ON: //四个灯全亮 tmp = readl(S3C64XX_GPKDAT); tmp &= ~(0xF << 4); writel(tmp, S3C64XX_GPKDAT); break; case ALL_LED_OFF: //四个灯全灭 tmp = readl(S3C64XX_GPKDAT); tmp |= (0xF << 4); writel(tmp, S3C64XX_GPKDAT); break; default: return -EINVAL; } } static struct file_operations dev_fops = { .owner = THIS_MODULE, .unlocked_ioctl = s3c6410_leds_ioctl, }; static struct miscdevice misc = { .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &dev_fops, }; static int __init dev_init(void) { int ret; { unsigned tmp; //将S3C64XX_GPKCON配制成输出,0xffffU<<16表示控制四个LED灯 tmp = readl(S3C64XX_GPKCON); tmp = (tmp & ~(0xffffU<<16))|(0x1111U<<16); writel(tmp, S3C64XX_GPKCON); //低电平有效,初始时将四个灯都关掉 tmp = readl(S3C64XX_GPKDAT); tmp |= (0xF << 4); writel(tmp, S3C64XX_GPKDAT); } ret = misc_register(&misc);//注册杂项设备 printk (DEVICE_NAME"\tinitialized\n"); return ret; } static void __exit dev_exit(void) { misc_deregister(&misc);//注销杂项设备 printk (DEVICE_NAME"\tuninstalled\n"); } module_init(dev_init); module_exit(dev_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("GENG");</span></span>
my_led.c源代码(应用程序)
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <stdlib.h> #define ALL_LED_SPLASH 'r' //四个灯间隔1s同时闪烁 #define ALL_LED_STOP 's' //四个灯停止闪烁 #define DEVICE_QUIT 'q' //设备退出 #define ALL_LED_ON 0 //四个灯全点亮 #define ALL_LED_OFF 1 //四个灯全熄灭 /* * 此函数用来获得从键盘输入的一个字符,也可以直接在主函数中用getchar()获得 */ static int getch(void) { struct termios oldt,newt; int ch; if (!isatty(STDIN_FILENO)) { fprintf(stderr, "this problem should be run at a terminal\n"); exit(1); } // save terminal setting if(tcgetattr(STDIN_FILENO, &oldt) < 0) { perror("save the terminal setting"); exit(1); } // set terminal as need newt = oldt; newt.c_lflag &= ~( ICANON | ECHO ); if(tcsetattr(STDIN_FILENO,TCSANOW, &newt) < 0) { perror("set terminal"); exit(1); } ch = getchar(); // restore termial setting if(tcsetattr(STDIN_FILENO,TCSANOW,&oldt) < 0) { perror("restore the termial setting"); exit(1); } return ch; } int main(int argc, char **argv) { int fd; //打开设备 fd = open("/dev/my_led", 0); if (fd < 0) { fd = open("/dev/my_led", 0); } if (fd < 0) { perror("open device my_led"); exit(1); } printf( "\nmy_led TEST ( led Control )\n" ); while(1) { int c; int i; c = getch(); //通过输入的字符选择功能 //注意:输入字符后,需要再按回车键 switch(c) { case ALL_LED_SPLASH: //四个led灯同时以1s的间隔闪烁 for (i = 0; i < 10; i++){ ioctl(fd, ALL_LED_ON);//同时亮 sleep(1);//睡一秒 ioctl(fd, ALL_LED_OFF);//同时灭 sleep(1);//睡一秒 } break; case ALL_LED_STOP: //四个灯全灭 ioctl(fd, ALL_LED_OFF);// break; case DEVICE_QUIT://关闭设备,退出 close(fd); exit(0); default://其他字符,继续等待输入 break; } } return 0; }
应用程序的Makefile
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"># ---------------------------------------------------------------------------- # Makefile for building tapp # # Copyright 2010 FriendlyARM (http://www.arm9.net/) # ifndef DESTDIR DESTDIR ?= /tmp/FriendlyARM/mini6410/rootfs endif CFLAGS = -Wall -O2 CC = arm-linux-gcc INSTALL = install TARGET = my_led all: $(TARGET) led: my_led.c $(CC) $(CFLAGS) $< -o $@ install: $(TARGET) $(INSTALL) $^ $(DESTDIR)/usr/bin clean distclean: rm -rf *.o $(TARGET) # ---------------------------------------------------------------------------- .PHONY: $(PHONY) install clean distclean # End of file # vim: syntax=make </span></span></span>
原文链接:http://blog.csdn.net/geng823/article/details/37531187
相关文章推荐
- 【原创】Tiny6410简单驱动 --- LED控制
- Tiny6410 简单的LED字符设备驱动
- linux字符驱动学习实践1(简单控制LED灯)
- tiny6410 Linux 按键控制LED驱动
- Tiny6410 简单的LED字符设备驱动
- LED驱动程序相关头文件简单介绍
- linux设备驱动归纳总结(五):4.写个简单的LED驱动
- 控制Windows Mobile的LED之四:多色呼吸LED SN3199的驱动
- (原创)移植ads7846驱动到tiny6410(tiny6410)(ads7846)(移植)(触摸屏)(抖动)
- 由简单的LED驱动分析内核源码包中的s3c2410寄存器宏定
- S3C6410 linux内核移植(11)---添加充电控制脚驱动(LED驱动)
- 简单的led驱动 了解下
- arm 驱动基础:通过次设备号精确控制led亮灭
- 【原创】MVC2/MVC3 Forms身份验证简单控制
- 【转】android 驱动例子(LED控制)
- 控制Windows Mobile的LED之四:多色呼吸LED SN3199的驱动
- 由简单的LED驱动分析内核源码包中的s3c2410寄存器宏定
- 慢慢学Linux驱动开发,第九篇,tiny6410_LED驱动
- 自制简单字符型设备驱动程序——LED驱动