源:http://blog.csdn.net/zyboy2000/article/details/4587037
(u32)(((DataQueue *)0)->Buf)的值为队列中从out指针到函数指针 (* WriteFull)() 总的字节数24字节, 真实队列数据应该是后24字节的数据,由于DataQueue 结构体28字节(由于结构体对齐可知),所以建立的队列数组长度至少要大于等于28字节。-KEIL+ARM
typedef struct { QUEUE_DATA_TYPE *Out; /* 指向数据输出位置 */ QUEUE_DATA_TYPE *In; /* 指向数据输入位置 */ QUEUE_DATA_TYPE *End; /* 指向Buf的结束位置 */ u16 NData; /* 队列中数据个数 */ u16 MaxData; /* 队列中允许存储的数据个数 */ u8 (* ReadEmpty)(); /* 读空处理函数 */ u8 (* WriteFull)(); /* 写满处理函数 */ QUEUE_DATA_TYPE Buf[1]; /* 存储数据的空间 */ } DataQueue; /********************************************************************************************************* ** 函数名称: QueueCreate ** 功能描述: 初始化数据队列 ** 输 入: Buf :为队列分配的存储空间地址 ** SizeOfBuf:为队列分配的存储空间大小(字节) ** ReadEmpty:为队列读空时处理程序 ** WriteFull:为队列写满时处理程序 ** 输 出: NOT_OK:参数错误 ** QUEUE_OK:成功 ** 全局变量: 无 ** 调用模块: OS_ENTER_CRITICAL,OS_EXIT_CRITICAL ** ** 作 者: 陈明计 ** 日 期: 2003年7月2日 **------------------------------------------------------------------------------------------------------- ** 修改人: ** 日 期: **------------------------------------------------------------------------------------------------------ ********************************************************************************************************/ u8 QueueCreate(void *Buf, u32 SizeOfBuf, u8 (* ReadEmpty)(), u8 (* WriteFull)() ) { DataQueue *Queue; if (Buf != NULL && SizeOfBuf >= (sizeof(DataQueue))) /* 判断参数是否有效 */ { Queue = (DataQueue *)Buf; /* 初始化结构体数据 */ Queue->MaxData = (SizeOfBuf - (u32)(((DataQueue *)0)->Buf)) / sizeof(QUEUE_DATA_TYPE); /* 计算队列可以存储的数据数目 */ Queue->End = Queue->Buf + Queue->MaxData; /* 计算数据缓冲的结束地址 */ Queue->Out = Queue->Buf; Queue->In = Queue->Buf; Queue->NData = 0; Queue->ReadEmpty = ReadEmpty; Queue->WriteFull = WriteFull; return QUEUE_OK; } else { return NOT_OK; } } /********************************************************************************************************* ** 函数名称: QueueRead ** 功能描述: 获取队列中的数据 ** 输 入: Ret:存储返回的消息的地址 ** Buf:指向队列的指针 ** 输 出: NOT_OK :参数错误 ** QUEUE_OK :收到消息 ** QUEUE_EMPTY:无消息 ** 全局变量: 无 ** 调用模块: OS_ENTER_CRITICAL,OS_EXIT_CRITICAL ** ** 作 者: 陈明计 ** 日 期: 2003年7月2日 **------------------------------------------------------------------------------------------------------- ** 修改人: ** 日 期: **------------------------------------------------------------------------------------------------------ ********************************************************************************************************/ u8 QueueRead(QUEUE_DATA_TYPE *Ret, void *Buf) { u8 err; DataQueue *Queue; err = NOT_OK; if (Buf != NULL) /* 队列是否有效 */ { /* 有效 */ Queue = (DataQueue *)Buf; if (Queue->NData > 0) /* 队列是否为空 */ { /* 不空 */ *Ret = Queue->Out[0]; /* 数据出队 */ Queue->Out++; /* 调整出队指针 */ if (Queue->Out >= Queue->End) { Queue->Out = Queue->Buf; } Queue->NData--; /* 数据减少 */ err = QUEUE_OK; } else { /* 空 */ err = QUEUE_EMPTY; if (Queue->ReadEmpty != NULL) /* 调用用户处理函数 */ { err = Queue->ReadEmpty(Ret, Queue); } } } return err; } /********************************************************************************************************* ** 函数名称: QueueWrite ** 功能描述: FIFO方式发送数据 ** 输 入: Buf :指向队列的指针 ** Data:消息数据 ** 输 出: NOT_OK :参数错误 ** QUEUE_FULL:队列满 ** QUEUE_OK :发送成功 ** 全局变量: 无 ** 调用模块: OS_ENTER_CRITICAL,OS_EXIT_CRITICAL ** ** 作 者: 陈明计 ** 日 期: 2003年7月2日 **------------------------------------------------------------------------------------------------------- ** 修改人: ** 日 期: **------------------------------------------------------------------------------------------------------ ********************************************************************************************************/ #ifndef EN_QUEUE_WRITE #define EN_QUEUE_WRITE 1 #endif #if EN_QUEUE_WRITE > 0 u8 QueueWrite(void *Buf, QUEUE_DATA_TYPE Data) { u8 err; DataQueue *Queue; err = NOT_OK; if (Buf != NULL) /* 队列是否有效 */ { Queue = (DataQueue *)Buf; if (Queue->NData < Queue->MaxData) /* 队列是否满 */ { /* 不满 */ Queue->In[0] = Data; /* 数据入队 */ Queue->In++; /* 调整入队指针*/ if (Queue->In >= Queue->End) { Queue->In = Queue->Buf; } Queue->NData++; /* 数据增加 */ err = QUEUE_OK; } else { /* 满 */ err = QUEUE_FULL; if (Queue->WriteFull != NULL) /* 调用用户处理函数 */ { err = Queue->WriteFull(Queue, Data, Q_WRITE_MODE); } } } return err; } #endif