Skip to content

Commit 82720d8

Browse files
author
Joakim Nohlgård
committed
drivers/nvram: Add vfs compatible functions
1 parent 486b8d8 commit 82720d8

4 files changed

Lines changed: 148 additions & 0 deletions

File tree

drivers/Makefile.dep

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ ifneq (,$(filter mpu9150,$(USEMODULE)))
9292
endif
9393

9494
ifneq (,$(filter nvram_spi,$(USEMODULE)))
95+
USEMODULE += nvram
9596
USEMODULE += xtimer
9697
endif
9798

drivers/include/nvram.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
#include <stdint.h>
3131
#include <stddef.h>
3232

33+
#if MODULE_VFS
34+
#include "vfs.h"
35+
#endif
36+
3337
#ifdef __cplusplus
3438
extern "C" {
3539
#endif
@@ -79,6 +83,10 @@ typedef struct nvram {
7983
void *extra;
8084
} nvram_t;
8185

86+
#if MODULE_VFS
87+
extern const vfs_file_ops_t nvram_vfs_ops;
88+
#endif
89+
8290
#ifdef __cplusplus
8391
}
8492
#endif

drivers/nvram/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
MODULE = nvram
2+
3+
include $(RIOTBASE)/Makefile.base

drivers/nvram/nvram-vfs.c

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* Copyright (C) 2016 Eistec AB
3+
*
4+
* This file is subject to the terms and conditions of the GNU Lesser General
5+
* Public License v2.1. See the file LICENSE in the top level directory for more
6+
* details.
7+
*/
8+
9+
#if MODULE_VFS
10+
11+
#include <fcntl.h>
12+
#include <errno.h>
13+
#include <unistd.h>
14+
15+
#include "nvram.h"
16+
#include "vfs.h"
17+
18+
/**
19+
* @ingroup nvram
20+
* @{
21+
*
22+
* @file
23+
*
24+
* @brief NVRAM generic VFS operations
25+
*
26+
* This allows the nvram driver to register as a node on DevFS
27+
*
28+
* See boards/mulle or tests/unittests/tests-devfs for examples on how to use.
29+
*
30+
* Tested with nvram_spi on Mulle
31+
*
32+
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
33+
*/
34+
35+
static int nvram_vfs_fstat(vfs_file_t *filp, struct stat *buf);
36+
static off_t nvram_vfs_lseek(vfs_file_t *filp, off_t off, int whence);
37+
static ssize_t nvram_vfs_read(vfs_file_t *filp, void *dest, size_t nbytes);
38+
static ssize_t nvram_vfs_write(vfs_file_t *filp, const void *src, size_t nbytes);
39+
40+
const vfs_file_ops_t nvram_vfs_ops = {
41+
.fstat = nvram_vfs_fstat,
42+
.lseek = nvram_vfs_lseek,
43+
.read = nvram_vfs_read,
44+
.write = nvram_vfs_write,
45+
};
46+
47+
static int nvram_vfs_fstat(vfs_file_t *filp, struct stat *buf)
48+
{
49+
if (buf == NULL) {
50+
return -EFAULT;
51+
}
52+
nvram_t *dev = filp->private_data;
53+
if (dev == NULL) {
54+
return -EFAULT;
55+
}
56+
buf->st_nlink = 1;
57+
buf->st_size = dev->size;
58+
return 0;
59+
}
60+
61+
static off_t nvram_vfs_lseek(vfs_file_t *filp, off_t off, int whence)
62+
{
63+
nvram_t *dev = filp->private_data;
64+
if (dev == NULL) {
65+
return -EFAULT;
66+
}
67+
switch (whence) {
68+
case SEEK_SET:
69+
break;
70+
case SEEK_CUR:
71+
off += filp->pos;
72+
break;
73+
case SEEK_END:
74+
off += dev->size;
75+
break;
76+
default:
77+
return -EINVAL;
78+
}
79+
if (off < 0) {
80+
/* the resulting file offset would be negative */
81+
return -EINVAL;
82+
}
83+
/* POSIX allows seeking past the end of the file */
84+
filp->pos = off;
85+
return off;
86+
}
87+
88+
static ssize_t nvram_vfs_read(vfs_file_t *filp, void *dest, size_t nbytes)
89+
{
90+
nvram_t *dev = filp->private_data;
91+
if (dev == NULL) {
92+
return -EFAULT;
93+
}
94+
uint32_t src = filp->pos;
95+
if (src >= dev->size) {
96+
return 0;
97+
}
98+
if (src + nbytes > dev->size) {
99+
nbytes = dev->size - src;
100+
}
101+
int res = dev->read(dev, dest, src, nbytes);
102+
if (res < 0) {
103+
return res;
104+
}
105+
/* Advance file position */
106+
filp->pos += res;
107+
return res;
108+
}
109+
110+
static ssize_t nvram_vfs_write(vfs_file_t *filp, const void *src, size_t nbytes)
111+
{
112+
nvram_t *dev = filp->private_data;
113+
if (dev == NULL) {
114+
return -EFAULT;
115+
}
116+
uint32_t dest = filp->pos;
117+
if (dest >= dev->size) {
118+
return 0;
119+
}
120+
if (dest + nbytes > dev->size) {
121+
nbytes = dev->size - dest;
122+
}
123+
int res = dev->write(dev, src, dest, nbytes);
124+
if (res < 0) {
125+
return res;
126+
}
127+
/* Advance file position */
128+
filp->pos += res;
129+
return res;
130+
}
131+
132+
/** @} */
133+
134+
#else
135+
typedef int dont_be_pedantic;
136+
#endif /* MODULE_VFS */

0 commit comments

Comments
 (0)