cpu/native: Add file-backed simulated EEPROM to native cpu.
This patch removes a defunct EEPROM implementation from the native platform and provides a new EEPROM implementation for the native cpu. The previous implementation appears to be vestigal. This is useful for testing code which uses the EEPROM without running the code on the actual hardware. By default the code will create a new temporary file as the EEPROM backing, reinitializing each time. If you would like to preserve the EEPROM contents or specify a specific EEPROM file to use, you can set the `CONTIKI_EEPROM` environment variable to the name of the EEPROM file you wish to use instead. If it already exists, its contents will be used. If it does not already exist, it will be created and initialized by filling it with `0xFF`---just like a real EEPROM. A new example is also included, which was used to verify the correctness of the implementation. It can easily be used to verify the EEPROM implementations of other targets.
This commit is contained in:
parent
5af6540980
commit
b8c0f2de6c
10 changed files with 298 additions and 69 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
167
cpu/native/dev/eeprom.c
Normal file
167
cpu/native/dev/eeprom.c
Normal file
|
@ -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 <darco@deepdarc.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "dev/eeprom.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
5
examples/eeprom-test/Makefile
Normal file
5
examples/eeprom-test/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
CONTIKI_PROJECT = eeprom-test
|
||||
all: $(CONTIKI_PROJECT)
|
||||
|
||||
CONTIKI = ../..
|
||||
include $(CONTIKI)/Makefile.include
|
98
examples/eeprom-test/eeprom-test.c
Normal file
98
examples/eeprom-test/eeprom-test.c
Normal file
|
@ -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 <darco@deepdarc.com>
|
||||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "dev/eeprom.h"
|
||||
|
||||
#include <stdio.h> /* 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();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -39,6 +39,10 @@
|
|||
|
||||
#define COOJA 1
|
||||
|
||||
#ifndef EEPROM_CONF_SIZE
|
||||
#define EEPROM_CONF_SIZE 1024
|
||||
#endif
|
||||
|
||||
#define w_memcpy memcpy
|
||||
|
||||
#if WITH_UIP
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#include "dev/eeprom.h"
|
||||
#include "node.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
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);
|
||||
}
|
|
@ -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 \
|
||||
|
|
Loading…
Reference in a new issue