您的位置:首页 > 其它

6-1 misc设备驱动开发与实例

2013-07-13 11:46 363 查看
6-1 misc设备驱动开发与实例

1、实例

1.1驱动程序

(1)驱动源代码\beep_misc\driver\beep_misc.c:

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <mach/regs-clock.h>
#include <plat/regs-timer.h>

#include <mach/regs-gpio.h>
// /opt/linux-2.6.34/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
#include <linux/cdev.h>

#define DEVICE_NAME		"beep"

MODULE_AUTHOR("Hanson He");
MODULE_LICENSE("Dual BSD/GPL");

#define BEEP_MAGIC 'k'
#define BEEP_START_CMD _IO (BEEP_MAGIC, 1)
#define BEEP_STOP_CMD _IO (BEEP_MAGIC, 2)

/*
* Open the device; in fact, there's nothing to do here.
*/
int beep_open (struct inode *inode, struct file *filp)
{
return 0;
}

ssize_t beep_read(struct file *file, char __user *buff, size_t count, loff_t *offp)
{
return 0;
}

ssize_t beep_write(struct file *file, const char __user *buff, size_t count, loff_t *offp)
{
return 0;
}

void beep_stop( void )
{
//add your src HERE!!!
//set GPB0 as output
s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPB(0),0);

}

void beep_start( void )
{
//add your src HERE!!!
//set GPB0 as output
s3c2410_gpio_pullup(S3C2410_GPB(0),1);
s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPB(0),1);

}

static int beep_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
//add your src HERE!!!
switch ( cmd ) {
case BEEP_START_CMD: {
beep_start(); 	break;
}
case BEEP_STOP_CMD: {
beep_stop(); 	break;
}
default: {
break;
}
}
return 0;

}

static int beep_release(struct inode *node, struct file *file)
{
return 0;
}

/*
* Our various sub-devices.
*/
/* Device 0 uses remap_pfn_range */
static struct file_operations beep_remap_ops = {
.owner   = THIS_MODULE,
.open    = beep_open,
.release = beep_release,
.read    = beep_read,
.write   = beep_write,
.ioctl   = beep_ioctl,
};

/*
* There's no need for us to maintain any
* special housekeeping info, so we just deal with raw cdevs.
*/

static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR, //动态设备号
.name = DEVICE_NAME,
.fops = &beep_remap_ops,
};

/*
* Module housekeeping.
*/
static int beep_init(void)
{
int ret;

ret = misc_register(&misc);

printk("The device name is: %s\n", DEVICE_NAME);
return 0;
}

static void beep_cleanup(void)
{
misc_deregister(&misc);
printk("beep device uninstalled\n");
}

module_init(beep_init);
module_exit(beep_cleanup);

(2)Makefile文件:

ifeq ($(KERNELRELEASE),)

#KERNELDIR ?= /your/target/source/directory/
KERNELDIR ?=/opt/linux-2.6.34
PWD := $(shell pwd)

modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

.PHONY: modules modules_install clean

else
obj-m := beep_misc.o
endif

1.2用户程序

(1)用户源代码\beep_misc\user\main.c:

/*
* main.c : test beep driver
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/ioctl.h>

#define BEEP_MAGIC 'k'
#define BEEP_START_CMD _IO (BEEP_MAGIC, 1)
#define BEEP_STOP_CMD _IO (BEEP_MAGIC, 2)

int main()
{
int i = 0;
int dev_fd;
dev_fd = open("/dev/beep",O_RDWR | O_NONBLOCK);
if ( dev_fd == -1 ) {
printf("Cann't open file /dev/beep\n");
exit(1);
}
printf("Start beep\n");
ioctl (dev_fd, BEEP_START_CMD,0);
getchar();
ioctl (dev_fd, BEEP_STOP_CMD,0);
printf("Stop beep and Close device\n");
close(dev_fd);
return 0;
}

(2)Makefile文件:

KERNELDIR ?=/opt/linux-2.6.34
all: beep_test

beep_test : main.c
#arm-linux-gcc -I$(KERNELDIR) -s -Wl,-warn-common --static -o $@ $^
arm-linux-gcc -I$(KERNELDIR) -o $@ $^

clean :
rm beep_test


声明:本文非原创,整理自申嵌。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: