【原创】Tiny6410简单驱动 --- LED控制

来源:互联网 发布:淘宝套餐链接转换 编辑:程序博客网 时间:2024/04/29 17:49


【原创】Tiny6410简单驱动 --- 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_ON0<span style="white-space:pre"></span>//四个灯全点亮#define ALL_LED_OFF1<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_ON0//四个灯全点亮#define ALL_LED_OFF1//四个灯全熄灭/* * 此函数用来获得从键盘输入的一个字符,也可以直接在主函数中用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 settingif(tcgetattr(STDIN_FILENO, &oldt) < 0) {perror("save the terminal setting");exit(1);}// set terminal as neednewt = oldt;newt.c_lflag &= ~( ICANON | ECHO );if(tcsetattr(STDIN_FILENO,TCSANOW, &newt) < 0) {perror("set terminal");exit(1);}ch = getchar();// restore termial settingif(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 DESTDIRDESTDIR   ?= /tmp/FriendlyARM/mini6410/rootfsendifCFLAGS= -Wall -O2CC= arm-linux-gccINSTALL= installTARGET= my_ledall: $(TARGET)led: my_led.c$(CC) $(CFLAGS) $< -o $@install: $(TARGET)$(INSTALL) $^ $(DESTDIR)/usr/binclean 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

0 0
原创粉丝点击