linux led驱动

led驱动,需要了解硬件资源。查原理图,下面使用三种字符注册方式编写led驱动

1早期注册方式

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/io.h>
#include <asm/uaccess.h>

#define GPM4CON_PHY_ADDR 0x110002E0
#define GPM4DAT_PHY_ADDR 0x110002E4

static volatile unsigned long* gpm4con;
static volatile unsigned long* gpm4dat;

static int led_major;
static struct class* led_class;

static int led_open(struct inode *inod, struct file *fil)
{
return 0;
}

static int led_release(struct inode *inod, struct file *fil)
{
printk("led release......\n");

return 0;
}

static ssize_t led_write(struct file *fil, const char __user *buf, size_t count, loff_t *offsets)
{
unsigned char ledflag=0;

unsigned long ret = copy_from_user(&ledflag, buf, count);

*gpm4dat &= ~(0x1<<0);
*gpm4dat |= ledflag<<0;

return ret;
}

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

static int __init leddriver_init(void)
{
led_major = register_chrdev(0,"leddriver", &led_fops);

led_class = class_create(THIS_MODULE,"led_class");
device_create(led_class,NULL,MKDEV(led_major,0),NULL,"led");

gpm4con = ioremap(GPM4CON_PHY_ADDR,8);
gpm4dat = gpm4con + 1;

*gpm4con &= ~(0xF<<0);
*gpm4con |= 0x1<<0;
*gpm4dat |= 0x1<<0;

return 0;
}

static void __exit leddriver_exit(void)
{
iounmap(gpm4con);

device_destroy(led_class, MKDEV(led_major,0));
class_destroy(led_class);

unregister_chrdev(led_major, "leddriver");
}

module_init(leddriver_init);
module_exit(leddriver_exit);
MODULE_LICENSE("GPL");

 led测试程序

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
int led_fd;
unsigned char ledflag = 0;

if(argc!=3)
{
printf("Usage:<%s> </dev/?node> <0/1>\n",argv[0]);
return -1;
}

led_fd = open(argv[1],O_WRONLY);

ledflag = atoi(argv[2]);
write(led_fd, &ledflag,1);
}

 

 2cdev注册

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/cdev.h>


#define GPM4CON_PHY_ADDR 0x110002E0
#define GPM4DAT_PHY_ADDR 0x110002E4
#define count1 1

static volatile unsigned long* gpm4con;
static volatile unsigned long* gpm4dat;

static struct class* led_class;

static int led_open(struct inode *inod, struct file *fil)
{

return 0;
}

static int led_release(struct inode *inod, struct file *fil)
{

printk("led release......!!!\n");

return 0;
}

static ssize_t led_write(struct file *fil, const char __user *buf, size_t count, loff_t *offsets)
{
unsigned char ledflag=0;

unsigned long ret = copy_from_user(&ledflag, buf, count);

*gpm4dat &= ~(0x1<<0);
*gpm4dat |= ~(ledflag)<<0;

return ret;
}

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

static dev_t led_dev;
struct cdev *led_cdev;


static int __init leddriver_init(void)
{

//*******************************************************

alloc_chrdev_region(&led_dev, 0,count1,"leddriver");
led_cdev = cdev_alloc();

led_cdev->count = count1;
led_cdev->dev = led_dev;
led_cdev->ops = &led_fops;
led_cdev->owner = THIS_MODULE;

cdev_init(led_cdev,&led_fops);
cdev_add(led_cdev, led_dev,count1);

//********************************************************
led_class = class_create(THIS_MODULE,"led_class");
device_create(led_class,NULL,led_dev,NULL,"led");

gpm4con = ioremap(GPM4CON_PHY_ADDR,8);
gpm4dat = gpm4con + 1;

*gpm4con &= ~(0xF<<0);
*gpm4con |= 0x1<<0;
*gpm4dat |= 0x1<<0;

return 0;
}

static void __exit leddriver_exit(void)
{
iounmap(gpm4con);

device_destroy(led_class, led_dev);
class_destroy(led_class);

cdev_del(led_cdev);
unregister_chrdev_region(led_dev,count1);
}

module_init(leddriver_init);
module_exit(leddriver_exit);
MODULE_LICENSE("GPL");

 led测试

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
int led_fd;
unsigned char ledflag = 0;

if(argc!=3)
{
printf("Usage:<%s> </dev/?node> <0/1>\n",argv[0]);
return -1;
}

led_fd = open(argv[1],O_WRONLY);

ledflag = atoi(argv[2]);
write(led_fd, &ledflag,1);
}

 

 3杂项注册

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>


#define GPM4CON_PHY_ADDR 0x110002E0
#define GPM4DAT_PHY_ADDR 0x110002E4
#define count1 1

static volatile unsigned long* gpm4con;
static volatile unsigned long* gpm4dat;

static struct class* led_class;

static int led_open(struct inode *inod, struct file *fil)
{

return 0;
}

static int led_release(struct inode *inod, struct file *fil)
{

printk("led release......!!!\n");

return 0;
}

static ssize_t led_write(struct file *fil, const char __user *buf, size_t count, loff_t *offsets)
{
unsigned char ledflag=0;

unsigned long ret = copy_from_user(&ledflag, buf, count);

*gpm4dat &= ~(0x1<<0);
*gpm4dat |= ~(ledflag)<<0;

return ret;
}

static struct file_operations led_fops =
{
.owner = THIS_MODULE,
.open = led_open,
.release = led_release,
.write = led_write,
};
static struct miscdevice led_misc=
{
.minor = 255,
.name = "led",
.fops = &led_fops,

};


static dev_t led_dev;
struct cdev *led_cdev;


static int __init leddriver_init(void)
{

//*******************************************************
led_dev = misc_register(&led_misc);


//********************************************************
led_class = class_create(THIS_MODULE,"led_class");
device_create(led_class,NULL,led_dev,NULL,"led");

gpm4con = ioremap(GPM4CON_PHY_ADDR,8);
gpm4dat = gpm4con + 1;

*gpm4con &= ~(0xF<<0);
*gpm4con |= 0x1<<0;
*gpm4dat |= 0x1<<0;

return 0;
}

static void __exit leddriver_exit(void)
{
iounmap(gpm4con);

device_destroy(led_class, led_dev);
class_destroy(led_class);

misc_deregister(&led_misc);
}

module_init(leddriver_init);
module_exit(leddriver_exit);
MODULE_LICENSE("GPL");

 测试程序

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
int led_fd;
unsigned char ledflag = 0;

if(argc!=3)
{
printf("Usage:<%s> </dev/?node> <0/1>\n",argv[0]);
return -1;
}

led_fd = open(argv[1],O_WRONLY);

ledflag = atoi(argv[2]);
write(led_fd, &ledflag,1);
}

 

 Makefile

obj-m += leddriver.o
SOURCE = ledtest.o

CROSS_COMPLIE = arm-linux-
CC = $(CROSS_COMPLIE)gcc

KERNDIR = /centos/xyd/linux-3.5
#CURDIR = $(shell pwd)
CURDIR = `pwd`

.PHONY: module clean

all: module $(SOURCE:.o=)

module:
$(MAKE) -C $(KERNDIR) M=$(CURDIR) modules

$(SOURCE:.o=):$(SOURCE)
$(CC) -o $@ $^

%.o:%.c
$(CC) -c $<

clean:
$(MAKE) -C $(KERNDIR) M=$(CURDIR) clean
rm $(SOURCE:.o=)

 4编写多设备节点的led程序(一个节点控制一个灯亮)

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/cdev.h>


#define GPM4CON_PHY_ADDR 0x110002E0
#define GPM4DAT_PHY_ADDR 0x110002E4
#define count1 4

static volatile unsigned long* gpm4con;
static volatile unsigned long* gpm4dat;

static struct class* led_class;
static unsigned long led_minor;
static int led_open(struct inode *inod, struct file *fil)
{
//得到次设备号
led_minor = MINOR(inod->i_rdev);

*gpm4con &= ~(0xF<<(led_minor*4));
*gpm4con |= 0x1<<(led_minor*4);
*gpm4dat |= 0x1<<led_minor;

return 0;
}

static int led_release(struct inode *inod, struct file *fil)
{

printk("led release......!!!\n");

return 0;
}

static ssize_t led_write(struct file *fil, const char __user *buf, size_t count, loff_t *offsets)
{
unsigned char ledflag=0;

unsigned long ret = copy_from_user(&ledflag,buf,count);

*gpm4dat &= ~(0x1<<led_minor);
*gpm4dat |= ~(ledflag)<<led_minor;

return ret;
}

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

static dev_t led_dev;
struct cdev * led_cdev;


static int __init leddriver_init(void)
{
int i;

//*******************************************************

alloc_chrdev_region(&led_dev, 0,count1,"leddriver");
led_cdev = cdev_alloc();

led_cdev->count = count1;
led_cdev->dev = led_dev;
led_cdev->ops = &led_fops;
led_cdev->owner = THIS_MODULE;

cdev_init(led_cdev,&led_fops);
cdev_add(led_cdev, led_dev,count1);

//********************************************************
led_class = class_create(THIS_MODULE,"led_class");
for(i=0;i<count1;i++)
device_create(led_class,NULL,led_dev+i,NULL,"led%d",i);

gpm4con = ioremap(GPM4CON_PHY_ADDR,8);
gpm4dat = gpm4con + 1;


return 0;
}

static void __exit leddriver_exit(void)
{
int i;
iounmap(gpm4con);

for(i=0;i<count1;i++)
device_destroy(led_class, led_dev+i);

class_destroy(led_class);

cdev_del(led_cdev);
unregister_chrdev_region(led_dev,count1);
}

module_init(leddriver_init);
module_exit(leddriver_exit);
MODULE_LICENSE("GPL");

 测试程序

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
int led_fd;
unsigned char ledflag = 0;

if(argc!=3)
{
printf("Usage:<%s> </dev/?node> <0/1>\n",argv[0]);
return -1;
}

led_fd = open(argv[1],O_WRONLY);

ledflag = atoi(argv[2]);
write(led_fd, &ledflag,1);
}

 

 Makefile

obj-m += leddriver.o
SOURCE = ledtest.o

CROSS_COMPLIE = arm-linux-
CC = $(CROSS_COMPLIE)gcc

KERNDIR = /centos/xyd/linux-3.5
#CURDIR = $(shell pwd)
CURDIR = `pwd`

.PHONY: module clean

all: module $(SOURCE:.o=)

module:
$(MAKE) -C $(KERNDIR) M=$(CURDIR) modules

$(SOURCE:.o=):$(SOURCE)
$(CC) -o $@ $^

%.o:%.c
$(CC) -c $<

clean:
$(MAKE) -C $(KERNDIR) M=$(CURDIR) clean
rm $(SOURCE:.o=)

 

转载于:https://www.cnblogs.com/wqwlinux/p/6970995.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值