Contiki-NG
eeprom.c
1 /*
2  * Copyright (c) 2013, Robert Quattlebaum.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  * Author: Robert Quattlebaum <darco@deepdarc.com>
32  *
33  */
34 
35 #include "contiki.h"
36 #include "dev/eeprom.h"
37 
38 #include <stdio.h>
39 #include <stdlib.h>
40 
41 static FILE *eeprom_file;
42 
43 /*---------------------------------------------------------------------------*/
44 static void
45 eeprom_fill(eeprom_addr_t addr, unsigned char value, int size)
46 {
47  if((addr > EEPROM_END_ADDR) || (addr+size > EEPROM_END_ADDR+1) || size < 0) {
48  fprintf(stderr, "eeprom_fill: Bad address and/or size (addr = %04x, size = %d)\n", addr, size);
49 
50  /* Abort here so that we break into the debugger. If a debugger isn't
51  * attached, well we might as well crash anyway.
52  */
53  abort();
54  }
55 
56  if(!eeprom_file) {
57  eeprom_init();
58  }
59 
60  fseek(eeprom_file, addr, SEEK_SET);
61 
62  while(size--) {
63  if(fputc(value, eeprom_file) != value) {
64  perror("fputc() failed");
65  exit(EXIT_FAILURE);
66  }
67  }
68 }
69 
70 /*---------------------------------------------------------------------------*/
71 void
73 {
74  long length;
75  char *eeprom_filename = getenv("CONTIKI_EEPROM");
76 
77  if(eeprom_filename) {
78  eeprom_file = fopen(eeprom_filename, "r+");
79 
80  if(!eeprom_file) {
81  /* File does exist yet, so let's create it. */
82  eeprom_file = fopen(eeprom_filename, "w+");
83 
84  if(!eeprom_file) {
85  perror("Unable to create EEPROM file");
86  exit(EXIT_FAILURE);
87  }
88  }
89 
90  fprintf(stderr, "eeprom_init: Using \"%s\".\n", eeprom_filename);
91  } else {
92  eeprom_file = tmpfile();
93 
94  if(!eeprom_file) {
95  perror("Unable to create temporary EEPROM file");
96  exit(EXIT_FAILURE);
97  }
98  }
99 
100  /* Make sure that the file is the correct size by seeking
101  * to the end and checking the file position. If it is
102  * less than what we expect, we pad out the rest of the file
103  * with 0xFF, just like a real EEPROM. */
104 
105  fseek(eeprom_file, 0, SEEK_END);
106  length = ftell(eeprom_file);
107 
108  if(length < 0) {
109  perror("ftell failed");
110  exit(EXIT_FAILURE);
111  }
112 
113  if(length < EEPROM_END_ADDR) {
114  /* Fill with 0xFF, just like a real EEPROM. */
115  eeprom_fill(length, 0xFF, EEPROM_SIZE - length);
116  }
117 }
118 
119 /*---------------------------------------------------------------------------*/
120 void
121 eeprom_write(eeprom_addr_t addr, unsigned char *buf, int size)
122 {
123  if((addr > EEPROM_END_ADDR) || (addr+size > EEPROM_END_ADDR+1) || size < 0) {
124  fprintf(stderr, "eeprom_write: Bad address and/or size (addr = %04x, size = %d)\n", addr, size);
125 
126  /* Abort here so that we break into the debugger. If a debugger isn't
127  * attached, well we might as well crash anyway.
128  */
129  abort();
130  }
131 
132  if(!eeprom_file) {
133  eeprom_init();
134  }
135 
136  fseek(eeprom_file, addr, SEEK_SET);
137 
138  if(fwrite(buf, 1, size, eeprom_file) != size) {
139  perror("fwrite() failed");
140  exit(EXIT_FAILURE);
141  }
142 }
143 
144 /*---------------------------------------------------------------------------*/
145 void
146 eeprom_read(eeprom_addr_t addr, unsigned char *buf, int size)
147 {
148  if((addr > EEPROM_END_ADDR) || (addr+size > EEPROM_END_ADDR+1) || size < 0) {
149  fprintf(stderr, "eeprom_read: Bad address and/or size (addr = %04x, size = %d)\n", addr, size);
150 
151  /* Abort here so that we break into the debugger. If a debugger isn't
152  * attached, well we might as well crash anyway. */
153  abort();
154  }
155 
156  if(!eeprom_file) {
157  eeprom_init();
158  }
159 
160  fseek(eeprom_file, addr, SEEK_SET);
161 
162  if(fread(buf, 1, size, eeprom_file) != size) {
163  perror("fread() failed");
164  exit(EXIT_FAILURE);
165  }
166 }
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition: uip-nd6.c:107
EEPROM functions.
void eeprom_init(void)
Initialize the EEPROM module.
Definition: eeprom.c:72
void eeprom_read(eeprom_addr_t addr, unsigned char *buf, int size)
Read data from the EEPROM.
Definition: eeprom.c:146
void eeprom_write(eeprom_addr_t addr, unsigned char *buf, int size)
Write a buffer into EEPROM.
Definition: eeprom.c:121