我正在学习如何为 linux 编写设备驱动程序,并且我有一个关于使用通用数据结构的问题。
我有一个任务,我有完整的功能......所以我不要求你做我的家庭作业......
此分配要求设备能够将元素从 fifo 缓冲区中入队和出队。我使缓冲区“通用”,以便可以使用任何元素大小(并在运行时指定)。源码在下面(注意这不是内核版本,但错误是一样的)...内核版本需要kmalloc,copy_to/from_user()等...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct RB_Buffer
{
void* RBData;
unsigned int getindex; //index to remove element
unsigned int putindex; //index to put element at
unsigned int capacity; //max elements buffer holds
unsigned int elemCount; //num elements inserted
unsigned int elemSize; //size of each element
};
void* RB_kcreate(int numElements, unsigned int elementSize);
int putring(struct RB_Buffer *rbptr, void* data);
int getring(struct RB_Buffer *rbptr, void* data);
//Creates a Ring buffer of specified number of elements and element size.
//Returns void* pointer pointing to the RB_Buffer struct. This pointer can
//then be used on putring and getring functions.
void* RB_kcreate(int numElements, unsigned int elementSize)
{
struct RB_Buffer *newBuf = malloc(sizeof(struct RB_Buffer));
if(newBuf == NULL) return 0;
newBuf->RBData = (void*)malloc(elementSize*numElements);//, GFP_KERNEL);
if(newBuf->RBData == NULL)
{
free(newBuf);
return 0;
}
newBuf->capacity = numElements;
newBuf->elemSize = elementSize;
newBuf->getindex = 0;
newBuf->putindex = 0;
newBuf->elemCount = 0;
return newBuf;
}
//puts an element in the buffer. Returns -1 if full, 0 on success
//send data through void* data argument
int putring(struct RB_Buffer *rbptr, void* data)
{
int i = 0;
if ( rbptr->elemCount >= rbptr->capacity )
return -1;
memcpy(&rbptr->RBData[rbptr->putindex * rbptr->elemSize], data, rbptr->elemSize);
rbptr->putindex++;
if (rbptr->putindex >= rbptr->capacity )
rbptr->putindex = 0;
rbptr->elemCount++;
return 0;
}
//removes an element in the buffer. Returns -1 if empty, 0 on success
//data is returned through the data pointer
int getring(struct RB_Buffer *rbptr, void *data)
{
if ( !rbptr->elemCount )
return -1;
rbptr->elemCount--;
memcpy(data, &rbptr->RBData[rbptr->getindex * rbptr->elemSize], rbptr->elemSize);
rbptr->getindex++;
if ( rbptr->getindex >= rbptr->capacity )
rbptr->getindex = 0;
return 0;
}
当我将它编译成内核模块时,我收到警告:
kringbuf_generic.c:53: warning: dereferencing ‘void *’ pointer
kringbuf_generic.c:72: warning: dereferencing ‘void *’ pointer
错误发生在putring中(在memcpy中)
if ( rbptr->elemCount >= rbptr->capacity )
return -1;
memcpy(&rbptr->RBData[rbptr->putindex * rbptr->elemSize], data, rbptr->elemSize);
rbptr->putindex++;
在 getring 中,在 memcpy() 函数中
rbptr->elemCount--;
memcpy(data, &rbptr->RBData[rbptr->getindex * rbptr->elemSize], rbptr->elemSize);
rbptr->getindex++;
显然,由于这是一个内核模块,所以不知道谁会使用它,并且固定缓冲区元素大小将限制此缓冲区的使用。
有没有办法摆脱警告?还是在开发此类代码时我应该做一些不同的基本事情?