linux设备驱动之我是led灯-基于OK6410开发板

原创 2012年03月29日 22:44:45

原创作品转载请注明出处

http://blog.csdn.net/cediy2088long?viewmode=contents



学习嵌入式linux编程,我们接触到的大多是linux设备驱动程序的编程。今天我就给大家简单的分析一下飞凌的led驱动程序,有了我们前面led的裸机的程序的基础,这个led的驱动也就简单多了。

大家最好是看一下linux设备驱动程序一书的前六章,这样不会对linux中的led中的一些函数太陌生。首先要对linux的字符设备驱动框架有一个大概的了解。

打开linux的源码目录,找到drivers/char/s3c6410-led.c

打开看一下源码。里边的函数都不难。

主要的函数实现就是下面这个函数,我们在用户空间调用的时候也是最终调用到这个函数

#define DEVICE_NAME "leds"

static long s3c6410_leds_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	switch(cmd) {
		unsigned tmp;
	case 0:
	case 1:
                 if (arg > 4) 
                 {
		 	return -EINVAL;
		 }
		tmp = readl(S3C64XX_GPMDAT);
            
		if(cmd==0) //close light
                  { 
			tmp &= (~(1<<arg));
                  }
		else  //open light
                  { 
			tmp |= (1<<arg);
                  }

                writel(tmp,S3C64XX_GPMDAT);

		printk (DEVICE_NAME": %d %d\n", arg, cmd);
		return 0;
	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;

       //gpm0-3 pull up
	tmp = readl(S3C64XX_GPMPUD);
	tmp &= (~0xFF);
	tmp |= 0xaa;
	writel(tmp,S3C64XX_GPMPUD);

	//gpm0-3 output mode
	tmp =readl(S3C64XX_GPMCON);
	tmp &= (~0xFFFF);
	tmp |= 0x1111;
	writel(tmp,S3C64XX_GPMCON);
	
	//gpm0-3 output 0
	tmp = __raw_readl(S3C64XX_GPMDAT);
	tmp |= 0x10;
	writel(tmp,S3C64XX_GPMDAT);  

	ret = misc_register(&misc);

	printk (DEVICE_NAME"\tinitialized\n");

	return ret;
}

static void __exit dev_exit(void)
{
	misc_deregister(&misc);
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("FORLINX Inc.");

上面是初始化部分和注册设备。代码很简单,就不多说了。

如何把这个编译进入内核呢?

还有再给大家说一下怎么来把led驱动加到内核中呢,linux的编译用的是makefile管理的,初学者对于makefile的基本结构要知道一些,不用把整个makefile的文档都看一遍,但也要把知道大概,  makefile的格式规则是这样的

target : prerequisites  

            command 

我们打开char目录下的makefie看一下,


这一行是把led的驱动加入内核的关键,而我们在编译的时候要配置是加入内核还是编译成模块呢,我们运行make menuconfig的时候是怎么出现的配置的呢?这个要看我们的Kconfig文件



这个就是我们在make menuconfig 的时候的配置选项。

进入到Device DriversàCharacter devices找到LedS driver forlinx6410



我们选上这一项就是编译进内核,如果是M,就是要编译成模块,可以动态加载,如果是空就是不编译。Makemenuconfig的时候就是如何剪裁操作系统了,我们可以把不需要的或者没有必要的驱动不选上,重新编译,就可以得到自己剪裁过的内核了

这样就会在dev目录下生成一个led设备了。这样驱动部分就好了。我们如何测试我们的led能用呢?

写个流水灯吧

#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>

sleeps(int j){
	int i=0,m=0;
	for(i=0;i<j;i++){
		for(m=0;m<100000;m++){
		
		}	
	}
}
int main(void){
	int i,fd;
	fd=open("/dev/leds",O_RDWR);
	if(fd == -1)
	    exit(1);
	for(i=0;i<4;i++){
		ioctl(fd,0,i);
		sleeps(100);
		ioctl(fd,1,i);
		if(i == 3)
			i=0;
	}

}

编译一下这个程序,

arm-linux-gcc -o ledtest ledtest.c -static

就可以生成ledtest,注意如果把arm-linux-gcc的路径加到PATH环境变量中去,否则会出现找到不命令的错误。

把ledtest通过串口发到开发板中,因为没有执行权限,先运行chmod 777 ledtest

然后再./ledtest


就可以看到流水灯闪动了。



“手把手教你学linux驱动开发”OK6410系列之02---虚拟字符设备

上一篇文章我们介绍了如何在linux下编写一个模块,并加载到内核空间。通过实验我们了解了大体的流程以及模块的工作原理。本篇文章我们将介绍如何编写一个虚拟的字符设备驱动程序。        之所以称之...
  • luo3532869
  • luo3532869
  • 2012年05月13日 17:40
  • 333

linux设备驱动之我是led灯-基于OK6410开发板 .

转载自:http://blog.csdn.net/cediy2088long?viewmode=contents 学习嵌入式linux编程,我们接触到的大多是linux设备驱动程序的编程。今天我...
  • u011348999
  • u011348999
  • 2013年12月31日 18:48
  • 1683

ok6410学习笔记(16.按键中断控制led驱动)

这一节是我学驱动这么多天来,最头疼的一节,事后想了想应该是poll驱动当时没有做练习,再加上对前面的一些知识开始遗忘了,出现了好多不该出现的错误,还有些错误仍然没有解决,但是好歹功能是实现了,看来不动...
  • qq418674358
  • qq418674358
  • 2013年07月03日 00:48
  • 2924

Linux 字符设备驱动开发基础(一)—— 编写简单 LED 设备驱动

现在,我们来编写自己第一个字符设备驱动 —— 点亮LED。 硬件平台:Exynos4412(FS4412) 编写驱动分下面几步: a -- 查看原理图、数据手册,了解设备的操作方法; b -- 在...
  • zqixiao_09
  • zqixiao_09
  • 2016年03月10日 22:48
  • 4084

第一个驱动程序(点亮LED灯)

1.概述 一个软件系统分为:应用程序、库、操作系统、驱动程序。 (1)应用程序使用库函数提供的open打开LED设备文件。 (2)库根据open函数传入的参数执行“swi”指令,引起CPU异常进入内核...
  • ckfckf123
  • ckfckf123
  • 2015年03月24日 22:19
  • 1041

ok6410学习笔记(18.linux串口驱动程序设计)

串口这节的资料真的是少的可怜啊~~~国嵌这节讲的真心不敢恭维,网上的资料基本都是一个样子,不是说说s3c6400.c和samsung.c这两个文件就是说说驱动的结构。都是些意义不大的东西。      ...
  • qq418674358
  • qq418674358
  • 2013年07月13日 17:43
  • 3616

linux字符驱动之点亮LED

上一节中,我们讲解了如何自动创建设备节点,这一节我们在上一节的基础上,实现点亮LED。 上一节文章链接:http://blog.csdn.net/lwj103862095/article/detail...
  • lwj103862095
  • lwj103862095
  • 2013年12月21日 21:53
  • 4644

浅谈linux的LED驱动

从简单的LED程序来看整个系统的框架。
  • u013584315
  • u013584315
  • 2014年04月13日 16:50
  • 1491

Linux设备驱动第四天(自动创建设备节点、LED驱动程序)

回顾: 与驱动有关的几个重要结构体 1,struct cdev //从软件上代表硬件设备 { dev_t dev;//设备号 = 主设备号+次设备号 struct fi...
  • PZ0605
  • PZ0605
  • 2016年11月26日 23:01
  • 681

嵌入式Linux字符设备驱动LED驱动编写

嵌入式Linux字符设备驱动LED驱动编写 标签: linux内核 2015-04-30 14:41 105人阅读 评论(0) 收藏 举报  分类:   Linux开...
  • chinazhangzhong123
  • chinazhangzhong123
  • 2016年06月01日 21:50
  • 898
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux设备驱动之我是led灯-基于OK6410开发板
举报原因:
原因补充:

(最多只允许输入30个字)