#include "fifo.h" //------------------------------------------------------------------------------------------------------------------- // 函数简介 FIFO 头指针位移 // 参数说明 *fifo FIFO 对象指针 // 参数说明 offset 偏移量 // 返回参数 void // 使用示例 fifo_head_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- static void fifo_head_offset (fifo_struct *fifo, uint32 offset) { fifo->head += offset; while(fifo->max <= fifo->head) // 如果范围超过则减缓冲区大小 直到小于最大缓冲区大小 { fifo->head -= fifo->max; } } //------------------------------------------------------------------------------------------------------------------- // 函数简介 FIFO 尾指针位移 // 参数说明 *fifo FIFO 对象指针 // 参数说明 offset 偏移量 // 返回参数 void // 使用示例 fifo_end_offset(fifo, 1); // 备注信息 本函数在文件内部调用 用户不用关注 也不可修改 //------------------------------------------------------------------------------------------------------------------- static void fifo_end_offset (fifo_struct *fifo, uint32 offset) { fifo->end += offset; while(fifo->max <= fifo->end) // 如果范围超过则减缓冲区大小 直到小于最大缓冲区大小 { fifo->end -= fifo->max; } } //------------------------------------------------------------------------------------------------------------------- // 函数简介 FIFO 重置缓冲器 // 参数说明 *fifo FIFO 对象指针 // 返回参数 void // 使用示例 fifo_clear(fifo); // 备注信息 清空当前 FIFO 对象的内存 //------------------------------------------------------------------------------------------------------------------- fifo_state_enum fifo_clear (fifo_struct *fifo) { //zf_assert(NULL != fifo); fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { // if(FIFO_IDLE != fifo->execution) // 判断是否当前 FIFO 是否空闲 // { // return_state = FIFO_RESET_UNDO; // 重置操作未完成 // break; // } fifo->execution |= FIFO_RESET; // 重置操作置位 fifo->head = 0; // 重置 FIFO 所有数值复位 fifo->end = 0; // 重置 FIFO 所有数值复位 fifo->reamin_size = fifo->max; // 重置 FIFO 所有数值复位 switch(fifo->type) { case FIFO_DATA_8BIT: memset(fifo->buffer, 0, (uint16)fifo->max); break; case FIFO_DATA_16BIT: memset(fifo->buffer, 0, (uint16)fifo->max * 2); break; case FIFO_DATA_32BIT: memset(fifo->buffer, 0, (uint16)fifo->max * 4); break; } fifo->execution = FIFO_IDLE; // 操作状态复位 }while(0); return return_state; } //------------------------------------------------------------------------------------------------------------------- // 函数简介 FIFO 查询当前数据个数 // 参数说明 *fifo FIFO 对象指针 // 返回参数 uint32 已使用长度 // 使用示例 uint32 len = fifo_used(fifo); // 备注信息 //------------------------------------------------------------------------------------------------------------------- uint32 fifo_used (fifo_struct *fifo) { //zf_assert(fifo != NULL); return (fifo->max - fifo->reamin_size); // 返回当前 FIFO 缓冲区中数据个数 } //------------------------------------------------------------------------------------------------------------------- // 函数简介 向 FIFO 中写入数据 // 参数说明 *fifo FIFO 对象指针 // 参数说明 dat 数据 // 返回参数 fifo_state_enum 操作状态 // 使用示例 zf_log(fifo_write_element(&fifo, data) == FIFO_SUCCESS, "fifo_write_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- fifo_state_enum fifo_write_element (fifo_struct *fifo, uint32 dat) { //zf_assert(NULL != fifo); fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } fifo->execution |= FIFO_WRITE; // 写入操作置位 if(1 <= fifo->reamin_size) // 剩余空间足够装下本次数据 { switch(fifo->type) { case FIFO_DATA_8BIT: ((uint8 *)fifo->buffer)[fifo->head] = dat; break; case FIFO_DATA_16BIT: ((uint16 *)fifo->buffer)[fifo->head] = dat; break; case FIFO_DATA_32BIT: ((uint32 *)fifo->buffer)[fifo->head] = dat; break; } fifo_head_offset(fifo, 1); // 头指针偏移 fifo->reamin_size -= 1; // 缓冲区剩余长度减小 } else { return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; } //------------------------------------------------------------------------------------------------------------------- // 函数简介 向 FIFO 中写入数据 // 参数说明 *fifo FIFO 对象指针 // 参数说明 *dat 数据来源缓冲区指针 // 参数说明 length 需要写入的数据长度 // 返回参数 fifo_state_enum 操作状态 // 使用示例 zf_log(fifo_write_buffer(&fifo, data, 32) == FIFO_SUCCESS, "fifo_write_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- fifo_state_enum fifo_write_buffer (fifo_struct *fifo, void *dat, uint32 length) { //zf_assert(NULL != fifo); fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 break; } if((FIFO_RESET | FIFO_WRITE) & fifo->execution) // 不在写入与重置状态 避免写入竞争与指向错误 { return_state = FIFO_WRITE_UNDO; // 写入操作未完成 break; } fifo->execution |= FIFO_WRITE; // 写入操作置位 if(length <= fifo->reamin_size) // 剩余空间足够装下本次数据 { temp_length = fifo->max - fifo->head; // 计算头指针距离缓冲区尾还有多少空间 if(length > temp_length) // 距离缓冲区尾长度不足写入数据 环形缓冲区分段操作 { switch(fifo->type) { case FIFO_DATA_8BIT: { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, (uint16)temp_length); // 拷贝第一段数据 fifo_head_offset(fifo, temp_length); // 头指针偏移 memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), &(((uint8 *)dat)[temp_length]), (uint16)(length - temp_length)); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 }break; case FIFO_DATA_16BIT: { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, temp_length * 2); // 拷贝第一段数据 fifo_head_offset(fifo, temp_length); // 头指针偏移 memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), &(((uint16 *)dat)[temp_length]), (length - temp_length) * 2); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 }break; case FIFO_DATA_32BIT: { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, temp_length * 4); // 拷贝第一段数据 fifo_head_offset(fifo, temp_length); // 头指针偏移 memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), &(((uint32 *)dat)[temp_length]), (length - temp_length) * 4); // 拷贝第二段数据 fifo_head_offset(fifo, length - temp_length); // 头指针偏移 }break; } } else { switch(fifo->type) { case FIFO_DATA_8BIT: { memcpy( &(((uint8 *)fifo->buffer)[fifo->head]), dat, (uint16)length); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 }break; case FIFO_DATA_16BIT: { memcpy( &(((uint16 *)fifo->buffer)[fifo->head]), dat, length * 2); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 }break; case FIFO_DATA_32BIT: { memcpy( &(((uint32 *)fifo->buffer)[fifo->head]), dat, length * 4); // 一次完整写入 fifo_head_offset(fifo, length); // 头指针偏移 }break; } } fifo->reamin_size -= length; // 缓冲区剩余长度减小 } else { return_state = FIFO_SPACE_NO_ENOUGH; // 当前 FIFO 缓冲区满 不能再写入数据 返回空间不足 } fifo->execution &= ~FIFO_WRITE; // 写入操作复位 }while(0); return return_state; } //------------------------------------------------------------------------------------------------------------------- // 函数简介 从 FIFO 读取数据 // 参数说明 *fifo FIFO 对象指针 // 参数说明 *dat 目标缓冲区指针 // 参数说明 flag 是否变更 FIFO 状态 可选择是否清空读取的数据 // 返回参数 fifo_state_enum 操作状态 // 使用示例 zf_log(fifo_read_element(&fifo, data, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_byte error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- fifo_state_enum fifo_read_element (fifo_struct *fifo, void *dat, fifo_operation_enum flag) { //zf_assert(NULL != fifo); fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; // 用户缓冲区异常 } else { if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } if(1 > fifo_used(fifo)) { return_state = FIFO_DATA_NO_ENOUGH; // 缓冲区没有数据 返回数据长度不足 break; // 直接退出操作 } fifo->execution |= FIFO_READ; // 读操作置位 switch(fifo->type) { case FIFO_DATA_8BIT: *((uint8 *)dat) = ((uint8 *)fifo->buffer)[fifo->end]; break; case FIFO_DATA_16BIT: *((uint16 *)dat) = ((uint16 *)fifo->buffer)[fifo->end]; break; case FIFO_DATA_32BIT: *((uint32 *)dat) = ((uint32 *)fifo->buffer)[fifo->end]; break; } fifo->execution &= ~FIFO_READ; // 读操作复位 } if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 { if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 { return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 break; } fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, 1); // 移动 FIFO 头指针 fifo->reamin_size += 1; // 释放对应长度空间 fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); return return_state; } //------------------------------------------------------------------------------------------------------------------- // 函数简介 从 FIFO 读取数据 // 参数说明 *fifo FIFO 对象指针 // 参数说明 *dat 目标缓冲区指针 // 参数说明 *length 读取的数据长度 如果没有这么多数据这里会被修改 // 参数说明 flag 是否变更 FIFO 状态 可选择是否清空读取的数据 // 返回参数 fifo_state_enum 操作状态 // 使用示例 zf_log(fifo_read_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 //------------------------------------------------------------------------------------------------------------------- fifo_state_enum fifo_read_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { //zf_assert(NULL != fifo); //zf_assert(NULL != length); fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; } else { if((FIFO_RESET | FIFO_CLEAR) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { *length = fifo_data_length; // 纠正读取的长度 return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 if(*length > fifo_data_length) // 判断长度是否足够 { *length = fifo_data_length; // 纠正读取的长度 return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 if(0 == fifo_data_length) // 如果没有数据 就直接退出 { fifo->execution &= ~FIFO_READ; // 读操作复位 break; } } fifo->execution |= FIFO_READ; // 读操作置位 temp_length = fifo->max - fifo->end; // 计算尾指针距离缓冲区尾还有多少空间 if(*length <= temp_length) // 足够一次性读取完毕 { switch(fifo->type) { case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), (uint16)*length); break; case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), (uint16)*length * 2); break; case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), (uint16)*length * 4); break; } } else { switch(fifo->type) { case FIFO_DATA_8BIT: { memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->end]), (uint16)temp_length); memcpy(&(((uint8 *)dat)[temp_length]), fifo->buffer, (uint16)(*length - temp_length)); }break; case FIFO_DATA_16BIT: { memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->end]), (uint16)(temp_length * 2)); memcpy(&(((uint16 *)dat)[temp_length]), fifo->buffer, (uint16)((*length - temp_length) * 2)); }break; case FIFO_DATA_32BIT: { memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->end]), (uint16)(temp_length * 4)); memcpy(&(((uint32 *)dat)[temp_length]), fifo->buffer, (uint16)((*length - temp_length) * 4)); }break; } } fifo->execution &= ~FIFO_READ; // 读操作复位 } if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 { if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 { return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 break; } fifo->execution |= FIFO_CLEAR; // 清空作置位 fifo_end_offset(fifo, *length); // 移动 FIFO 头指针 fifo->reamin_size += *length; // 释放对应长度空间 fifo->execution &= ~FIFO_CLEAR; // 清空作复位 } }while(0); return return_state; } //------------------------------------------------------------------------------------------------------------------- // 函数简介 从 FIFO 尾部读取指定长度 buffer // 参数说明 *fifo FIFO 对象指针 // 参数说明 *dat 目标缓冲区指针 // 参数说明 *length 读取的数据长度 如果没有这么多数据这里会被修改 // 参数说明 flag 是否变更 FIFO 状态 可选择是否清空读取的数据 // 返回参数 fifo_state_enum 操作状态 // 使用示例 zf_log(fifo_read_tail_buffer(&fifo, data, &length, FIFO_READ_ONLY) == FIFO_SUCCESS, "fifo_read_buffer error"); // 备注信息 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO // 如果使用 FIFO_READ_AND_CLEAN 操作 将会丢弃所有数据并清空整个 FIFO //------------------------------------------------------------------------------------------------------------------- fifo_state_enum fifo_read_tail_buffer (fifo_struct *fifo, void *dat, uint32 *length, fifo_operation_enum flag) { //zf_assert(NULL != fifo); //zf_assert(NULL != length); fifo_state_enum return_state = FIFO_SUCCESS; // 操作结果初值 uint32 temp_length = 0; uint32 fifo_data_length = 0; do { if(NULL == dat) { return_state = FIFO_BUFFER_NULL; } else { if((FIFO_RESET | FIFO_CLEAR | FIFO_WRITE) & fifo->execution) // 判断是否当前 FIFO 是否在执行清空或重置操作 { *length = fifo_data_length; // 纠正读取的长度 return_state = FIFO_READ_UNDO; // 读取操作未完成 break; } fifo_data_length = fifo_used(fifo); // 获取当前数据有多少 if(*length > fifo_data_length) // 判断长度是否足够 { *length = fifo_data_length; // 纠正读取的长度 return_state = FIFO_DATA_NO_ENOUGH; // 标志数据不够 if(0 == fifo_data_length) // 如果没有数据 就直接退出 { fifo->execution &= ~FIFO_READ; // 读操作复位 break; } } fifo->execution |= FIFO_READ; // 读操作置位 if((fifo->head > fifo->end) || (fifo->head >= *length)) { switch(fifo->type) { case FIFO_DATA_8BIT: memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->head - *length]), (uint16)*length); break; case FIFO_DATA_16BIT: memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->head - *length]), (uint16)(*length * 2));break; case FIFO_DATA_32BIT: memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->head - *length]), (uint16)(*length * 4));break; } } else { temp_length = *length - fifo->head; // 计算尾指针距离缓冲区尾还有多少空间 switch(fifo->type) { case FIFO_DATA_8BIT: { memcpy(dat, &(((uint8 *)fifo->buffer)[fifo->max - temp_length]), (uint16)temp_length); memcpy(&(((uint8 *)dat)[temp_length]), &(((uint8 *)fifo->buffer)[fifo->head - *length]), (uint16)(*length - temp_length)); }break; case FIFO_DATA_16BIT: { memcpy(dat, &(((uint16 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 2); memcpy(&(((uint16 *)dat)[temp_length]), &(((uint16 *)fifo->buffer)[fifo->head - *length]), (uint16)((*length - temp_length) * 2)); }break; case FIFO_DATA_32BIT: { memcpy(dat, &(((uint32 *)fifo->buffer)[fifo->max - temp_length]), temp_length * 4); memcpy(&(((uint32 *)dat)[temp_length]), &(((uint32 *)fifo->buffer)[fifo->head - *length]), (uint16)((*length - temp_length) * 4)); }break; } } fifo->execution &= ~FIFO_READ; // 读操作复位 } if(FIFO_READ_AND_CLEAN == flag) // 如果选择读取并更改 FIFO 状态 { if((FIFO_RESET | FIFO_CLEAR | FIFO_READ) == fifo->execution) // 不在 重置 清空 读取 状态 避免异常 { return_state = FIFO_CLEAR_UNDO; // 清空操作未完成 break; } fifo_clear(fifo); } }while(0); return return_state; } //------------------------------------------------------------------------------------------------------------------- // 函数简介 FIFO 初始化 挂载对应缓冲区 // 参数说明 *fifo FIFO 对象指针 // 参数说明 type FIFO 数据位数 // 参数说明 *buffer_addr 要挂载的缓冲区 // 参数说明 size 缓冲区大小 // 返回参数 fifo_state_enum 操作状态 // 使用示例 fifo_init(&user_fifo, user_buffer, 64); // 备注信息 //------------------------------------------------------------------------------------------------------------------- fifo_state_enum fifo_init (fifo_struct *fifo, fifo_data_type_enum type, void *buffer_addr, uint32 len) { //zf_assert(NULL != fifo); fifo_state_enum return_state = FIFO_SUCCESS; do { fifo->buffer = buffer_addr; fifo->execution = FIFO_IDLE; fifo->type = type; fifo->head = 0; fifo->end = 0; fifo->reamin_size = len; fifo->max = len; }while(0); return return_state; }