упрощенно, в первом приближении написал так. как минимум проверю живая ли память.
Код
uint32_t LOGGER_SaveData(uint32_t data)
{
uint32_t low_byte, high_byte;
low_byte = data & 0xFF;
high_byte = data >> 8;
SPIEEPROM_WriteByte(current_address, low_byte);
SPIEEPROM_WriteByte(current_address+1, high_byte);
current_address += 2;
if(current_address>=EEPROM_SIZE)
current_address = 0;
return current_address;
}
uint32_t LOGGER_GetData(uint32_t address)
{
uint32_t low_byte, high_byte;
low_byte = SPIEEPROM_ReadByte(address);
high_byte = SPIEEPROM_ReadByte(address+1);
return (high_byte << 8) | low_byte;
}
Цитата(CrimsonPig @ Feb 4 2015, 20:20)

"...иногда лучше молчать, чем говорить" (с)
Топикстартер явно упомянул многопоточность, а тут конструкции, типа "data[obuf_start++ & OBUF_MASK]".
Треды, атомарность, синхронизация.. слышали про такое ?
Можно сделать закат солнца вручную, т.е. написать свою очередь. Это не сложно. Сложно сделать так, чтобы оно работало правильно.
В самом тупом случае берутся примитивы синхронизации, типа мютексов, пишется тупая кольцевая очередь, где PutData() / GetData() обвешаны этими мютексами как новогодние елки.
Тупо, примитивно, не сильно оптимально по быстродействию и требует наличия ОС.
Если ОС нет или нужно выжать производительность, пишется неблокирующая очередь (а потом еще полгода отлаживается). Тут уже в ход идут такие вещи, как intrinsic функции для атомарного инкремента/декремента, реализация CAS, спинлоки и memory barriers если хотим, шоб оно еще не глючило на многоядерных системах..
.. Это один из любимых вопросов на собеседованиях в конторах типа АРМа..
В промежуточном случае пишутся свои мютексы. Но тут опять же надо очень хорошо разбираться в том, что делаешь.
Можно положиться на факт, что присваивание 32-битных значений атомарное, но для многоядерных систем все сильно сложнее с чтением и записью в одну переменную с разных ядер.
не горячитесь. вот есть приличный буфер. вопрос как увязать все вместе.
Код
typedef struct struct_cBuffer
{
unsigned char *dataptr; ///< the physical memory address where the buffer is stored
unsigned short size; ///< the allocated size of the buffer
unsigned short datalength; ///< the length of the data currently in the buffer
unsigned short dataindex; ///< the index into the buffer where the data starts
} cBuffer;
void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size)
{
// begin critical section
CRITICAL_SECTION_START;
// set start pointer of the buffer
buffer->dataptr = start;
buffer->size = size;
// initialize index and length
buffer->dataindex = 0;
buffer->datalength = 0;
// end critical section
CRITICAL_SECTION_END;
}
// access routines
unsigned char bufferGetFromFront(cBuffer* buffer)
{
unsigned char data = 0;
// begin critical section
CRITICAL_SECTION_START;
// check to see if there's data in the buffer
if(buffer->datalength)
{
// get the first character from buffer
data = buffer->dataptr[buffer->dataindex];
// move index down and decrement length
buffer->dataindex++;
if(buffer->dataindex >= buffer->size)
{
buffer->dataindex -= buffer->size;
}
buffer->datalength--;
}
// end critical section
CRITICAL_SECTION_END;
// return
return data;
}
void bufferDumpFromFront(cBuffer* buffer, unsigned short numbytes)
{
// begin critical section
CRITICAL_SECTION_START;
// dump numbytes from the front of the buffer
// are we dumping less than the entire buffer?
if(numbytes < buffer->datalength)
{
// move index down by numbytes and decrement length by numbytes
buffer->dataindex += numbytes;
if(buffer->dataindex >= buffer->size)
{
buffer->dataindex -= buffer->size;
}
buffer->datalength -= numbytes;
}
else
{
// flush the whole buffer
buffer->datalength = 0;
}
// end critical section
CRITICAL_SECTION_END;
}
unsigned char bufferGetAtIndex(cBuffer* buffer, unsigned short index)
{
// begin critical section
CRITICAL_SECTION_START;
// return character at index in buffer
unsigned char data = buffer->dataptr[(buffer->dataindex+index)%(buffer->size)];
// end critical section
CRITICAL_SECTION_END;
return data;
}
unsigned char bufferAddToEnd(cBuffer* buffer, unsigned char data)
{
// begin critical section
CRITICAL_SECTION_START;
// make sure the buffer has room
if(buffer->datalength < buffer->size)
{
// save data byte at end of buffer
buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = data;
// increment the length
buffer->datalength++;
// end critical section
CRITICAL_SECTION_END;
// return success
return -1;
}
// end critical section
CRITICAL_SECTION_END;
// return failure
return 0;
}
unsigned short bufferIsNotFull(cBuffer* buffer)
{
// begin critical section
CRITICAL_SECTION_START;
// check to see if the buffer has room
// return true if there is room
unsigned short bytesleft = (buffer->size - buffer->datalength);
// end critical section
CRITICAL_SECTION_END;
return bytesleft;
}
void bufferFlush(cBuffer* buffer)
{
// begin critical section
CRITICAL_SECTION_START;
// flush contents of the buffer
buffer->datalength = 0;
// end critical section
CRITICAL_SECTION_END;
}