[Linux C]自己写的串口缓冲区

        闲来没事自己写了一个串口缓冲区玩,利用数组实现,运行在Linux环境底下,gcc编译和自测试通过。


#include<stdio.h>
#include<string.h>

/* 缓冲区大小 */
#define SERIAL_BUFFER_SIZE 250

/* 错误代码:取负值是为了与正常数值区别开来 */
#define CODE_SUCCESS 			-1
#define CODE_NO_OPERATE			-2
#define CODE_INVALID_ARG 		-11
#define CODE_BUFFER_OVERFLOW	-12

#define _8_BIT_SYSTEM	1
#define _16_BIT_SYSTEM	0
#define _32_BIT_SYSTEM	0

/* 数据类型:视编译器而定,GCC编译器的定义 */
#if _8_BIT_SYSTEM
typedef unsigned char u8;
typedef char s8;
typedef unsigned int u16;
typedef int s16;
#endif

#if _16_BIT_SYSTEM
typedef unsigned char u8;
typedef char s8;
typedef unsigned int u16;
typedef int s16;
typedef unsigned long u32;
typedef long s32;
#endif

/* 串口缓冲区结构体定义 */
typedef struct SerialBuffer_Str{
	u8 WriteIndex;
	u8 ReadIndex;
	u8 Buffer[SERIAL_BUFFER_SIZE];
	u8 ZeroFlag;
}SerialBuffer_Str;


/* 功能函数声明区 */
s16 SerialBuffer_Init(SerialBuffer_Str *p_SBstr);
s16 SerialBuffer_Read(SerialBuffer_Str *p_SBstr);
s16 SerialBuffer_Write(SerialBuffer_Str *p_SBstr,u8 *p_wdata);

/* 自测试用例声明区 */
void SerialBuffer_Test(SerialBuffer_Str *p_SBstr);

/*******************************************
* 函数名:SerialBuffer_Init
* 作用:初始化缓冲区结构体
* 输入参数:缓冲区结构体地址
* 输出参数:无
* 返回值:成功则返回 -1
*******************************************/
s16 SerialBuffer_Init(SerialBuffer_Str *p_SBstr)
{
	if(p_SBstr == NULL){
		/* 检查输入参数的有效性 */
		return CODE_INVALID_ARG;
	}

	p_SBstr->WriteIndex=0;
	p_SBstr->ReadIndex=1;
	/* 初始化 读索引值>写索引值(表示缓冲区为空) */
	p_SBstr->ZeroFlag=0;

	/* 标准C库函数,移植时需注意 */
	memset(p_SBstr->Buffer,0,SERIAL_BUFFER_SIZE);
	
	return CODE_SUCCESS;
}

/*******************************************
* 函数名:SerialBuffer_Read
* 作用:读取缓冲区中的数据
* 说明:必须始终保持读索引值不大于写索引值(防止读到无效数据)
* 输入参数:缓冲区结构体地址
* 输出参数:无
* 返回值:从缓冲区中读到的数据,异常返回为负值
*******************************************/
s16 SerialBuffer_Read(SerialBuffer_Str *p_SBstr)
{
	s16 ret;

	if(p_SBstr == NULL){
		/* 检查输入参数的有效性 */
		return CODE_INVALID_ARG;	
	}

	if(p_SBstr->ZeroFlag >= 2){
		/* 当写索引值归零了两次或以上,某些未读数据会被覆盖掉 */	
		return CODE_BUFFER_OVERFLOW;
	}
	
	if((p_SBstr->ZeroFlag==1)&&(p_SBstr->WriteIndex >= p_SBstr->ReadIndex)){
		/* 当写索引值归零之后,再次超过了读索引值,某些未读数据会被覆盖掉 */
		return CODE_BUFFER_OVERFLOW;
	}
	
	if((p_SBstr->ZeroFlag==0) && (p_SBstr->ReadIndex > p_SBstr->WriteIndex)){
		/* 读索引值大于写索引值,表示缓冲区为空,不作任何处理*/
		return CODE_NO_OPERATE;
	}
	
	ret=p_SBstr->Buffer[p_SBstr->ReadIndex];
	
	if(p_SBstr->ReadIndex >= (SERIAL_BUFFER_SIZE-1)){
		p_SBstr->ReadIndex=0;
		p_SBstr->ZeroFlag--;		
	}
	else{
		p_SBstr->ReadIndex++;
	}
	
	return ret;
}


/*******************************************
* 函数名:SerialBuffer_Write
* 作用:写数据到缓冲区中
* 说明:写时不对缓冲区作任何检查,尽量简短。
*		检查放在读函数中(方便移植到中断处理函数中)
* 输入参数1:缓冲区结构体地址
* 输入参数2:数据的地址(某个寄存器地址)
* 输出参数:无
* 返回值:成功则返回 -1
*******************************************/
s16 SerialBuffer_Write(SerialBuffer_Str *p_SBstr,u8 *p_wdata)
{
	if(p_SBstr == NULL){
		/* 检查输入参数的有效性 */
		return CODE_INVALID_ARG;
	}

	if(p_SBstr->WriteIndex >= (SERIAL_BUFFER_SIZE-1)){
		p_SBstr->WriteIndex=0;
		p_SBstr->ZeroFlag++;		
	}
	else{
		p_SBstr->WriteIndex++;	
	}

	p_SBstr->Buffer[p_SBstr->WriteIndex] = *p_wdata;
	
	return CODE_SUCCESS;	
}

void main(void)
{
	SerialBuffer_Str Uart0_Buffer_Str;
	SerialBuffer_Init(&Uart0_Buffer_Str);
	SerialBuffer_Test(&Uart0_Buffer_Str);
}


已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页