首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在内核空间程序中正确构建环形缓冲区?

如何在内核空间程序中正确构建环形缓冲区?
EN

Stack Overflow用户
提问于 2022-04-05 22:42:47
回答 1查看 354关注 0票数 1

我试图在内核空间中编写一个带有环形缓冲区的程序,它在用户空间上工作得很好,我用kmalloc替换了内存分配器,并得到了一个类型转换错误。以下是用户空间上的程序:

代码语言:javascript
复制
main ()
{
  char last_char = 'a';
  RingBuffer *buffer = newRingBuffer (10);
  RingBuffer_trywrite (buffer, last_char);
  RingBuffer_tryread(buffer, &last_char);
  printf ("%s", &last_char);

  return 0;
}

下面是内核空间程序代码的一部分:

代码语言:javascript
复制
struct RingBuffer* buffer;
static int __init ch_drv_init(void) {
buffer = newRingBuffer(BUF_CAPACITY);
}

环缓冲区的实现取自维基百科(https://ru.wikipedia.org/wiki/Кольцевой_буфер)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-06 13:04:47

请试试这个:

代码语言:javascript
复制
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/vmalloc.h>

#define CHAR_SIZE (sizeof(char))
#define RINGBUFFER_OK (0)
#define RINGBUFFER_ERR_NULL (-1)
#define RINGBUFFER_ERR_EMPTY (-2)
#define RINGBUFFER_ERR_FULL (-3)

struct RingBuffer {
    char *start;
    char *end;
    volatile char *readptr;
    volatile char *writeptr;
};

struct RingBuffer *newRingBuffer(unsigned long int capacity)
{
    struct RingBuffer *rb;
    char *mem = vmalloc(capacity * CHAR_SIZE);
    if (mem == NULL) {
        return NULL;
    }

    rb = vmalloc(sizeof(*rb));
    if (rb == NULL) {
        vfree(mem);
        return NULL;
    }

    rb->start = mem;
    rb->end = mem + capacity;
    rb->readptr = mem;
    rb->writeptr = mem;

    return rb;
}

void deleteRingBuffer(struct RingBuffer *rb)
{
    if (rb == NULL)
        return;

    vfree(rb->start);
    vfree(rb);
}

int RingBuffer_trywrite(struct RingBuffer *rb, char c)
{
    volatile char *tmp;
    if (rb == NULL)
        return RINGBUFFER_ERR_NULL;

    if (rb->writeptr + 1 == rb->readptr)
        return RINGBUFFER_ERR_FULL;

    *(rb->writeptr) = c;
    tmp = rb->writeptr + 1;
    if (tmp >= rb->end) tmp = rb->start;
    rb->writeptr = tmp;

    return RINGBUFFER_OK;
}

int RingBuffer_tryread(struct RingBuffer *rb, char *c)
{
    volatile char *tmp;
    if (rb == NULL)
        return RINGBUFFER_ERR_NULL;

    if (rb->readptr == rb->writeptr)
        return RINGBUFFER_ERR_EMPTY;

    *c = (*rb->readptr);
    tmp = rb->readptr + 1;
    if (tmp >= rb->end) tmp = rb->start;
    rb->readptr = tmp;

    return RINGBUFFER_OK;
}

static int __init init_test_module(void)
{
    char last_char = 'a';
    struct RingBuffer *buffer = newRingBuffer(10);
    RingBuffer_trywrite(buffer, last_char);
    RingBuffer_tryread(buffer, &last_char);
    pr_info("last_char: %c\n", last_char);
    deleteRingBuffer(buffer);

    return 0;
}

static void __exit exit_test_module(void)
{
}

module_init(init_test_module);
module_exit(exit_test_module);
MODULE_LICENSE("GPL");
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71759193

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档