linux下的字符设备驱动程序,Linux下的字符设备驱动

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

demo.c

linux driver example for UP_CUP6410 platform

It can be compiled for x86 PC

modify by sprife

derive from zou jian-guo's driver exp.

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

#ifdef MODULE

#include

#ifdef CONFIG_DEVFS_FS

#include

#endif

#include

#include /* printk() */

#include /* kmalloc() */

#include /* everything... */

#include /* error codes */

#include /* size_t */

#include

#include /* O_ACCMODE */

#include /* COPY_TO_USER */

#include /* cli(), *_flags */

#define DEVICE_NAME "UP-TECH DEMO"

#define DEMORAW_MINOR 1

#define DEMO_Devfs_path "demo/0"

static int demoMajor = 0;

static int MAX_BUF_LEN=1024;

static char drv_buf[1024];

static int WRI_LENGTH=0;

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

/*逆序排列缓冲区数据*/

static void do_write(void)

{

int i;

int len = WRI_LENGTH;

int mid = len>>1;

char tmp;

for(i = 0; i < mid; i++,len--){

tmp = drv_buf[len-1];

drv_buf[len-1] = drv_buf[i];

drv_buf[i] = tmp;

}

}

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

static ssize_t demo_write(struct file *file, const char __user *buffer, size_t count, loff_t * ppos)

{

if(count > MAX_BUF_LEN)count = MAX_BUF_LEN;

copy_from_user(drv_buf , buffer, count);

WRI_LENGTH = count;

// printk("user write data to driver\\n");

do_write();

return count;

}

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

static ssize_t demo_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos)

{

if(count > MAX_BUF_LEN)

count=MAX_BUF_LEN;

copy_to_user(buffer, drv_buf,count);

// printk("user read data from driver\\n");

return count;

}

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

static int demo_ioctl(struct inode *inode, struct file *filp,

unsigned int cmd, unsigned long arg)

{

// printk("ioctl runing\\n");

switch(cmd){

case 1:printk("runing command 1 \\n");break;

case 2:printk("runing command 2 \\n");break;

default:

printk("error cmd number\\n");break;

}

return 0;

}

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

static int demo_open(struct inode *inode, struct file *filp)

{

// MOD_INC_USE_COUNT;

printk(KERN_DEBUG" device open sucess!\\n");

return 0;

}

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

static int demo_release(struct inode *inode, struct file *filp)

{

// MOD_DEC_USE_COUNT;

printk(KERN_DEBUG "device release\\n");

return 0;

}

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

static struct file_operations pxa270_fops = {

owner: THIS_MODULE,

write: demo_write,

read: demo_read,

ioctl: demo_ioctl,

open: demo_open,

release: demo_release,

};

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

static int __init demo_init(void)

{

int ret;

ret = register_chrdev(0, DEVICE_NAME, &pxa270_fops);

if (ret < 0) {

printk(DEVICE_NAME " can't get major number\\n");

return ret;

}

demoMajor=ret;

printk("demo driver initialized \\n");

#ifdef CONFIG_DEVFS_FS

devfs_mk_cdev(MKDEV(demoMajor, DEMORAW_MINOR),

S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP, DEMO_Devfs_path);

#endif

return 0;

}

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

#ifdef MODULE

void __exit demo_exit(void)

{

#ifdef CONFIG_DEVFS_FS

devfs_remove(DEMO_Devfs_path);

#endif

unregister_chrdev(demoMajor, DEVICE_NAME);

}

module_exit(demo_exit);

#endif

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

module_init(demo_init);

MODULE_LICENSE("Dual BSD/GPL");

#endif // MODULE

/*

* Makefile 文件如下

*/

# To build modules outside of the kernel tree, we run "make"

# in the kernel source tree; the Makefile these then includes this

# Makefile once again.

# This conditional selects whether we are being included from the

# kernel Makefile or not.

TARGET = test_demo

CROSS_COMPILE =

CC = $(CROSS_COMPILE)gcc

STRIP = $(CROSS_COMPILE)strip

#CFLAGS = -O2

ifeq ($(KERNELRELEASE),)

# Assume the source tree is where the running kernel was built

# You should set KERNELDIR in the environment if it's elsewhere

# KERNELDIR ?=/home/sprife/kernel/linux-2.6.24.4

KERNELDIR ?=/linux-2.6.21

# KERNELDIR ?= /usr/src/kernels/2.6.9-42.EL-smp-i686/

# The current directory is passed to sub-makes as argument

PWD := $(shell pwd)

all: $(TARGET) modules

$(TARGET):

$(CC) -o $(TARGET) $(TARGET).c

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 $(TARGET)

.PHONY: modules modules_install clean

else

# called from kernel build system: just declare what our modules are

obj-m := demo.o

endif

#include

#include

#include

#include

#include

void showbuf(char *buf);

int MAX_LEN=32;

/*

* 驱动测试文件如下

*/

int main(int argc,char **argv)

{

int fd;

int i;

char buf[255];

for(i=0; i

buf[i]=i;

}

fd=open("/dev/demo",O_RDWR);

if(fd < 0){

printf("####DEMO device open fail####\\n");

return (-1);

}

printf("write %d bytes data to /dev/demo \\n",MAX_LEN);

showbuf(buf);

write(fd,buf,MAX_LEN);

printf("Read %d bytes data from /dev/demo \\n",MAX_LEN);

read(fd,buf,MAX_LEN);

showbuf(buf);

// ioctl(fd,1,NULL);

// ioctl(fd,4,NULL);

close(fd);

return 0;

}

void showbuf(char *buf)

{

int i,j=0;

for(i=0;i

if(i%4 ==0)

printf("\\n%4d: ",j++);

printf("%4d ",buf[i]);

}

printf("\\n*****************************************************\\n");

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值