253 lines
7.6 KiB
C
253 lines
7.6 KiB
C
#include "storage.h"
|
||
|
||
/**
|
||
* @brief 根据索引查找存储节点
|
||
*
|
||
* 在给定的存储结构中,根据索引查找对应的存储节点。
|
||
*
|
||
* @param storage 存储结构指针
|
||
* @param index 要查找的索引值
|
||
*
|
||
* @return 指向找到的存储节点的指针,如果未找到则返回 NULL
|
||
*/
|
||
static storage_node_t *storage_node_find(storage_t *storage, uint16_t index)
|
||
{
|
||
storage_node_t *node = NULL;
|
||
for (clist_node_t *p = storage->head; p != NULL; p = p->Next)
|
||
{
|
||
node = (storage_node_t *)p->data;
|
||
if (node->index == index)
|
||
{
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
node = NULL;
|
||
}
|
||
}
|
||
|
||
return node;
|
||
}
|
||
/**
|
||
* @brief 初始化存储结构
|
||
*
|
||
* 根据给定的基地址和页大小,初始化存储结构。
|
||
*
|
||
* @param base_addr 存储的基地址
|
||
* @param page_size 存储的页大小
|
||
*
|
||
* @return 指向存储结构的指针
|
||
*/
|
||
storage_t *storage_init(uint32_t base_addr, uint16_t page_size)
|
||
{
|
||
storage_t *storage = (storage_t *)osel_mem_alloc(sizeof(storage_t));
|
||
DBG_ASSERT(storage != NULL __DBG_LINE);
|
||
osel_memset((uint8_t *)storage, 0, sizeof(storage_t));
|
||
clist_init(&storage->head);
|
||
|
||
storage->params.base_addr = base_addr;
|
||
storage->params.page_size = page_size;
|
||
return storage;
|
||
}
|
||
|
||
/**
|
||
* @brief 销毁存储结构
|
||
*
|
||
* 销毁给定的存储结构,并释放其占用的内存。
|
||
*
|
||
* @param storage 指向存储结构的指针
|
||
*/
|
||
void storage_destroy(storage_t *storage)
|
||
{
|
||
if (storage != NULL)
|
||
{
|
||
clist_destroy(&storage->head);
|
||
osel_mem_free(storage);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 向存储结构中添加一个新的节点
|
||
*
|
||
* 在给定的存储结构中添加一个新的节点。节点的索引和大小由参数指定。
|
||
*
|
||
* @param storage 指向存储结构的指针
|
||
* @param index 新节点的索引
|
||
* @param size 新节点的大小
|
||
*/
|
||
void storage_add_node(storage_t *storage, uint16_t index, uint16_t size)
|
||
{
|
||
DBG_ASSERT(storage != NULL __DBG_LINE);
|
||
storage_node_t *node = (storage_node_t *)osel_mem_alloc(sizeof(storage_node_t));
|
||
node->index = index;
|
||
node->size = size;
|
||
node->address = storage->params.base_addr + storage->params.variable_size;
|
||
storage->params.variable_size += size;
|
||
storage->params.variable_count++;
|
||
storage->params.page_count = storage->params.variable_size / storage->params.page_size;
|
||
if (storage->params.variable_size % storage->params.page_size != 0)
|
||
{
|
||
storage->params.page_count++;
|
||
}
|
||
clist_push_back(&storage->head, (cnode)node);
|
||
}
|
||
|
||
/**
|
||
* @brief 将缓冲区中的所有数据写入存储设备
|
||
*
|
||
* 将指定缓冲区中的数据写入存储设备。
|
||
*
|
||
* @param storage 存储设备的指针
|
||
* @param buf 待写入数据的缓冲区指针
|
||
*
|
||
* @return 如果写入成功,则返回TRUE;否则返回FALSE
|
||
*/
|
||
BOOL storage_write_all(storage_t *storage, const uint8_t *buf)
|
||
{
|
||
DBG_ASSERT(storage != NULL __DBG_LINE);
|
||
DBG_ASSERT(buf != NULL __DBG_LINE);
|
||
DBG_ASSERT(storage->ops.write != NULL __DBG_LINE);
|
||
return storage->ops.write(storage->params.base_addr, (uint8_t *)buf, storage->params.variable_size);
|
||
}
|
||
|
||
/**
|
||
* @brief 向存储设备写入数据
|
||
*
|
||
* 将指定的数据写入到存储设备中指定的索引位置。
|
||
*
|
||
* @param storage 存储设备指针
|
||
* @param index 索引位置
|
||
* @param buf 要写入的数据缓冲区指针
|
||
*
|
||
* @return 写入成功返回TRUE,失败返回FALSE
|
||
*/
|
||
BOOL storage_write(storage_t *storage, uint16_t index, const uint8_t *buf)
|
||
{
|
||
DBG_ASSERT(storage != NULL __DBG_LINE);
|
||
DBG_ASSERT(buf != NULL __DBG_LINE);
|
||
DBG_ASSERT(storage->ops.write != NULL __DBG_LINE);
|
||
storage_node_t *node = storage_node_find(storage, index);
|
||
if (node == NULL)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
return storage->ops.write(node->address, (uint8_t *)buf, node->size);
|
||
}
|
||
|
||
/**
|
||
* @brief 从存储设备中读取所有数据到缓冲区
|
||
*
|
||
* 从指定的存储设备中读取数据,并将数据存储在提供的缓冲区中。
|
||
*
|
||
* @param storage 存储设备的指针
|
||
* @param buf 用于存储读取数据的缓冲区指针
|
||
*
|
||
* @return 如果读取成功,则返回 TRUE;否则返回 FALSE
|
||
*
|
||
* @note 必须在调用此函数之前,确保提供的存储设备和缓冲区指针均不为空,且要读取的数据大小不为零。
|
||
* 此外,存储设备的读取操作函数也必须不为空。
|
||
*/
|
||
BOOL storage_read_all(storage_t *storage, uint8_t *buf)
|
||
{
|
||
DBG_ASSERT(storage != NULL __DBG_LINE);
|
||
DBG_ASSERT(buf != NULL __DBG_LINE);
|
||
DBG_ASSERT(storage->ops.read != NULL __DBG_LINE);
|
||
return storage->ops.read(storage->params.base_addr, buf, storage->params.variable_size);
|
||
}
|
||
|
||
/**
|
||
* @brief 从存储中读取数据
|
||
*
|
||
* 从指定的存储位置读取数据到缓冲区中。
|
||
*
|
||
* @param storage 存储指针,指向存储结构的指针
|
||
* @param index 要读取的数据的索引
|
||
* @param buf 指向存储读取数据的缓冲区的指针
|
||
*
|
||
* @return 如果读取成功,返回TRUE;否则返回FALSE
|
||
*/
|
||
BOOL storage_read(storage_t *storage, uint16_t index, uint8_t *buf)
|
||
{
|
||
DBG_ASSERT(storage != NULL __DBG_LINE);
|
||
DBG_ASSERT(buf != NULL __DBG_LINE);
|
||
DBG_ASSERT(storage->ops.read != NULL __DBG_LINE);
|
||
storage_node_t *node = storage_node_find(storage, index);
|
||
if (node == NULL)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
return storage->ops.read(node->address, buf, node->size);
|
||
}
|
||
|
||
/**
|
||
* @brief 检查存储中的数据是否与给定的缓冲区内容相同
|
||
*
|
||
* 检查给定索引位置的存储节点中的数据是否与给定的缓冲区内容相同。
|
||
*
|
||
* @param storage 存储对象指针
|
||
* @param index 要检查的存储节点的索引
|
||
* @param buf 要比较的缓冲区指针
|
||
*
|
||
* @return 如果存储节点中的数据与缓冲区内容相同,则返回 TRUE;否则返回 FALSE
|
||
*/
|
||
BOOL storage_check(storage_t *storage, uint16_t index, uint8_t *buf)
|
||
{
|
||
DBG_ASSERT(storage != NULL __DBG_LINE);
|
||
DBG_ASSERT(buf != NULL __DBG_LINE);
|
||
DBG_ASSERT(storage->ops.read != NULL __DBG_LINE);
|
||
BOOL ret = FALSE;
|
||
storage_node_t *node = storage_node_find(storage, index);
|
||
if (node == NULL)
|
||
{
|
||
return FALSE;
|
||
}
|
||
uint8_t *tmp = (uint8_t *)osel_mem_alloc(node->size);
|
||
DBG_ASSERT(tmp != NULL __DBG_LINE);
|
||
if (storage->ops.read(node->address, tmp, node->size) == TRUE)
|
||
{
|
||
if (osel_memcmp(tmp, buf, node->size) == 0)
|
||
{
|
||
ret = TRUE;
|
||
}
|
||
}
|
||
osel_mem_free(tmp);
|
||
return ret;
|
||
}
|
||
|
||
/**
|
||
* @brief 检查存储区内容是否与给定的缓冲区内容一致
|
||
*
|
||
* 该函数会检查存储区(由storage参数指定)的内容是否与给定的缓冲区(由buf参数指定)内容一致。
|
||
*
|
||
* @param storage 存储区指针,指向一个存储区结构体
|
||
* @param buf 缓冲区指针,指向要比较的缓冲区
|
||
*
|
||
* @return 如果存储区内容与缓冲区内容一致,则返回TRUE;否则返回FALSE
|
||
*
|
||
* @note 调用此函数前,需要确保storage和buf均不为NULL,且storage->ops.read指向有效的读操作函数。
|
||
*/
|
||
BOOL storage_check_all(storage_t *storage, uint8_t *buf)
|
||
{
|
||
DBG_ASSERT(storage != NULL __DBG_LINE);
|
||
DBG_ASSERT(buf != NULL __DBG_LINE);
|
||
DBG_ASSERT(storage->ops.read != NULL __DBG_LINE);
|
||
BOOL ret = FALSE;
|
||
uint8_t *tmp = (uint8_t *)osel_mem_alloc(storage->params.variable_size);
|
||
DBG_ASSERT(tmp != NULL __DBG_LINE);
|
||
if (storage->ops.read(storage->params.base_addr, tmp, storage->params.variable_size) == TRUE)
|
||
{
|
||
if (osel_memcmp(tmp, buf, storage->params.variable_size) == 0)
|
||
{
|
||
ret = TRUE;
|
||
}
|
||
else
|
||
{
|
||
__NOP();
|
||
}
|
||
}
|
||
osel_mem_free(tmp);
|
||
return ret;
|
||
}
|