Skip to content

Commit

Permalink
drivers/nvram: Add vfs compatible functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Joakim Nohlgård committed Mar 7, 2017
1 parent 26b99a5 commit e021b3b
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ ifneq (,$(filter nrfmin,$(USEMODULE)))
endif

ifneq (,$(filter nvram_spi,$(USEMODULE)))
USEMODULE += nvram
USEMODULE += xtimer
endif

Expand Down
8 changes: 8 additions & 0 deletions drivers/include/nvram.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
#include <stdint.h>
#include <stddef.h>

#if MODULE_VFS
#include "vfs.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -79,6 +83,10 @@ typedef struct nvram {
void *extra;
} nvram_t;

#if MODULE_VFS
extern const vfs_file_ops_t nvram_vfs_ops;
#endif

#ifdef __cplusplus
}
#endif
Expand Down
3 changes: 3 additions & 0 deletions drivers/nvram/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
MODULE = nvram

include $(RIOTBASE)/Makefile.base
136 changes: 136 additions & 0 deletions drivers/nvram/nvram-vfs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
* Copyright (C) 2016 Eistec AB
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/

#if MODULE_VFS

#include <fcntl.h>
#include <errno.h>
#include <unistd.h>

#include "nvram.h"
#include "vfs.h"

/**
* @ingroup nvram
* @{
*
* @file
*
* @brief NVRAM generic VFS operations
*
* This allows the nvram driver to register as a node on DevFS
*
* See boards/mulle or tests/unittests/tests-devfs for examples on how to use.
*
* Tested with nvram_spi on Mulle
*
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
*/

static int nvram_vfs_fstat(vfs_file_t *filp, struct stat *buf);
static off_t nvram_vfs_lseek(vfs_file_t *filp, off_t off, int whence);
static ssize_t nvram_vfs_read(vfs_file_t *filp, void *dest, size_t nbytes);
static ssize_t nvram_vfs_write(vfs_file_t *filp, const void *src, size_t nbytes);

const vfs_file_ops_t nvram_vfs_ops = {
.fstat = nvram_vfs_fstat,
.lseek = nvram_vfs_lseek,
.read = nvram_vfs_read,
.write = nvram_vfs_write,
};

static int nvram_vfs_fstat(vfs_file_t *filp, struct stat *buf)
{
if (buf == NULL) {
return -EFAULT;
}
nvram_t *dev = filp->private_data.ptr;
if (dev == NULL) {
return -EFAULT;
}
buf->st_nlink = 1;
buf->st_size = dev->size;
return 0;
}

static off_t nvram_vfs_lseek(vfs_file_t *filp, off_t off, int whence)
{
nvram_t *dev = filp->private_data.ptr;
if (dev == NULL) {
return -EFAULT;
}
switch (whence) {
case SEEK_SET:
break;
case SEEK_CUR:
off += filp->pos;
break;
case SEEK_END:
off += dev->size;
break;
default:
return -EINVAL;
}
if (off < 0) {
/* the resulting file offset would be negative */
return -EINVAL;
}
/* POSIX allows seeking past the end of the file */
filp->pos = off;
return off;
}

static ssize_t nvram_vfs_read(vfs_file_t *filp, void *dest, size_t nbytes)
{
nvram_t *dev = filp->private_data.ptr;
if (dev == NULL) {
return -EFAULT;
}
uint32_t src = filp->pos;
if (src >= dev->size) {
return 0;
}
if (src + nbytes > dev->size) {
nbytes = dev->size - src;
}
int res = dev->read(dev, dest, src, nbytes);
if (res < 0) {
return res;
}
/* Advance file position */
filp->pos += res;
return res;
}

static ssize_t nvram_vfs_write(vfs_file_t *filp, const void *src, size_t nbytes)
{
nvram_t *dev = filp->private_data.ptr;
if (dev == NULL) {
return -EFAULT;
}
uint32_t dest = filp->pos;
if (dest >= dev->size) {
return 0;
}
if (dest + nbytes > dev->size) {
nbytes = dev->size - dest;
}
int res = dev->write(dev, src, dest, nbytes);
if (res < 0) {
return res;
}
/* Advance file position */
filp->pos += res;
return res;
}

/** @} */

#else
typedef int dont_be_pedantic;
#endif /* MODULE_VFS */

0 comments on commit e021b3b

Please sign in to comment.