FIFO is a first in first out data structure that which can be used to hold any kind of data. Linux kernel provides useful APIs to make creation and use of FIFO data structure easy.
The first step in creation of FIFO is to define the FIFO required with the type of data it will be holding using
Once the FIFO has been defined we can use a number of functions available to add,remove, check the FIFO. To put data into the FIFO
To take the date out of the FIFO
Just to see the above functions in use we will create a proc entry which will output one data from a FIFO that gets created as soon as the module is inserted into the kernel.
To create a module with 6 char entries
An array of values to be added to the FIFO
To add the entries into the FIFO when the module gets inserted into the kernel, the init function needs to call the kfifo_put function
Once the fifo has been created, we can extract one data at a time using the function kfifo_get . To ensure that only one data is read from the FIFO each time we use the cat command on the proc entry extra checks and flags are needed
The function kfifo_is_empty returns true when the fifo is empty else it returns false.
The full code for creation of the proc entry called "fifo" which will output one data value at a time is:
If the file is saved as proc_read_fifo.c, it can be compiled using
To test the code, once the compile and insert the code
Read the proc entry using the cat command
The output shows that every call to read the entry removes one item from the fifo and when all entries are removed "FIFO empty" message gets printed.
The first step in creation of FIFO is to define the FIFO required with the type of data it will be holding using
Once the FIFO has been defined we can use a number of functions available to add,remove, check the FIFO. To put data into the FIFO
To take the date out of the FIFO
Just to see the above functions in use we will create a proc entry which will output one data from a FIFO that gets created as soon as the module is inserted into the kernel.
To create a module with 6 char entries
An array of values to be added to the FIFO
To add the entries into the FIFO when the module gets inserted into the kernel, the init function needs to call the kfifo_put function
Once the fifo has been created, we can extract one data at a time using the function kfifo_get . To ensure that only one data is read from the FIFO each time we use the cat command on the proc entry extra checks and flags are needed
The function kfifo_is_empty returns true when the fifo is empty else it returns false.
The full code for creation of the proc entry called "fifo" which will output one data value at a time is:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <linux/module.h> | |
#include <linux/kernel.h> | |
#include <linux/proc_fs.h> | |
#include<linux/sched.h> | |
#include <asm/uaccess.h> | |
#include<linux/slab.h> | |
#include<linux/kfifo.h> | |
#define FIFO_SIZE 32 | |
ssize_t size; | |
int flag=1; | |
char entries[]={'a','b','c','d','e','f','g','h'}; | |
DEFINE_KFIFO(test,char,FIFO_SIZE); | |
ssize_t read_proc(struct file *filp,char *buf,size_t count,loff_t *offp ) | |
{ | |
int ret,size; | |
char *temp,*start; | |
temp=kmalloc(sizeof(char)*10,GFP_KERNEL); | |
start=temp; | |
if(flag==0) { | |
size=0; | |
flag=1; | |
printk(KERN_INFO "in if"); | |
} | |
else { | |
if(kfifo_is_empty(&test)) { | |
temp="FIFO empty\n"; | |
printk(KERN_INFO "in empty"); | |
size=strlen(temp); | |
simple_read_from_buffer(buf,count,offp,temp,size); | |
} | |
else { | |
ret=kfifo_get(&test,temp); | |
temp=temp+1; | |
printk(KERN_INFO "in else %d",ret); | |
*temp='\n'; | |
simple_read_from_buffer(buf,count,offp,start,ret+1); | |
size=ret+1; | |
} | |
flag=flag-1; | |
} | |
return size; | |
} | |
struct file_operations proc_fops = { | |
read: read_proc | |
}; | |
void create_new_proc_entry(void) | |
{ | |
proc_create("fifo",0,NULL,&proc_fops); | |
} | |
int proc_init (void) { | |
int i=0; | |
create_new_proc_entry(); | |
for(i=0;i<6;i++) | |
kfifo_put(&test,entries[i]); | |
return 0; | |
} | |
void proc_cleanup(void) { | |
remove_proc_entry("fifo",NULL); | |
} | |
MODULE_LICENSE("GPL"); | |
module_init(proc_init); | |
module_exit(proc_cleanup); |
If the file is saved as proc_read_fifo.c, it can be compiled using
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ifneq ($(KERNELRELEASE),) | |
obj-m := proc_read_fifo1.o | |
else | |
KERNELDIR ?= /lib/modules/$(shell uname -r)/build | |
PWD := $(shell pwd) | |
default: | |
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules | |
clean: | |
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean | |
endif | |
To test the code, once the compile and insert the code
Read the proc entry using the cat command
The output shows that every call to read the entry removes one item from the fifo and when all entries are removed "FIFO empty" message gets printed.
No comments:
Post a Comment