diff --git a/APP_Framework/Applications/general_functions/circular_area/circular_area_app.c b/APP_Framework/Applications/general_functions/circular_area/circular_area_app.c new file mode 100644 index 000000000..12cf8c5fd --- /dev/null +++ b/APP_Framework/Applications/general_functions/circular_area/circular_area_app.c @@ -0,0 +1,268 @@ +/** + +@file: circular_area_app.c +@brief: 循环区域应用程序文件 +@version: 3.0 +@author: AIIT XUOS Lab +@date: 2022/11/21 */ +#include "circular_area_app.h" + +// 检查参数是否有效的宏定义 +#define CA_PARAM_CHECK(param) do { + +if ((param) == NULL) { + +printf("Invalid parameter\n"); + +return; + +} + +} while (0) + +// 检查条件是否成立的宏定义 +#define CA_CHECK(condition) do { + +if (!(condition)) { + +printf("Check failed: " #condition "\n"); + +return; + +} + +} while (0) + +/** + +@brief 判断循环区域是否已满 + +@param circular_area 循环区域描述符 + +@return int 如果循环区域已满,返回1;否则返回0 +*/ +int CircularAreaAppIsFull(CircularAreaAppType circular_area) +{ +CA_PARAM_CHECK(circular_area); + +if((circular_area->read_idx == circular_area->write_idx) && (circular_area->status)) { +printf("The circular area is full\n"); +return 1; +} else { +return 0; +} +} + +/** + +@brief 判断循环区域是否为空 + +@param circular_area 循环区域描述符 + +@return int 如果循环区域为空,返回1;否则返回0 +*/ +int CircularAreaAppIsEmpty(CircularAreaAppType circular_area) +{ +CA_PARAM_CHECK(circular_area); + +if((circular_area->read_idx == circular_area->write_idx) && (!circular_area->status)) { +printf("The circular area is empty\n"); +return 1; +} else { +return 0; +} +} + +/** + +@brief 重置循环区域,并将描述符设置为默认值 + +@param circular_area 循环区域描述符 +*/ +void CircularAreaAppReset(CircularAreaAppType circular_area) +{ +CA_PARAM_CHECK(circular_area); + +circular_area->write_idx = 0; +circular_area->read_idx = 0; +circular_area->status = 0; +} + +/** + +@brief 释放循环区域描述符并释放内存 + +@param circular_area 循环区域描述符 +*/ +void CircularAreaAppRelease(CircularAreaAppType circular_area) +{ +CA_PARAM_CHECK(circular_area); + +circular_area->read_idx = 0; +circular_area->write_idx = 0; +circular_area->p_head = NULL; +circular_area->p_tail = NULL; +circular_area->status = 0; +circular_area->length = 0; + +PrivFree(circular_area->data_buffer); +PrivFree(circular_area); +} + +/** + +@brief 获取循环区域的最大长度 + +@param circular_area 循环区域描述符 + +@return uint32_t 循环区域的最大长度 +*/ +uint32_t CircularAreaAppGetMaxLength(CircularAreaAppType circular_area) +{ +CA_PARAM_CHECK(circular_area); + +return circular_area->length; +} + +/** + +@brief 获取循环区域中数据的长度 + +@param circular_area 循环区域描述符 + +@return uint32_t 循环区域中数据的长度 +*/ +uint32_t CircularAreaAppGetDataLength(CircularAreaAppType circular_area) +{ +CA_PARAM_CHECK(circular_area); + +if(CircularAreaAppIsFull(circular_area)) { +return circular_area->length; +} else { +return (circular_area->write_idx - circular_area->read_idx + circular_area->length) % circular_area->length; +} +} + +/** + +@brief 判断读取的数据是否需要划分为两部分 + +@param circular_area 循环区域描述符 + +@param data_length 输出数据长度 + +@return uint32_t 如果需要划分,返回1;否则返回0 +*/ +static uint32_t CircularAreaAppDivideRdData(CircularAreaAppType circular_area, uint32_t data_length) +{ +CA_PARAM_CHECK(circular_area); + +if(circular_area->read_idx + data_length <= circular_area->length) { +return 0; +} else { +return 1; +} +} + +/** + +@brief 判断写入的数据是否需要划分为两部分 + +@param circular_area 循环区域描述符 + +@param data_length 输入数据长度 + +@return uint32_t 如果需要划分,返回1;否则返回0 +*/ +static uint32_t CircularAreaAppDivideWrData(CircularAreaAppType circular_area, uint32_t data_length) +{ +CA_PARAM_CHECK(circular_area); + +if(circular_area->write_idx + data_length <= circular_area->length) { +return 0; +} else { +return 1; +} +} + +/** + +@brief 从循环区域中读取数据 + +@param circular_area 循环区域描述符 + +@param output_buffer 输出数据缓冲区指针 + +@param data_length 输出数据长度 + +@return int 成功读取的数据长度,如果循环区域为空,返回-1 +*/ +int CircularAreaAppRead(CircularAreaAppType circular_area, uint8_t *output_buffer, uint32_t data_length) +{ +CA_PARAM_CHECK(circular_area); +CA_PARAM_CHECK(output_buffer); +CA_CHECK(data_length > 0); + +if(CircularAreaAppIsEmpty(circular_area)) { +return -1; +} + +int read_length = (data_length > CircularAreaAppGetDataLength(circular_area)) ? CircularAreaAppGetDataLength(circular_area) : data_length; + +if(CircularAreaAppDivideRdData(circular_area, read_length)) { +uint32_t read_len_up = circular_area->length - circular_area->read_idx; +uint32_t read_len_down = read_length - read_len_up; + + memcpy(output_buffer, &circular_area->data_buffer[circular_area->read_idx], read_len_up); + memcpy(output_buffer + read_len_up, circular_area->p_head, read_len_down); + + circular_area->read_idx = read_len_down; +} else { +memcpy(output_buffer, &circular_area->data_buffer[circular_area->read_idx], read_length); +circular_area->read_idx = (circular_area->read_idx + read_length) % circular_area->length; +} + +circular_area->status = 0; + +return read_length; +} + +/** + +@brief 向循环区域中写入数据 + +@param circular_area 循环区域描述符 + +@param input_buffer 输入数据缓冲区指针 + +@param data_length 输入数据长度 + +@param b_force 是否强制写入数据,不考虑长度限制 + +@return int 如果循环区域已满且不强制写入,返回-1;否则返回0 +*/ +int CircularAreaAppWrite(CircularAreaAppType circular_area, uint8_t *input_buffer, uint32_t data_length, int b_force) +{ +CA_PARAM_CHECK(circular_area); +CA_PARAM_CHECK(input_buffer); +CA_CHECK(data_length > 0); + +if(CircularAreaAppIsFull(circular_area) && (!b_force)) { +return -1; +} + +uint32_t write_data_length = circular_area->length - circular_area->write_idx; + +if(write_data_length >= data_length) { +memcpy(&circular_area->data_buffer[circular_area->write_idx], input_buffer, data_length); +circular_area->write_idx = (circular_area->write_idx + data_length) % circular_area->length; +} else { +memcpy(&circular_area->data_buffer[circular_area->write_idx], input_buffer, write_data_length); +memcpy(circular_area->p_head, input_buffer + write_data_length, data_length - write_data_length); +circular_area->write_idx = data_length - write_data_length; +} + +circular_area->status = 1; + +return 0; +} \ No newline at end of file