OK6410驱动之led(只用指定的设备号)

Linux 驱动学习之led驱动

首先是led.c文件:

#include <linux/module.h>  
#include <linux/kernel.h>  
#include <linux/fs.h>  
#include <asm/uaccess.h> /* copy_to_user,copy_from_user */  
#include <linux/miscdevice.h>    
#include <linux/pci.h>    
#include <mach/map.h>    
#include <mach/regs-gpio.h>    
#include <mach/gpio-bank-m.h>    
#include <plat/gpio-cfg.h>  


#define LED_MAJOR 240  


int led_open(struct inode *inode, struct file *filp)


{
	unsigned tmp;
	tmp = readl(S3C64XX_GPMCON);
//	tmp = (tmp & ~(0x7U << 1)) | (0x1U);
	tmp = (tmp & ~(0xffff)) | (0x1111);
	writel(tmp, S3C64XX_GPMCON);
	printk("#########open######\n");
	return 0;
}


ssize_t led_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
	printk("#########read######\n");
	return count;
}




ssize_t led_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
	char wbuf[10];
	unsigned tmp;
	printk("#########write######\n");
	copy_from_user(wbuf, buf, count);
	switch (wbuf[0])
	{
	case 0:  //off  
		tmp = readl(S3C64XX_GPMDAT);
		tmp |= (0xFU);
		writel(tmp, S3C64XX_GPMDAT);
		break;
	case 1:  //on  
		tmp = readl(S3C64XX_GPMDAT);
		tmp &= ~(0xFU);
		writel(tmp, S3C64XX_GPMDAT);
		break;
	default:
		break;
	}
	return count;
}


int led_release(struct inode *inode, struct file *filp)
{
	printk("#########release######\n");
	return 0;
}


struct file_operations led_fops = {
	.owner = THIS_MODULE,
	.open = led_open,
	.read = led_read,
	.write = led_write,
	.release = led_release,
};


int __init led_init(void)
{
	int rc;
	printk("Test led dev\n");
	rc = register_chrdev(LED_MAJOR, "led", &led_fops);
	if (rc <0)
	{
		printk("register %s char dev error\n", "led");
		return -1;
	}
	printk("ok!\n");
	return 0;
}


void __exit led_exit(void)
{
	unregister_chrdev(LED_MAJOR, "led");
	printk("module exit\n");
	return;
}


module_init(led_init);
module_exit(led_exit);


以上led.c就是led驱动的主要内容了,然后是Makefile文件:

obj-m:=led.o
KDIR:=/home/msc/Desktop/linux-3.0.1/
all:
	make -C $(KDIR) M=$(shell pwd) modules
clean:
	make -C $(KDIR) M=$(shell pwd) clean



这里的KDIR是和目标板相同的内核的交叉编译路径。

最后是测试代码test.c:

#include <stdio.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <fcntl.h>  
//#include <linux/io.h>
//#include <linux/gpio.h>
int main(void)
{
	int fd;
	char buf[10] = { 0,1 };
	fd = open("/dev/my_led", O_RDWR);
	if (fd < 0)
	{
		printf("Open /dev/my_led file error\n");
		return -1;
	}
	while (1)
	{
		write(fd, &buf[0], 1);
		sleep(1);
		write(fd, &buf[1], 1);
		sleep(1);
	}
	close(fd);
	return 0;


}


步骤:

1.将以上三个文件放在同一个文件夹下,使用make指令进行编译生成led.ko驱动。

2.使用arm-linux-gcc -o test test.c编译测试代码。

3.使用网络文件系统将上述文件夹挂载到目标板上

4.使用insmod led.ko 命令加载驱动。

5.使用mknod /dev/my_led c 240 0 创建设备文件。

6.运行测试代码./test就可以看到OK6410开发板上的四个led同时闪烁。


这里led.c 文件里芯片寄存器的配置是根据数据手册来的。所以还是要认真看数据手册。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值