STM32上使用的环形FIFO队列,用于缓存待发送数据_stm32 循环fifo(1)

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 功能: 实时数据发送缓冲区
  • 作者: cp1300@139.com
  • 创建时间: 2015-08-09
  • 最后修改时间: 2017-08-26
  • 详细: 用于数据发送缓冲区
    2017-08-26:增加溢出回调函数,可以对溢出的数据进行处理,用于FIFO嵌套
    *************************************************************************************************************/
    #include “system.h”
    #include “usart.h”
    #include “led.h”
    #include “main.h”
    #include “SendDataFIFO.h”
    #include “SYSMalloc.h”

#define FIFO_INIT_STATUS_ID 0x354789d //用于标示是否初始化

//初始化缓冲区
bool FIFO_Init(FIFO_HANDLE *pHandle,u16 OneSize, u16 MaxCnt, void (*FullCallBack)(void *pData), bool isExtSRAM)
{

if(pHandle == NULL) return FALSE;
if(isExtSRAM == TRUE)	//是否使用外部缓冲区
{
	pHandle->pFifoBuff = (u8 *)mymalloc(SRAMEX, OneSize*MaxCnt);			//缓冲区指针,申请内存
	pHandle->pByteCntBuff = (u16 *)mymalloc(SRAMEX, sizeof(u16)*MaxCnt);	//数据大小记录缓冲区,申请内存
}
else
{
	pHandle->pFifoBuff = (u8 *)mymalloc(SRAMIN, OneSize*MaxCnt);			//缓冲区指针,申请内存
	pHandle->pByteCntBuff = (u16 *)mymalloc(SRAMIN, sizeof(u16)*MaxCnt);	//数据大小记录缓冲区,申请内存
}

//uart_printf("pHandle->pFifoBuff=0x%X\r\n", (u32)pHandle->pFifoBuff);
//uart_printf("pHandle->pByteCntBuff=0x%X\r\n", (u32)pHandle->pByteCntBuff);
if(pHandle->pFifoBuff==NULL)
{
	DEBUG("pHandle->pFifoBuff申请内存出错\r\n");
}
if(pHandle->pByteCntBuff==NULL)
{
	DEBUG("pHandle->pByteCntBuff申请内存出错\r\n");
}
pHandle->InitStatus = 0;		//初始化成功状态无效
if((pHandle->pFifoBuff==NULL)||(pHandle->pByteCntBuff==NULL)) return FALSE;
pHandle->OneSize = OneSize;		//单条数据大小
pHandle->Cnt = MaxCnt;			//缓冲区总数据容量(条数)
pHandle->ReadCnt = 0;			//读取位置
pHandle->WriteCnt = 0;			//写位置
pHandle->NotReadCnt = 0;		//未读取数量
pHandle->FullCallBack = FullCallBack;			//溢出回调函数
pHandle->InitStatus = FIFO_INIT_STATUS_ID;		//初始化成功状态有效


return TRUE;

}

//写入一条数据
//当缓冲区满了后,缓存最新的数据,丢掉最早的数据
bool FIFO_Write(FIFO_HANDLE *pHandle,u8 *pBuff, u16 ByteCnt)
{
u16 cnt;
#ifdef UCOS_II
OS_CPU_SR cpu_sr;
#endif

if(pHandle == NULL) return FALSE;
if(pHandle->InitStatus != FIFO_INIT_STATUS_ID) return FALSE;						//没有初始化
if (pHandle->NotReadCnt >= pHandle->Cnt)											//发送溢出										
{
	cnt = pHandle->WriteCnt;														//先将写指针后移,占位,防止多线程写冲突
	
	if(pHandle->FullCallBack!=NULL) pHandle->FullCallBack(&pHandle->pFifoBuff[cnt * pHandle->OneSize]);
	if (ByteCnt > pHandle->OneSize) ByteCnt = pHandle->OneSize;						//限制单条数据大小
	
	pHandle->WriteCnt++;
	if (pHandle->WriteCnt >= pHandle->Cnt) pHandle->WriteCnt = 0;					//环形FIFO
	pHandle->ReadCnt++;																//读取数量增加
	if (pHandle->ReadCnt >= pHandle->Cnt) pHandle->ReadCnt = 0;						//环形FIFO,把读写指针都增加,但是剩余数据数量不变
	pHandle->pByteCntBuff[cnt] = ByteCnt;											//记录数据大小
	memcpy(&pHandle->pFifoBuff[cnt * pHandle->OneSize], pBuff, ByteCnt);			//拷贝数据到缓冲区
	
	return FALSE;																	//数据已经满了
}
else
{
	if (ByteCnt > pHandle->OneSize) ByteCnt = pHandle->OneSize;						//限制单条数据大小
	//先将写指针后移,占位,防止多线程写冲突
	cnt = pHandle->WriteCnt;
	pHandle->WriteCnt++;
	if (pHandle->WriteCnt >= pHandle->Cnt) pHandle->WriteCnt = 0;					//环形FIFO
	pHandle->pByteCntBuff[cnt] = ByteCnt;											//记录数据大小
	
	memcpy(&pHandle->pFifoBuff[cnt * pHandle->OneSize], pBuff, ByteCnt);			//拷贝数据到缓冲区
	/*{
		u16 i;
		printf("\r\n写入的数据测试[读%d/写:%d]:\r\n",pHandle->ReadCnt,pHandle->WriteCnt);
		for(i = 0;i < ByteCnt;i ++)
		{
			pHandle->pFifoBuff[cnt * pHandle->OneSize+i] = pBuff[i];
			printf("%02X\t",pBuff[i]);
			if(pHandle->pFifoBuff[cnt * pHandle->OneSize+i] != pBuff[i])
			{
				printf("拷贝检测错误,数据丢失了\r\n");
			}
		}
		printf("\r\n检测写入的数据测试:\r\n");
		for(i = 0;i < ByteCnt;i ++)
		{
			printf("%02X\t",pHandle->pFifoBuff[cnt * pHandle->OneSize+i]);
		}
		printf("\r\n");
	}*/

#ifdef UCOS_II
OS_ENTER_CRITICAL(); //关闭系统中断
#endif

	pHandle->NotReadCnt ++;															//没有读取的数量增加

#ifdef UCOS_II
OS_EXIT_CRITICAL(); //开启系统中断
#endif

	return TRUE;
}

}

//读取一条数据,返回指针,无需复制数据
bool FIFO_ReadNotCopy(FIFO_HANDLE *pHandle,u8 **pBuff, u16 *pByteCnt)
{
u16 cnt;

printf("\r\n读取数据[读%d/写:%d]:\r\n",pHandle->ReadCnt,pHandle->WriteCnt);
if(pHandle == NULL) return FALSE;
if(pHandle->InitStatus != FIFO_INIT_STATUS_ID) return FALSE;					//没有初始化
if (pHandle->NotReadCnt == 0)  return FALSE;									//数据为空
cnt = pHandle->pByteCntBuff[pHandle->ReadCnt];									//获取数据大小
if (cnt > pHandle->OneSize) cnt = pHandle->OneSize;								//限制单条数据大小
*pBuff = &pHandle->pFifoBuff[pHandle->ReadCnt * pHandle->OneSize];				//数据缓冲区指针
*pByteCnt = cnt;


return TRUE;

}

//未读取数据减少一次,用于读取数据返回指针后调用
u16 FIFO_ReduceOne(FIFO_HANDLE *pHandle)
{
#ifdef UCOS_II
OS_CPU_SR cpu_sr;
#endif

if(pHandle == NULL) return FALSE;
if(pHandle->InitStatus != FIFO_INIT_STATUS_ID) return FALSE;					//没有初始化
if (pHandle->NotReadCnt == 0) return FALSE;
pHandle->ReadCnt++;																//读取数量增加
if (pHandle->ReadCnt >= pHandle->Cnt) pHandle->ReadCnt = 0;						//环形FIFO

#ifdef UCOS_II
OS_ENTER_CRITICAL(); //关闭系统中断
#endif

pHandle->NotReadCnt--;															//没有读取的数量减少

#ifdef UCOS_II
OS_EXIT_CRITICAL(); //开启系统中断
#endif

return pHandle->NotReadCnt;														//返回没有读取的数据数量

}

//清除FIFO
bool FIFO_Clear(FIFO_HANDLE *pHandle)
{
if(pHandle == NULL) return FALSE;
if(pHandle->InitStatus != FIFO_INIT_STATUS_ID) return FALSE; //没有初始化

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值