四、内核KFIFO

4.1、概述

  • 在驱动编程中,经常会遇到异步数据处理的情况,比如采用中断或定时器处理数据输入输出等情况
  • 此时数据的采集与处理往往不同步,于是驱动编程中数据采集方需要将采集的数据暂时放到一个缓冲区中,使用方在需要处理数据时从缓冲区中将数据读出
  • 驱动编程中常采用队列这种数据结构来实现整个过程,我们可以选择自己编写一个队列,也可以利用内核中现有队列kfifo来实现。

4.2、使用过程

  1. 定义KFIFO变量;
  2. 为KFIFO开辟空间;
  3. 把数据写入KFIFO;
  4. 从KFIFO读出数据;
  5. 释放KFIFO。

4.3、KFIFO相关的API

#include <linux/kfifo.h>  //头文件包含

//kfifo结构体类型
struct kfifo{
unsigned char *buffer; //存放数据的缓存区
unsigned int size; //buffer空间大小
unsigned int in; //指向buffer队头
unsigned int out; //指向buffer队尾
};

第四讲 Linux内核KFIFO的使用_kfifo

1. kfifo申请分配空间:

/*
*gfp_mask申请内存的flags:
*GFP_KERNEL 在分配的空间时可以参与进程调度
*GFP_ATOMIC 在分配空间时,必须一次性完成
*/
int kfifo_alloc(struct kfifo *fifo,unsigned int size, gfp_t gfp_mask)

void kfifo_free(struct kfifo*fifo) //释放空间

2. 内核空间内存的申请和释放

/* kmalloc分配的空间在物理内存和虚拟内存上均连续*/
void *kmalloc(size_t size,gfp_t gfp);
void kfree(void *p);

/*分配的内存空间在虚拟内存上连续,在物理内存上不一定连续*/
void* vmalloc(unsigned long size);
void vfree(void*ptr);

3. kfifo相关操作:

  • 将数据放入kfifo内,返回值为实际写入的数据长度:
unsigned int kfifo_in(struct kfifo *fifo,const void *from, unsigned int len);
  • 从kfifo读取数据,返回值为实际读出的数据长度:
unsigned int kfifo_out(struct kfifo *fifo, void *to, unsigned int len);
  • 获取fifo内的已用数据个数 :
unsigned int kfifo_len(struct kfifo *fifo);
  • 获取fifo总大小:
unsigned int kfifo_size(struct kfifo *fifo);
  • 检查kfifo是否为空:
int kfifo_is_empty(struct kfifo *fifo);
  • 检查kfifo是否为满:
int kfifo_is_full(struct kfifo *fifo);