Чтение из EEPROM и знание того, что оно не записано при запуске

#c #embedded

#c #встроенный

Вопрос:

Я записываю структуру в EEPRM следующим образом

 typedef struct
{
   fract32 AmpF; // amplitude fundamental
   fract32 AmpH; // amplitude harmonic 
   UINT32 b;
   UINT16 d;
   UINT16 crc;

}CoilBoardAmp_T;

// mechanic angles and salt water angles of coil stored in coil-eeprom
typedef struct
{
    ChannelData_T     channel[NUM_CHANNELS];
    CoilBoard_T       coilboard;
    CoilBoardAmp_T    coil_h;
    CoilBoardAmp_T    coil_d;
//  UINT32    gCoilSerialNumber;
//  UINT32    gInversSerialNumber;
} Coil_Eeprom_Data_T;
  

Я устанавливаю эти данные с помощью программного обеспечения, которое записывает в эту структуру.

Проблема в том, что при первом чтении этой структуры без записи в нее я считываю ложные данные.

Мне нужно определить эту точку. Как я узнаю, являются ли считываемые данные ложными, или как я узнаю, что я прочитал данные без программного обеспечения.

Ответ №1:

Вы можете добавить контрольную сумму или CRC в конце вашей структуры, которая вычисляется для всех членов структуры.

Когда вы записываете данные в EEPROM, вы вычисляете значение контрольной суммы и записываете его. Когда вы считываете данные из EEPROM, вы вычисляете контрольную сумму этих данных и сравниваете ее с контрольной суммой данных, которые вы только что прочитали, и если они совпадают, это означает (с высокой вероятностью), что ваши данные верны.

В принципе, если мы представляем вашу структуру в памяти :

 byte |0 1 2 3|4 5 6 7|8 9 10 11|12 13|14 15|
       AmpF    AmpH      b        d    CRC
  

Тогда 2-байтовый CRC может быть вычислен следующим образом :

 CRC = (AmpF<<2)   (AmpF amp; 0x00FF) 
      (AmpH<<2)   (AmpH amp; 0x00FF) 
      (h<<2)      (h amp; 0x00FF) 
      d;
  

Который, очевидно, может быть оптимизирован с for помощью цикла. Я совершенно уверен, что в сети есть примеры, но идея заключалась бы в том, чтобы перейти от адреса вашей структуры к этому адресу sizeof (struct) — sizeof (CRC) с шагом в 2 байта.

Интернет полон реализаций контрольных сумм и CRC, которые варьируются от чрезвычайно простых до очень сложных, в зависимости от того, чего вы хотите достичь, и возможностей вашей системы, но в основном простая контрольная сумма — это просто добавление всех байтов в вашу структуру данных.

Простая контрольная сумма, подобная той, которую я привел в качестве примера, обнаруживает только неправильные биты в ваших данных, вы не обнаружите, если поменяются местами два значения, например, AmpF и AmpH.

Обратите внимание, что, хотя контрольные суммы и CRC — это разные вещи, оба термина часто используются для обозначения другого.

Комментарии:

1. что, если контрольная сумма равна ошибке, это означает, что пользователь должен написать структуру с помощью программного обеспечения?

2. Если вычисляемая вами контрольная сумма не соответствует прочитанной вами контрольной сумме, это означает, что вы не можете считать прочитанные данные действительными. Это может быть потому, что вы не писали его раньше или потому, что он был поврежден. Вам решать разобраться с этим в управлении ошибками. Но имейте в виду ограничения контрольной суммы, если у вас есть возможности для выполнения CRC, вероятно, стоит это сделать!

3. Я никогда не слышал, чтобы контрольная сумма называлась CRC.

4. @Olaf Хотел бы я сказать то же самое, но я сталкиваюсь с этим почти каждый день. Может быть, это региональная или только моя компания, кто знает.

5. @TimF: О, наоборот, довольно часто. Но CRC для контрольной суммы не является хорошей ссылкой для тех, кто ее использует.

Ответ №2:

Один из способов сделать это — иметь дополнительный байт check_eeprom в EEPROM. Это считывается перед чтением структуры. В первый раз вы можете записать 0x55 в этот байт. Если вы прочитали этот байт как 0x55, то в EEPROM заданы допустимые значения, иначе вам нужно его инициализировать. Эта проверка может быть выполнена в процедуре инициализации

 // read check_eeprom from eeprom
if (check_eeprom == 0x55)
{
   // Normal operation
}
else
{
   // First time. Write default values

   // write 0x55 into check_eeprom location
}
  

Ответ №3:

Простым подходом должна быть установка ФЛАГА во время первого чтения, чтобы помочь определить, является ли он первым прочитанным или нет.

При выполнении операции чтения проверьте, установлен ли ФЛАГ. Если ФЛАГ установлен, выполните обычное чтение и обработку. Если ФЛАГ не установлен, то это означает, что это первое чтение, и поэтому заполните структуру значениями по умолчанию. Убедитесь, что ФЛАГ установлен в конце первой операции чтения.