⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eeprom.c

📁 Intrisyc 公司的PXA255-bootloader,源码易懂
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * 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 + -