diff --git a/core/dev/eeprom.h b/core/dev/eeprom.h index a09baaa9e..4a1ff0c8b 100644 --- a/core/dev/eeprom.h +++ b/core/dev/eeprom.h @@ -55,7 +55,20 @@ #define __EEPROM_H__ typedef unsigned short eeprom_addr_t; -#define EEPROM_NULL 0 + +#define EEPROM_NULL 0 + +#ifdef EEPROM_CONF_SIZE +#define EEPROM_SIZE (EEPROM_CONF_SIZE) +#else +#define EEPROM_SIZE 0 /* Default to no EEPROM */ +#endif + +#ifdef EEPROM_CONF_END_ADDR +#define EEPROM_END_ADDR (EEPROM_CONF_END_ADDR) +#else +#define EEPROM_END_ADDR (EEPROM_SIZE - 1) +#endif /** * Write a buffer into EEPROM. diff --git a/cpu/native/Makefile.native b/cpu/native/Makefile.native index eaf716424..bf4e8ea47 100644 --- a/cpu/native/Makefile.native +++ b/cpu/native/Makefile.native @@ -1,6 +1,6 @@ -CONTIKI_CPU_DIRS = . net +CONTIKI_CPU_DIRS = . net dev -CONTIKI_SOURCEFILES += mtarch.c rtimer-arch.c elfloader-stub.c watchdog.c +CONTIKI_SOURCEFILES += mtarch.c rtimer-arch.c elfloader-stub.c watchdog.c eeprom.c ### Compiler definitions CC ?= gcc diff --git a/cpu/native/dev/eeprom.c b/cpu/native/dev/eeprom.c new file mode 100644 index 000000000..48e28e144 --- /dev/null +++ b/cpu/native/dev/eeprom.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2013, Robert Quattlebaum. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Robert Quattlebaum + * + */ + +#include "contiki.h" +#include "dev/eeprom.h" + +#include +#include +#include + +static FILE *eeprom_file; + +/*---------------------------------------------------------------------------*/ +static void +eeprom_fill(eeprom_addr_t addr, unsigned char value, int size) +{ + if((addr > EEPROM_END_ADDR) || (addr+size > EEPROM_END_ADDR+1) || size < 0) { + fprintf(stderr, "eeprom_fill: Bad address and/or size (addr = %04x, size = %d)\n", addr, size); + + /* Abort here so that we break into the debugger. If a debugger isn't + * attached, well we might as well crash anyway. + */ + abort(); + } + + if(!eeprom_file) { + eeprom_init(); + } + + fseek(eeprom_file, addr, SEEK_SET); + + while(size--) { + if(fputc(value, eeprom_file) != value) { + perror("fputc() failed"); + exit(EXIT_FAILURE); + } + } +} + +/*---------------------------------------------------------------------------*/ +void +eeprom_init(void) +{ + long length; + char *eeprom_filename = getenv("CONTIKI_EEPROM"); + + if(eeprom_filename) { + eeprom_file = fopen(eeprom_filename, "r+"); + + if(!eeprom_file) { + /* File does exist yet, so let's create it. */ + eeprom_file = fopen(eeprom_filename, "w+"); + + if(!eeprom_file) { + perror("Unable to create EEPROM file"); + exit(EXIT_FAILURE); + } + } + + fprintf(stderr, "eeprom_init: Using \"%s\".\n", eeprom_filename); + } else { + eeprom_file = tmpfile(); + + if(!eeprom_file) { + perror("Unable to create temporary EEPROM file"); + exit(EXIT_FAILURE); + } + } + + /* Make sure that the file is the correct size by seeking + * to the end and checking the file position. If it is + * less than what we expect, we pad out the rest of the file + * with 0xFF, just like a real EEPROM. */ + + fseek(eeprom_file, 0, SEEK_END); + length = ftell(eeprom_file); + + if(length < 0) { + perror("ftell failed"); + exit(EXIT_FAILURE); + } + + if(length < EEPROM_END_ADDR) { + /* Fill with 0xFF, just like a real EEPROM. */ + eeprom_fill(length, 0xFF, EEPROM_SIZE - length); + } +} + +/*---------------------------------------------------------------------------*/ +void +eeprom_write(eeprom_addr_t addr, unsigned char *buf, int size) +{ + if((addr > EEPROM_END_ADDR) || (addr+size > EEPROM_END_ADDR+1) || size < 0) { + fprintf(stderr, "eeprom_write: Bad address and/or size (addr = %04x, size = %d)\n", addr, size); + + /* Abort here so that we break into the debugger. If a debugger isn't + * attached, well we might as well crash anyway. + */ + abort(); + } + + if(!eeprom_file) { + eeprom_init(); + } + + fseek(eeprom_file, addr, SEEK_SET); + + if(fwrite(buf, 1, size, eeprom_file) != size) { + perror("fwrite() failed"); + exit(EXIT_FAILURE); + } +} + +/*---------------------------------------------------------------------------*/ +void +eeprom_read(eeprom_addr_t addr, unsigned char *buf, int size) +{ + if((addr > EEPROM_END_ADDR) || (addr+size > EEPROM_END_ADDR+1) || size < 0) { + fprintf(stderr, "eeprom_read: Bad address and/or size (addr = %04x, size = %d)\n", addr, size); + + /* Abort here so that we break into the debugger. If a debugger isn't + * attached, well we might as well crash anyway. */ + abort(); + } + + if(!eeprom_file) { + eeprom_init(); + } + + fseek(eeprom_file, addr, SEEK_SET); + + if(fread(buf, 1, size, eeprom_file) != size) { + perror("fread() failed"); + exit(EXIT_FAILURE); + } +} diff --git a/examples/eeprom-test/Makefile b/examples/eeprom-test/Makefile new file mode 100644 index 000000000..0d78a7341 --- /dev/null +++ b/examples/eeprom-test/Makefile @@ -0,0 +1,5 @@ +CONTIKI_PROJECT = eeprom-test +all: $(CONTIKI_PROJECT) + +CONTIKI = ../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/eeprom-test/eeprom-test.c b/examples/eeprom-test/eeprom-test.c new file mode 100644 index 000000000..c20e5d009 --- /dev/null +++ b/examples/eeprom-test/eeprom-test.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013, Robert Quattlebaum + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * A very simple Contiki application showing how to read and write + * data using Contiki's EEPROM API. + * \author + * Robert Quattlebaum + */ + +#include "contiki.h" +#include "dev/eeprom.h" + +#include /* For printf() */ + +/*---------------------------------------------------------------------------*/ +PROCESS(eeprom_test_process, "EEPROM Test Process"); +AUTOSTART_PROCESSES(&eeprom_test_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(eeprom_test_process, ev, data) +{ + static uint8_t counter = 0; + + static eeprom_addr_t addr = 0; + + PROCESS_BEGIN(); + + printf("eeprom-test: Size = %d bytes\n", EEPROM_SIZE); + + /* Check to see if the EEPROM is empty */ + for(addr = 0; addr < EEPROM_SIZE; ++addr) { + uint8_t byte; + + eeprom_read(addr, &byte, 1); + if(byte != 0xFF) { + break; + } + } + + if(addr == EEPROM_SIZE) { + printf("eeprom-test: EEPROM is empty. Proceding with write test...\n"); + + counter = 0; + for(addr = 0; addr < EEPROM_SIZE; ++addr) { + eeprom_write(addr, &counter, 1); + counter += 1; + } + + counter = 0; + for(addr = 0; addr < EEPROM_SIZE; ++addr) { + uint8_t byte; + + eeprom_read(addr, &byte, 1); + if(byte != counter) { + printf("eeprom-test: EEPROM write failure!\n"); + break; + } + counter += 1; + } + + printf("eeprom-test: EEPROM write test success!\n"); + } else { + printf("eeprom-test: EEPROM is NOT empty! Skipping write test.\n"); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/cooja/contiki-conf.h b/platform/cooja/contiki-conf.h index 4abb59a71..769a27ba7 100644 --- a/platform/cooja/contiki-conf.h +++ b/platform/cooja/contiki-conf.h @@ -39,6 +39,10 @@ #define COOJA 1 +#ifndef EEPROM_CONF_SIZE +#define EEPROM_CONF_SIZE 1024 +#endif + #define w_memcpy memcpy #if WITH_UIP diff --git a/platform/minimal-net/contiki-conf.h b/platform/minimal-net/contiki-conf.h index a4d7f65d4..9f132ead8 100644 --- a/platform/minimal-net/contiki-conf.h +++ b/platform/minimal-net/contiki-conf.h @@ -44,6 +44,10 @@ #define CCIF #define CLIF +#ifndef EEPROM_CONF_SIZE +#define EEPROM_CONF_SIZE 1024 +#endif + /* These names are deprecated, use C99 names. */ typedef uint8_t u8_t; typedef uint16_t u16_t; diff --git a/platform/native/contiki-conf.h b/platform/native/contiki-conf.h index 28f9e7796..952c90658 100644 --- a/platform/native/contiki-conf.h +++ b/platform/native/contiki-conf.h @@ -50,6 +50,9 @@ int select_set_callback(int fd, const struct select_callback *callback); #define CC_CONF_VA_ARGS 1 /*#define CC_CONF_INLINE inline*/ +#ifndef EEPROM_CONF_SIZE +#define EEPROM_CONF_SIZE 1024 +#endif #define CCIF #define CLIF diff --git a/platform/native/dev/eeprom.c b/platform/native/dev/eeprom.c deleted file mode 100644 index e803b56fe..000000000 --- a/platform/native/dev/eeprom.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels - * - */ -#include "dev/eeprom.h" -#include "node.h" -#include - -#include -#include -#include -#include - -static unsigned char eeprom[65536]; - -void -eeprom_write(eeprom_addr_t addr, unsigned char *buf, int size) -{ - int f; - char name[400]; - - snprintf(name, sizeof(name), "eeprom.%d.%d", node_x(), node_y()); - f = open(name, O_WRONLY | O_APPEND | O_CREAT, 0644); - lseek(f, addr, SEEK_SET); - write(f, buf, size); - close(f); - - printf("eeprom_write(addr 0x%02x, buf %p, size %d);\n", addr, buf, size); - - memcpy(&eeprom[addr], buf, size); -} -void -eeprom_read(eeprom_addr_t addr, unsigned char *buf, int size) -{ - /* printf("eeprom_read(addr 0x%02x, buf %p, size %d);\n", addr, buf, size);*/ - memcpy(buf, &eeprom[addr], size); -} diff --git a/regression-tests/01-compile/Makefile b/regression-tests/01-compile/Makefile index 67047b68c..1ec0b00c7 100644 --- a/regression-tests/01-compile/Makefile +++ b/regression-tests/01-compile/Makefile @@ -15,6 +15,7 @@ hello-world/wismote \ hello-world/z1 \ hello-world/sensinode \ hello-world/cc2530dk \ +eeprom-test/native \ ipv6/rpl-border-router/econotag \ collect/sky \ er-rest-example/sky \