Reorganized Linux nonvolatile memory devices

pull/239/merge
Silvano Seva 2024-04-03 21:16:08 +02:00
rodzic 5b9cc789b9
commit 6aee71ec84
3 zmienionych plików z 68 dodań i 86 usunięć

Wyświetl plik

@ -29,7 +29,7 @@
#define NVM_MAX_PATHLEN 256
POSIX_FILE_DEVICE_DEFINE(stateDevice, NULL, 1024)
POSIX_FILE_DEVICE_DEFINE(stateDevice, 1024)
const struct nvmPartition statePartitions[] =
{
@ -43,15 +43,12 @@ const struct nvmPartition statePartitions[] =
}
};
const struct nvmArea areas[] =
{
const struct nvmDescriptor stateNvm =
{
.name = "Device state NVM area",
.dev = &stateDevice,
.startAddr = 0x0000,
.size = 1024,
.dev = (const struct nvmDevice *) &stateDevice,
.partNum = sizeof(statePartitions) / sizeof(struct nvmPartition),
.partitions = statePartitions
}
};
@ -153,11 +150,12 @@ void nvm_terminate()
posixFile_terminate(&stateDevice);
}
size_t nvm_getMemoryAreas(const struct nvmArea **list)
const struct nvmDescriptor *nvm_getDesc(const size_t index)
{
*list = &areas[0];
if(index > 0)
return NULL;
return (sizeof(areas) / sizeof(struct nvmArea));
return &stateNvm;
}
void nvm_readHwInfo(hwInfo_t *info)
@ -168,7 +166,7 @@ void nvm_readHwInfo(hwInfo_t *info)
int nvm_readVfoChannelData(channel_t *channel)
{
int ret = nvmArea_readPartition(&areas[0], 0, 0, channel, sizeof(channel_t));
int ret = nvm_read(0, 0, 0, channel, sizeof(channel_t));
if(ret < 0)
return ret;
@ -185,7 +183,7 @@ int nvm_readVfoChannelData(channel_t *channel)
int nvm_readSettings(settings_t *settings)
{
int ret = nvmArea_readPartition(&areas[0], 1, 0, settings, sizeof(settings_t));
int ret = nvm_read(0, 1, 0, settings, sizeof(settings_t));
if(ret < 0)
return ret;
@ -202,14 +200,14 @@ int nvm_readSettings(settings_t *settings)
int nvm_writeSettings(const settings_t *settings)
{
return nvmArea_writePartition(&areas[0], 1, 0, settings, sizeof(settings_t));
return nvm_write(0, 1, 0, settings, sizeof(settings_t));
}
int nvm_writeSettingsAndVfo(const settings_t *settings, const channel_t *vfo)
{
int ret = nvmArea_writePartition(&areas[0], 1, 0, settings, sizeof(settings_t));
int ret = nvm_write(0, 1, 0, settings, sizeof(settings_t));
if(ret < 0)
return ret;
return nvmArea_writePartition(&areas[0], 0, 0, vfo, sizeof(channel_t));
return nvm_write(0, 0, 0, vfo, sizeof(channel_t));
}

Wyświetl plik

@ -24,55 +24,43 @@
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include "posix_file.h"
static const struct nvmParams posix_file_params =
int posixFile_init(struct nvmFileDevice *dev, const char *fileName)
{
.write_size = 1,
.erase_size = 1,
.erase_cycles = INT_MAX,
.type = NVM_FILE
};
int posixFile_init(const struct nvmDevice *dev, const char *fileName)
{
const struct posixFileCfg *cfg = (const struct posixFileCfg *)(dev->config);
const char *name = cfg->fileName;
// Override filename from config, if a new one is provided.
if(fileName != NULL)
name = fileName;
// struct nvmFileDevice *pDev = (struct nvmFileDevice *)(dev);
// Test if file exists, if it doesn't create it.
int flags = O_RDWR;
int ret = access(name, F_OK);
int ret = access(fileName, F_OK);
if(ret != 0)
flags |= O_CREAT | O_EXCL;
// Open file
int fd = open(name, flags, S_IRUSR | S_IWUSR);
int fd = open(fileName, flags, S_IRUSR | S_IWUSR);
if(fd < 0)
return fd;
// Truncate to size, pad with zeroes if extending.
ftruncate(fd, cfg->fileSize);
ftruncate(fd, dev->size);
*(int *)(dev->priv) = fd;
dev->fd = fd;
return 0;
}
int posixFile_terminate(const struct nvmDevice *dev)
int posixFile_terminate(struct nvmFileDevice *dev)
{
int fd = *(int *)(dev->priv);
if(fd < 0)
// struct nvmFileDevice *pDev = (struct nvmFileDevice *)(dev);
if(dev->fd < 0)
return -EBADF;
fsync(fd);
close(fd);
fsync(dev->fd);
close(dev->fd);
*(int *)(dev->priv) = -1;
dev->fd = -1;
return 0;
}
@ -81,47 +69,45 @@ int posixFile_terminate(const struct nvmDevice *dev)
static int nvm_api_read(const struct nvmDevice *dev, uint32_t offset,
void *data, size_t len)
{
const struct posixFileCfg *cfg = (const struct posixFileCfg *)(dev->config);
const int fd = *(int *)(dev->priv);
struct nvmFileDevice *pDev = (struct nvmFileDevice *)(dev);
if(fd < 0)
if(pDev->fd < 0)
return -EBADF;
if((offset + len) >= cfg->fileSize)
if((offset + len) >= pDev->size)
return -EINVAL;
lseek(fd, offset, SEEK_SET);
return read(fd, data, len);
lseek(pDev->fd, offset, SEEK_SET);
return read(pDev->fd, data, len);
}
static int nvm_api_write(const struct nvmDevice *dev, uint32_t offset,
const void *data, size_t len)
{
const struct posixFileCfg *cfg = (const struct posixFileCfg *)(dev->config);
const int fd = *(int *)(dev->priv);
struct nvmFileDevice *pDev = (struct nvmFileDevice *)(dev);
if(fd < 0)
if(pDev->fd < 0)
return -EBADF;
if((offset + len) >= cfg->fileSize)
if((offset + len) > pDev->size)
return -EINVAL;
lseek(fd, offset, SEEK_SET);
return write(fd, data, len);
lseek(pDev->fd, offset, SEEK_SET);
return write(pDev->fd, data, len);
}
static const struct nvmParams *nvm_api_params(const struct nvmDevice *dev)
{
(void) dev;
return &posix_file_params;
}
const struct nvmApi posix_file_api =
const struct nvmOps posix_file_ops =
{
.read = nvm_api_read,
.write = nvm_api_write,
.erase = NULL,
.sync = NULL,
.params = nvm_api_params
};
const struct nvmInfo posix_file_info =
{
.write_size = 1,
.erase_size = 1,
.erase_cycles = INT_MAX,
.device_info = NVM_FILE | NVM_WRITE | NVM_BITWRITE
};

Wyświetl plik

@ -32,37 +32,35 @@
/**
* Driver configuration data structure.
*/
struct posixFileCfg
struct nvmFileDevice
{
const char *fileName; ///< Full path of the file used for data storage
const size_t fileSize; ///< File size, in bytes
const void *priv; ///< Device driver private data
const struct nvmOps *ops; ///< Device operations
const struct nvmInfo *info; ///< Device info
const size_t size; ///< Device size
int fd; ///< File descriptor
};
/**
* Driver API functions.
* Driver API functions and info.
*/
extern const struct nvmApi posix_file_api;
extern const struct nvmOps posix_file_ops;
extern const struct nvmInfo posix_file_info;
/**
* Instantiate a POSIX file storage NVM device.
*
* @param name: device name.
* @param path: full path of the file used for data storage.
* @param size: size of the storage file, in bytes.
* @param dim: size of the storage file, in bytes.
*/
#define POSIX_FILE_DEVICE_DEFINE(name, path, size) \
static int fd_##name; \
static const struct posixFileCfg cfg_##name = \
#define POSIX_FILE_DEVICE_DEFINE(name, dim) \
static struct nvmFileDevice name = \
{ \
.fileName = path, \
.fileSize = size \
}; \
static const struct nvmDevice name = \
{ \
.config = &cfg_##name, \
.priv = &fd_##name, \
.api = &posix_file_api \
.ops = &posix_file_ops, \
.info = &posix_file_info, \
.size = dim, \
.fd = -1 \
};
/**
@ -71,10 +69,10 @@ static const struct nvmDevice name = \
* storage, where necessary.
*
* @param dev: pointer to device descriptor.
* @param fileName: alternative path of the file used for data storage or NULL.
* @param fileName: full path of the file used for data storage.
* @return zero on success, a negative error code otherwise.
*/
int posixFile_init(const struct nvmDevice *dev, const char *fileName);
int posixFile_init(struct nvmFileDevice *dev, const char *fileName);
/**
* Shut down a POSIX file driver instance.
@ -83,6 +81,6 @@ int posixFile_init(const struct nvmDevice *dev, const char *fileName);
* @param maxSize: maximum size for the storage file, in bytes.
* @return zero on success, a negative error code otherwise.
*/
int posixFile_terminate(const struct nvmDevice *dev);
int posixFile_terminate(struct nvmFileDevice *dev);
#endif /* POSIX_FILE_H */