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

2019-07-13 07:13发布

        闲来没事自己写了一个串口缓冲区玩,利用数组实现,运行在Linux环境底下,gcc编译和自测试通过。
#include #include /* 缓冲区大小 */ #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); }