内核中的kfifo的例子

来源:互联网 发布:帝国cms系统目录 编辑:程序博客网 时间:2024/06/17 00:06

  关于内核的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 <stefani@seibold.net> * * 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_SIZE128/* name of the proc entry */#definePROC_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 DYNAMICstruct kfifo_rec_ptr_1 test;#elsetypedef STRUCT_KFIFO_REC_1(FIFO_SIZE) mytest;static mytest test;#endifstatic const char *expected_result[] = {"a","bb","ccc","dddd","eeeee","ffffff","ggggggg","hhhhhhhh","iiiiiiiii","jjjjjjjjjj",};static int __init testfunc(void){charbuf[100];unsigned inti;unsigned intret;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 DYNAMICint ret;ret = kfifo_alloc(&test, FIFO_SIZE, GFP_KERNEL);if (ret) {printk(KERN_ERR "error kfifo_alloc\n");return ret;}#elseINIT_KFIFO(test);#endifif (testfunc() < 0) {#ifdef DYNAMICkfifo_free(&test);#endifreturn -EIO;}if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) {#ifdef DYNAMICkfifo_free(&test);#endifreturn -ENOMEM;}return 0;}static void __exit example_exit(void){remove_proc_entry(PROC_FIFO, NULL);#ifdef DYNAMICkfifo_free(&test);#endif}module_init(example_init);module_exit(example_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Stefani Seibold <stefani@seibold.net>");


内核的打印为

<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 -staticCC=arm-linux-gnueabi-gccEXEC1 =  kfifo_writeOBJS1 =  kfifo_write.oEXEC2 =  kfifo_readOBJS2 =  kfifo_read.oPWD :=$(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

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


0 0