内核中的kfifo的例子

  关于内核的kfifo介绍,可参考http://www.cnblogs.com/Anker/p/3481373.html

咱玩一点理论性没这么强的东西,先那个例子来跑一下就知道是怎么回事了。这里以内核下的samples/kfifo/record-example.c为例

/*
 * Sample dynamic sized record fifo implementation
 *
 * Copyright (C) 2010 Stefani Seibold <[email protected]>
 *
 * Released under the GPL version 2 only.
 *
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/mutex.h>
#include <linux/kfifo.h>

/*
 * This module shows how to create a variable sized record fifo.
 */

/* fifo size in elements (bytes) */
#define FIFO_SIZE	128

/* name of the proc entry */
#define	PROC_FIFO	"record-fifo"

/* lock for procfs read access */
static DEFINE_MUTEX(read_lock);

/* lock for procfs write access */
static DEFINE_MUTEX(write_lock);

/*
 * define DYNAMIC in this example for a dynamically allocated fifo.
 *
 * Otherwise the fifo storage will be a part of the fifo structure.
 */
#if 0
#define DYNAMIC
#endif

/*
 * struct kfifo_rec_ptr_1 and  STRUCT_KFIFO_REC_1 can handle records of a
 * length between 0 and 255 bytes.
 *
 * struct kfifo_rec_ptr_2 and  STRUCT_KFIFO_REC_2 can handle records of a
 * length between 0 and 65535 bytes.
 */

#ifdef DYNAMIC
struct kfifo_rec_ptr_1 test;

#else
typedef STRUCT_KFIFO_REC_1(FIFO_SIZE) mytest;

static mytest test;
#endif

static const char *expected_result[] = {
	"a",
	"bb",
	"ccc",
	"dddd",
	"eeeee",
	"ffffff",
	"ggggggg",
	"hhhhhhhh",
	"iiiiiiiii",
	"jjjjjjjjjj",
};

static int __init testfunc(void)
{
	char		buf[100];
	unsigned int	i;
	unsigned int	ret;
	struct { unsigned char buf[6]; } hello = { "hello" };

	printk(KERN_INFO "record fifo test start\n");

	kfifo_in(&test, &hello, sizeof(hello));

	/* show the size of the next record in the fifo */
	printk(KERN_INFO "fifo peek len: %u\n", kfifo_peek_len(&test));

	/* put in variable length data */
	for (i = 0; i < 10; i++) {
		memset(buf, 'a' + i, i + 1);
		kfifo_in(&test, buf, i + 1);
	}

	/* skip first element of the fifo */
	printk(KERN_INFO "skip 1st element\n");
	kfifo_skip(&test);

	printk(KERN_INFO "fifo len: %u\n", kfifo_len(&test));

	/* show the first record without removing from the fifo */
	ret = kfifo_out_peek(&test, buf, sizeof(buf));
	if (ret)
		printk(KERN_INFO "%.*s\n", ret, buf);

	/* check the correctness of all values in the fifo */
	i = 0;
	while (!kfifo_is_empty(&test)) {
		ret = kfifo_out(&test, buf, sizeof(buf));
		buf[ret] = '\0';
		printk(KERN_INFO "item = %.*s\n", ret, buf);
		if (strcmp(buf, expected_result[i++])) {
			printk(KERN_WARNING "value mismatch: test failed\n");
			return -EIO;
		}
	}
	if (i != ARRAY_SIZE(expected_result)) {
		printk(KERN_WARNING "size mismatch: test failed\n");
		return -EIO;
	}
	printk(KERN_INFO "test passed\n");

	return 0;
}

static ssize_t fifo_write(struct file *file, const char __user *buf,
						size_t count, loff_t *ppos)
{
	int ret;
	unsigned int copied;

	if (mutex_lock_interruptible(&write_lock))
		return -ERESTARTSYS;

	ret = kfifo_from_user(&test, buf, count, &copied);

	mutex_unlock(&write_lock);

	return ret ? ret : copied;
}

static ssize_t fifo_read(struct file *file, char __user *buf,
						size_t count, loff_t *ppos)
{
	int ret;
	unsigned int copied;

	if (mutex_lock_interruptible(&read_lock))
		return -ERESTARTSYS;

	ret = kfifo_to_user(&test, buf, count, &copied);

	mutex_unlock(&read_lock);

	return ret ? ret : copied;
}

static const struct file_operations fifo_fops = {
	.owner		= THIS_MODULE,
	.read		= fifo_read,
	.write		= fifo_write,
	.llseek		= noop_llseek,
};

static int __init example_init(void)
{
#ifdef DYNAMIC
	int ret;

	ret = kfifo_alloc(&test, FIFO_SIZE, GFP_KERNEL);
	if (ret) {
		printk(KERN_ERR "error kfifo_alloc\n");
		return ret;
	}
#else
	INIT_KFIFO(test);
#endif
	if (testfunc() < 0) {
#ifdef DYNAMIC
		kfifo_free(&test);
#endif
		return -EIO;
	}

	if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) {
#ifdef DYNAMIC
		kfifo_free(&test);
#endif
		return -ENOMEM;
	}
	return 0;
}

static void __exit example_exit(void)
{
	remove_proc_entry(PROC_FIFO, NULL);
#ifdef DYNAMIC
	kfifo_free(&test);
#endif
}

module_init(example_init);
module_exit(example_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Stefani Seibold <[email protected]>");


内核的打印为

<6>[(1975-10-08 17:34:05.583932503 UTC)] record fifo test start
<6>[(1975-10-08 17:34:05.583974429 UTC)] fifo peek len: 6
<6>[(1975-10-08 17:34:05.583995170 UTC)] skip 1st element
<6>[(1975-10-08 17:34:05.584013244 UTC)] fifo len: 65
<6>[(1975-10-08 17:34:05.584031021 UTC)] a
<6>[(1975-10-08 17:34:05.584047318 UTC)] item = a
<6>[(1975-10-08 17:34:05.584063614 UTC)] item = bb
<6>[(1975-10-08 17:34:05.584078281 UTC)] item = ccc
<6>[(1975-10-08 17:34:05.584093095 UTC)] item = dddd
<6>[(1975-10-08 17:34:05.584109688 UTC)] item = eeeee
<6>[(1975-10-08 17:34:05.584124799 UTC)] item = ffffff
<6>[(1975-10-08 17:34:05.584141392 UTC)] item = ggggggg
<6>[(1975-10-08 17:34:05.584156651 UTC)] item = hhhhhhhh
<6>[(1975-10-08 17:34:05.584173836 UTC)] item = iiiiiiiii
<6>[(1975-10-08 17:34:05.584189243 UTC)] item = jjjjjjjjjj
<6>[(1975-10-08 17:34:05.584205540 UTC)] test passed


写个进程(kfifo_write)去写kfifo

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <semaphore.h>
#include <pthread.h>
#include <string.h>

#define DEVICE_NAME "/proc/record-fifo"
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) 
static const char *expected_result[] = {
	"a",
	"bb",
	"ccc",
	"dddd",
	"eeeee",
	"ffffff",
	"ggggggg",
	"hhhhhhhh",
	"iiiiiiiii",
	"jjjjjjjjjj",
};

int main(void)
{	
    
	
	int fd;
	int ret;
	int i;
	fd=open(DEVICE_NAME,O_RDWR);
	if(fd<0)
	{
		printf("open kfifo err!");
		return -1;
	}

	while(1)
	{	
		for(i=0;i<ARRAY_SIZE(expected_result);i++)
		{
			ret=write(fd,expected_result[i],strlen(expected_result[i]));
			printf("the size of array[%d])=%d\n",i,strlen(expected_result[i]));	
			if(ret<0)
			printf("write err!\n");		 
			sleep(2);
		    printf("----kfifo write---\n");
		}
	}
	return 0;
}

写个进程(kfifo_read)去读kfifo

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <semaphore.h>
#include <pthread.h>
#include <string.h>

#define DEVICE_NAME "/proc/record-fifo"
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) 
static const char *expected_result[] = {
	"a",
	"bb",
	"ccc",
	"dddd",
	"eeeee",
	"ffffff",
	"ggggggg",
	"hhhhhhhh",
	"iiiiiiiii",
	"jjjjjjjjjj",
};

int main(void)
{		
	int fd;
	int ret;
	int i;
	char *buf;
	fd=open(DEVICE_NAME,O_RDWR);
	if(fd<0)
	{
		printf("open kfifo err!");
		return -1;
	}
	buf=malloc(10);
	if(buf<0)
		return -1;
	while(1)
	{
	
		
			ret=read(fd,buf,10);
			if(ret<0)
				printf("read kfifo err!\n");
			else if(ret==0)
				printf("no kfifo read!\n");
			else
				{
				printf("----kfifo read---\n");
				buf[ret]='\0';
				printf("read length is %d,and the string is %s\n",ret,buf);	
				} 
			sleep(1);	    
	}
	return 0;
}


同时写个Makefile,将驱动和应用同时编译出来

ifeq ($(KERNELRELEASE),)  
KERNELDIR ?= /home/w/xxxx/kernel/
DBG_CROSS_COMPILE ?= /home/w/xxxxx/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
EXTRA_LIBS += -lpthread -static
CC=arm-linux-gnueabi-gcc
EXEC1 =  kfifo_write
OBJS1 =  kfifo_write.o
EXEC2 =  kfifo_read
OBJS2 =  kfifo_read.o
PWD :=$(shell pwd)  
all: $(EXEC1) $(EXEC2) modules
$(EXEC1): $(OBJS1)
	$(CC) $(LDFLAGS) -o $@ $(OBJS1)  $(EXTRA_LIBS)
$(EXEC2): $(OBJS2)
	$(CC) $(LDFLAGS) -o $@ $(OBJS2)  $(EXTRA_LIBS)
modules:  
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules  
modules_install:  
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install  
clear:  
	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions modules.order  Module.symvers  *.elf *.elf2flt *.gdb *.o 
else  
     obj-m:= kfifo.o  
endif


先运行kfifo_read,再运行kfifo_write,打印信息为

root@android:/system # ./kfifo_write                                           
the size of array[0])=1
----kfifo write---
the size of array[1])=2
----kfifo write---
the size of array[2])=3
----kfifo write---
the size of array[3])=4
----kfifo write---
the size of array[4])=5
----kfifo write---
the size of array[5])=6
----kfifo write---
the size of array[6])=7
----kfifo write---
the size of array[7])=8
----kfifo write---
the size of array[8])=9
----kfifo write---
the size of array[9])=10
----kfifo write---
the size of array[0])=1
----kfifo write---
the size of array[1])=2
----kfifo write---

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

root@android:/system # ./kfifo_read                                            
no kfifo read!
no kfifo read!
no kfifo read!
no kfifo read!
no kfifo read!
no kfifo read!
no kfifo read!
no kfifo read!
no kfifo read!
no kfifo read!
no kfifo read!
no kfifo read!
no kfifo read!
no kfifo read!
no kfifo read!
no kfifo read!
no kfifo read!
no kfifo read!
----kfifo read---
read length is 1,and the string is a
no kfifo read!
----kfifo read---
read length is 2,and the string is bb
no kfifo read!
----kfifo read---
read length is 3,and the string is ccc
no kfifo read!
----kfifo read---
read length is 4,and the string is dddd
no kfifo read!
----kfifo read---
read length is 5,and the string is eeeee
no kfifo read!
----kfifo read---
read length is 6,and the string is ffffff
no kfifo read!
----kfifo read---
read length is 7,and the string is ggggggg
no kfifo read!
----kfifo read---
read length is 8,and the string is hhhhhhhh
no kfifo read!
----kfifo read---
read length is 9,and the string is iiiiiiiii
no kfifo read!
----kfifo read---
read length is 10,and the string is jjjjjjjjjj
no kfifo read!
----kfifo read---
read length is 1,and the string is a
no kfifo read!
----kfifo read---
read length is 2,and the string is bb

-----------------------------------------------------------------------------------------------------------------------------------------------------------------


你可能感兴趣的:(内核中的kfifo的例子)