ADD file via upload
This commit is contained in:
parent
426eaca6ce
commit
a6505f3731
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue