📄 eeprom.c
字号:
/***************************************************************************** * Copyright (c) 2002, Intrinsyc Software Inc. * * FILE: eeprom.c * * FUNCTION: * This is the EEPROM storage driver for the Bootloader. * ****************************************************************************///We want failures to get to the user#define _DEBUG#define _DEBUG_FAIL#include <types.h>#include <debug.h>#include <string.h>#include <eeprom_24lc64.h>#include <eeprom.h>#include <util.h>#include <crc16.h>#define EEPROM_HEADER_MAGIC_0 0xEF#define EEPROM_HEADER_MAGIC_1 0xBE#define EXTENDED_LENGTH_FLAG 0x80typedef struct{ u16 length; u8 * data;} eeField;typedef struct{ eeField tag; eeField value;} eeItem;static int write_eof(u16 offset);////////////////////////////////////////////////////////////////////////////////// init_eeprom_tagged// PURPOSE: Initialize the EEPROM into tagged format if it isn't already.// PARAMS: None.// RETURNS: 0 on error, 1 on success// NOTES: None.////////////////////////////////////////////////////////////////////////////////intinit_eeprom_tagged(void){ if (!check_eeprom_header()) { DEBUG("Warning: EEPROM not initialized!\r\n");\ return 0; } return 1;} ////////////////////////////////////////////////////////////////////////////////// clear_eeprom// PURPOSE: Write an EEPROM tagged header and EOF record to the EEPROM// PARAMS: None.// RETURNS: 0 on error, 1 on success// NOTES: None.////////////////////////////////////////////////////////////////////////////////intclear_eeprom(void){ u8 header[EEPROM_HEADER_SIZE]; u16 len; memset8(header, 0, sizeof(header)); header[0] = EEPROM_HEADER_MAGIC_0; header[1] = EEPROM_HEADER_MAGIC_1; len = EEPROM_HEADER_SIZE; if (!write_data_eeprom (0, &header[0], &len) || !write_eof(EEPROM_HEADER_SIZE)) { DEBUG_FAIL("Error initializing EEPROM\r\n"); return 0; } return 1;} ////////////////////////////////////////////////////////////////////////////////// check_eeprom_header// PURPOSE: Check the EEPROM header to verify that it is in tagged format// PARAMS: None.// RETURNS: 0 on error, 1 on success// NOTES: None.////////////////////////////////////////////////////////////////////////////////intcheck_eeprom_header(void){ u8 head[EEPROM_HEADER_SIZE]; u16 len = EEPROM_HEADER_SIZE; if (!read_data_eeprom(0, &head[0], &len)) { return 0; } if ((head[0] != EEPROM_HEADER_MAGIC_0) || (head[1] != EEPROM_HEADER_MAGIC_1)) { return 0; } return 1;}////////////////////////////////////////////////////////////////////////////////// create_item// PURPOSE: Create an eeItem by storing pointers into the structure// PARAMS: (OUT)eeField* item - Structured view of the Raw data.// (IN) void* key - Key to lookup in EEPROM.// (IN) u16 keylen - Length of the key.// (OUT)void* data - Data associated with the key.// (OUT)u16* datalen - Length of the data returned.// RETURNS: None.// NOTES: None.////////////////////////////////////////////////////////////////////////////////inline static voidcreate_item(eeItem* item, u8 const *key, u16 keylen, u8 const *data, u16 datalen){ item->tag.length = keylen; item->tag.data = (char *) key; item->value.length = datalen; item->value.data = (char *) data;}////////////////////////////////////////////////////////////////////////////////// compress_length// PURPOSE: Write a compressed length into the buffer// PARAMS: (OUT) u8 *buf - buffer to write into// (IN) int length - length value// RETURNS: Number of bytes taken up by compressed length (maximum of 2)// NOTES: None.////////////////////////////////////////////////////////////////////////////////inline static intcompress_length(u8 *buf, int length){ if (length < 128) { // Length compression buf[0] = length; return 1; } else { buf[0] = (length >> 8) | EXTENDED_LENGTH_FLAG; buf[1] = length & 0xff; return 2; }}////////////////////////////////////////////////////////////////////////////////// record_length// PURPOSE: Calculate the amount of space required to store this record// PARAMS: (OUT) eeItem *item - record// RETURNS: Number of bytes taken up by record in EEPROM// NOTES: None.////////////////////////////////////////////////////////////////////////////////inline static intrecord_length(eeItem const *item){ u8 buf[2]; int len = compress_length(buf, item->tag.length); len += item->tag.length; len += compress_length(buf, item->value.length); len += item->value.length; len += 2; // CRC return len;}////////////////////////////////////////////////////////////////////////////////// write_record// PURPOSE: Write a tagged record to the EEPROM// PARAMS: (IN) u16 offset - Start of item in EEPROM.// (OUT)eeItem *item - Tagged item// RETURNS: 0 on error, 1 on success// NOTES: item->rawlength is set by this function.////////////////////////////////////////////////////////////////////////////////static intwrite_record(u16 offset, eeItem const * item){ u16 keylen_space, datalen_space, bytes, crc; u8 buf[2]; // Write the tag record -- length bytes = keylen_space = compress_length(buf, item->tag.length); crc = getcrc16(buf, bytes, INITIAL_CRC); if (!write_data_eeprom(offset, buf, &bytes)) return 0; offset += keylen_space; // Write the tag record -- value bytes = item->tag.length; crc = getcrc16(item->tag.data, bytes, crc); if (!write_data_eeprom(offset, item->tag.data, &bytes)) return 0; offset += item->tag.length; // Write the data record -- length bytes = datalen_space = compress_length(buf, item->value.length); crc = getcrc16(buf, bytes, crc); if (!write_data_eeprom(offset, buf, &bytes)) return 0; offset += datalen_space; // Write the data record -- value bytes = item->value.length; crc = getcrc16(item->value.data, bytes, crc); if (!write_data_eeprom(offset, item->value.data, &bytes)) return 0; offset += item->value.length; // Write the CRC // Note that this is written in big-endian format for some reason buf[0] = (crc >> 8) & 0xff; buf[1] = crc & 0xff; bytes = 2; return write_data_eeprom(offset, buf, &bytes);}////////////////////////////////////////////////////////////////////////////////// write_eof// PURPOSE: Write an EOF record to the EEPROM// PARAMS: (IN) u16 offset - Start of item in EEPROM.// RETURNS: CRC value// NOTES: None.////////////////////////////////////////////////////////////////////////////////static intwrite_eof(u16 offset){ eeItem eof; eof.tag.length = 0; eof.tag.data = 0; eof.value.length = 0; eof.value.data = 0; return write_record(offset, &eof);}////////////////////////////////////////////////////////////////////////////////// read_crc// PURPOSE: Read the record CRC from the EEPROM// PARAMS: (IN) u16 offset - Start of item in EEPROM.// (OUT)u8* dest - Destination of the raw CRC bytes (2 bytes).// RETURNS: CRC value// NOTES: None.////////////////////////////////////////////////////////////////////////////////inline static u16read_crc(u16 offset, u8* dest){ u16 bytes_read = 2; if (read_data_eeprom(offset, dest, &bytes_read)) { return ((dest[0] << 8) | dest[1]); } return 0xffff;} ////////////////////////////////////////////////////////////////////////////////// read_section// PURPOSE: Read a Key or Data Item in its raw form.// PARAMS: (IN) u16 next - Start of section in EEPROM.// (OUT)u8* dest - Destination of the raw data.// (OUT)eeField* field - Structured view of the Raw data.// RETURNS:// >0 = Raw record length (Actual bytes read)// 0 = Raw record length (Actual bytes read)// -1 = READ_ERROR// -2 = INVALID_SECTION// NOTES: None.////////////////////////////////////////////////////////////////////////////////static intread_section(u16 next, u8* dest, eeField* field){ u8* tmp = dest; const u16 begin = next; u16 bytes_read = 1; // Check for read beyond end of device. if (begin >= MAX_EEPROM_SIZE) return EEPROM_ERR_READ; if (read_data_eeprom(next++, tmp, &bytes_read)) { if (*tmp & EXTENDED_LENGTH_FLAG) { field->length = ((*tmp & 0x7f) << 8); if (!read_data_eeprom(next++, tmp+1, &bytes_read)) return EEPROM_ERR_READ; field->length |= (*(tmp+1) & 0xff); } else { field->length = (*tmp); } // Check for reasonable length. if (field->length > (MAX_EEPROM_SIZE - begin)) return EEPROM_ERR_SECTION; bytes_read = field->length; field->data = NULL; if (bytes_read > 0) { if (read_data_eeprom(next, (tmp+(next-begin)), &bytes_read)) { if (bytes_read != field->length) return EEPROM_ERR_READ; field->data = tmp+(next-begin); next += bytes_read; } else return EEPROM_ERR_READ; } } else return EEPROM_ERR_READ; return (next - begin); // OK}////////////////////////////////////////////////////////////////////////////////// read_record// PURPOSE: Read a Key and Data pair in its raw form.// PARAMS: (IN) u16 offset - Start of item in EEPROM.// (OUT)u8* dest - Destination of the raw data.// (OUT)eeItem* item - Structured view of the Raw data.// RETURNS:// >0 = Raw record length (Actual bytes read)// 0 = Not Found (EOF)// -1 = READ_ERROR// -2 = INVALID_SECTION// -3 = INVALID_CRC// NOTES: None.////////////////////////////////////////////////////////////////////////////////static intread_record(u16 offset, u8* dest, eeItem* item){ int bytes; u16 crc; const u16 begin = offset; if (!check_eeprom_header()) { DEBUG_FAIL("Error reading EEPROM header\r\n"); return EEPROM_ERR_READ; } bytes = read_section(offset, dest, &item->tag); if (bytes < 0) return bytes; offset += bytes; bytes = read_section(offset, dest+bytes, &item->value); if (bytes < 0) return bytes;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -