源:
(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 > 0u8 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