Linux kfifo的使用
基于3.10-lsti内核
Kfifo也叫内核队列。
1.首先定义struct kfifo fifo;
2. kfifo初始化。
方法一:动态分配并初始化
Int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask)
* kfifo_alloc - dynamically allocates a new fifo buffer
* @fifo: pointer to the fifo
* @size: the number of elements in the fifo, this must be a power of 2
* @gfp_mask: get_free_pages mask, passed to kmalloc()
*
* This macro dynamically allocates a new fifo buffer.
*
* The numer of elements will be rounded-up to a power of 2.
* The fifo will be release with kfifo_free().
* Return 0 if no error, otherwise an error code.
Size大小最好为2的幂。
ret = kfifo_alloc(&fpga_uart_device.fifo,1024,GFP_KERNEL);
方法二:先分配空间,在初始化。
/**
* kfifo_init - initialize a fifo using a preallocated buffer
* @fifo: the fifo to assign the buffer
* @buffer: the preallocated buffer to be used
* @size: the size of the internal buffer, this have to be a power of 2
*
* This macro initialize a fifo using a preallocated buffer.
*
* The numer of elements will be rounded-up to a power of 2.
* Return 0 if no error, otherwise an error code.
*/
#define kfifo_init(fifo, buffer, size) \
({ \
typeof((fifo) + 1) __tmp = (fifo); \
struct __kfifo *__kfifo = &__tmp->kfifo; \
__is_kfifo_ptr(__tmp) ? \
__kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \
-EINVAL; \
})
3.
入fifo
/**
* kfifo_in - put data into the fifo
* @fifo: address of the fifo to be used
* @buf: the data to be added
* @n: number of elements to be added
*
* This macro copies the given buffer into the fifo and returns the
* number of copied elements.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define
kfifo_in(fifo, buf, n)
4.出fifo
/**
* kfifo_out - get data from the fifo
* @fifo: address of the fifo to be used
* @buf: pointer to the storage buffer
* @n: max. number of elements to get
*
* This macro get some data from the fifo and return the numbers of elements
* copied.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define
kfifo_out(fifo, buf, n)
5.
返回fifo内部元素的个数 /**
* kfifo_len - returns the number of used elements in the fifo
* @fifo: address of the fifo to be used
*/
#define kfifo_len(fifo)
count = kfifo_len(&g_uart_devicep->fifo);
6. 返回fifo内部未使用空间的个数
/**
* kfifo_avail - returns the number of unused elements in the fifo
* @fifo: address of the fifo to be used
*/
#define
kfifo_avail(fifo)
7. puts some data from user space into the fifo
/**
* kfifo_from_user - puts some data from user space into the fifo
* @fifo: address of the fifo to be used
* @from: pointer to the data to be added
* @len: the length of the data to be added
* @copied: pointer to output variable to store the number of copied bytes
*
* This macro copies at most @len bytes from the @from into the
* fifo, depending of the available space and returns -EFAULT/0.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define
kfifo_from_user(fifo, from, len, copied)
8. copies data from the fifo into user space
/**
* kfifo_to_user - copies data from the fifo into user space
* @fifo: address of the fifo to be used
* @to: where the data must be copied
* @len: the size of the destination buffer
* @copied: pointer to output variable to store the number of copied bytes
*
* This macro copies at most @len bytes from the fifo into the
* @to buffer and returns -EFAULT/0.
*
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these macro.
*/
#define
kfifo_to_user(fifo, to, len, copied)
9. /**
* kfifo_free - frees the fifo
* @fifo: the fifo to be freed
*/
#define kfifo_free(fifo)
应用样例:
Int ret=0;
Int count = 0;
Unsigned char tempbuf[1024] = {0};
struct kfifo fifo;
ret = kfifo_alloc(&fifo, 1024, GFP_KERNEL);//分配1024个大小的空间,并初始化。
if(ret)//返回值为非0,代表出错。
return error;
count = kfifo_len(&fifo);//查看fifo空间里的元素个数。
count = kfifo_avail(fifo);//查看fifo空间里空闲的个数。
count = kfifo_in(&fifo,(void *)(tempbuf),20);//入队列20个字节到fifo中。返回成功copy的个数。
count = kfifo_out(&fifo,(void *)(tempbuf),20);//出队列20个字节到tempbuf中。返回成功copy的个数。
ret = kfifo_to_user(&fifo, (void *)_usr,20,&copied);//出队列20个字节到用户空间,copied为copy成功的字节数。
ret = kfifo_from_user(&fifo, (void *) _usr, 20, &copied);// 从用记空间copy 20个字节到队列中,copied为copy成功的字节数。