Ошибки чтения / записи EEPROM на dsPIC

8

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

Тестируемая плата принимает напряжение 24 В, которое снижается до 5 В через V7805. Чип работает на своем внутреннем генераторе с 16-кратным ФАПЧ, обеспечивая скорость работы ~ 29,5 MIPS. Соответствующий код на этой плате, по сути, очень прост: просыпайтесь, читайте данные из EEPROM, затем вводите бесконечный цикл. Прерывайте каждую миллисекунду, наблюдайте за некоторыми данными об окружающей среде и записывайте обновленное значение в EEPROM. Происходят другие события, но проблема по-прежнему возникает, даже если не связанный код закомментирован, поэтому я могу быть уверен, что он не имеет отношения к рассматриваемой проблеме.

В общем случае 95% времени плата просыпается с правильным значением в памяти и продолжает свое дело. Остальные 5% времени, однако, просыпаются с неправильным значением. В частности, он просыпается с перевернутой версией данных, которые он должен иметь. Это 4-байтовое беззнаковое длинное, которое я смотрю, и может перевернуться как верхнее, так и нижнее слово long. Например, 10 становится 2 ^ 16-10, что позже становится 2 ^ 32-10. Я могу воспроизвести сбой, вручную включив и выключив несколько десятков раз, но это не очень стабильно, и мой палец переключения изношен.

Чтобы воспроизвести проблему контролируемым образом, я построил вторую плату, которая подает питание 24 В на тестируемую плату. (Другой dsPIC управляет оптопарой Дарлингтона.) Плата тестера отключает напряжение 24 В на 1,5 секунды (достаточно долго, чтобы шина 5 В упала практически до 0 и оставалась там в течение одной секунды), затем включает 24 В на некоторое настраиваемое время , При времени включения около 520 мс я могу воспроизвести этот глюк EEPROM в течение пяти циклов питания, каждый раз.

Шина 5V ведет себя разумно. Он устанавливается при 5 В в течение 1 мс после включения, возможно, с перегрузкой, равной 0,4 В, при условии, что я могу доверять своему прицелу. При выключении он затухает до 0 В по экспоненте, достигая 1 В в течение 50 мс. У меня нет предупреждений о сборке, которые кажутся актуальными, просто неиспользуемые переменные и пропущенные символы новой строки в конце файлов.

Я пробовал несколько вещей:

  • Включение / отключение MCLR
  • Включение / отключение WDT
  • Включение / отключение защиты кода
  • Включение / отключение / изменение напряжения обнаружения отключения
  • Включение / отключение / изменение таймера включения
  • Различные настройки ФАПЧ на основном внутреннем генераторе
  • Подключение / отключение моего программатора PICkit 3
  • Добавление 470 мкФ емкости к шине 5 В
  • Добавление / удаление .1 мкФ через подтягивание 4.7k на моем выводе MCLR
  • Отключение всех прерываний в коде и не оставление ничего, кроме обновлений EEPROM в основном цикле
  • Добавление 1,5-секундной задержки в мою процедуру запуска, прежде чем я начну читать EEPROM

Я также написал отдельный тестовый код, который ничего не делает, но постоянно записывает значения в EEPROM, а затем считывает их обратно, следя за тем, чтобы значение не изменилось. Десятки тысяч итераций не дали ошибок. Все, что я могу сделать, - это то, что что-то идет не так с чтением или записью ЭСППЗУ, особенно при включении / выключении питания.

Я использую те же библиотеки EEPROM с 2007 года. Я видел случайные сбои, но ничего не воспроизводилось. Соответствующий код можно найти здесь:
http://srange.net/code/eeprom.c
http://srange.net/code/readEEByte.s
http://srange.net/code/eraseEEWord.s
http: / /srange.net/code/writeEEWord.s

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

Кто-нибудь знает, что происходит? У меня заканчиваются вещи, чтобы попробовать.

Стивен Коллингс
источник
Пожалуйста, смотрите здесь для получения обновленной информации по решению этой проблемы: electronics.stackexchange.com/questions/38083/…
Стивен Коллингс

Ответы:

3

Две вещи приходят мне на ум:

Во-первых, согласно спецификации, цикл стирания-записи занимает не менее 0,8 мс и до 2,6 мс. Вы говорите, что у вас есть прерывание каждые 1 мс, что может привести к операции записи. Я видел в коде, что вы отключаете прерывания для частей стирания и для частей функции записи. Но вы все равно можете получить смешное чередование вызовов функций. Может быть, это помогает, когда вы отключаете прерывания для всей последовательности стирания и записи?

Второе - вы можете захотеть записать, когда питание отключится, и запись в ЭСППЗУ произойдет именно в тот момент, когда напряжение питания упадет ниже рабочего напряжения. Вы можете попытаться контролировать напряжение питания и отказаться от записи, когда оно ниже, скажем, 4.5V. Это предполагает, что оно остается достаточно долго выше 2,7 В в качестве минимального рабочего напряжения, а обнаружение отключения настроено на срабатывание только ниже этой точки.

HLI
источник
Ты рядом! Цикл - стирание-> запись, поэтому, если между стиранием и записью происходит отключение питания, вы теряете свои данные. Моим первым решением было разделить EEPROM на несколько избыточных копий, которые автоматически проверяются на несоответствия. Но так как это съело 3/4 моего EEPROM, я заменяю это простым буфером записи. Буфер будет специальным блоком EEPROM, который содержит данные для записи, адрес для записи и флаг, указывающий, что запись еще не завершена. Это должно решить проблему, занимая гораздо меньше места.
Стивен Коллингс
Теперь я могу подтвердить, что мой подход на основе буфера работает и не страдает от потери данных из-за асинхронного отключения питания между стиранием и записью.
Стивен Коллингс,
5

Вы рассмотрели множество возможных проблем с оборудованием. Это нормально, но это скорее всего ошибка прошивки.

К сожалению, ваш исходный код плохо документирован и отформатирован так, что за ним трудно следить визуально. Ваш первый файл содержит объявление внешних подпрограмм вверху:

void readEEByte (без знака int, без знака int, void *);
void eraseEEWord (без знака int, без знака int);
void writeEEWord (без знака int, без знака int, void *);

Не только плохая идея помещать подобные объявления в клиентские модули, но ни одного комментария не видно! Мы можем только догадываться, что вы намереваетесь сделать из этих подпрограмм по их имени, а аргументы вызова полностью не документированы. Далее в этом файле у вас есть различные строки, начинающиеся с "//" и целая строка знаков равенства. Они добавляют визуальный беспорядок, делая слишком большим количеством проблем, чтобы следовать за кодом.

Вы можете сказать, что все это не имеет значения для работы кода. Тем не менее, плохие методы программирования, такие как это, имеют большое значение. Они приводят к плохому написанию кода и затрудняют выявление ошибок или даже того, что код должен делать. Все это приводит к тому, что трудно найти проблемы, как вы обнаруживаете. Вы даже сказали себе, что иногда видели сбои в этом коде с 2007 года. Это должно было быть серьезным признаком ошибки, возможно, даже плохого общего дизайна.

Исправьте беспорядок, правильно документируйте все интерфейсы и поместите общие объявления во включаемые файлы, которые вы пишете один раз, а затем ссылайтесь, когда это необходимо. Также ваше заявление о том, что у меня нет предупреждений о сборке, которые кажутся актуальными , это огромный красный флаг. Опять исправим беспорядок. При отладке всегда обращайтесь в первую очередь к легко воспроизводимым и исправимым проблемам. Иногда они на самом деле являются причиной серьезных проблем, а иногда, устраняя их, вы обнаруживаете причины других проблем. Компилятор предупреждает вас о неряшливости на серебряном блюде. Что вы еще хотите? У вас не должно быть неиспользуемых переменных, потому что они приводят в замешательство любого, кто пытается разобраться в вашем коде, и нет никаких оправданий отсутствующим новым строкам. Опять же, исправьте их очевидный беспорядок, особенно перед тем, как просить кого-либо еще взглянуть на ваш код.

Аккуратность и внимание к деталям имеют значение . Много.

 

Олин Латроп
источник
Вы совершенно правы в отношении кода. Просто для ясности, я начал использовать этот код пять лет назад, но кто-то другой написал его. Я не пишу вещи, которые выглядят так. Я все еще должен это исправить, и это не хорошо, что я не сделал. Просто, чтобы я не выглядел КУРОЧНЫМ, таким большим дураком. :-)
Стивен Коллингс
2
Доступ к внутренней EEPROM прост. Для таких простых вещей проще написать свой собственный код, чем пытаться выяснить, как работает чужое программное обеспечение, а затем исправлять его до тех пор, пока оно не сработает. Прочитайте паспорт и напишите код. Вы бы сделали через час.
Олин Латроп
Я согласен с Олином в том, что это скорее всего прошивка. В сообщении об ошибках ничего не говорится о EEPROM.
Адам Лоуренс
2
@Madmad - Листы с ошибками, возможно, не говорят, что с этой частью есть что-то подозрительное, но они никогда не скажут, что с ней нет ничего подозрительного :-)
stevenvh
1
@stevenvh Мои отношения с Microchip и их FAE были в основном положительными. Ошибки в частях, которые я использовал, были точными, и они вмешались, чтобы помочь нам с проблемами, часто находя обходные пути для нас.
Адам Лоуренс
0

У меня было идентичное поведение с 4-мя устройствами dsPIC30F6014A (около 10, использовавшихся за последние несколько месяцев ...), единственный способ избежать случайного повреждения данных при отключении питания - обнулить MCLR непосредственно перед выключением.

Очевидно, что на практике это невозможно, поэтому я выбрал замену «плохого» dsPIC, если у кого-то есть другое решение ...

Angelo
источник
3
Почему это не осуществимо? Обнаружение перебоев в подаче электроэнергии сделано очень много, даже для сохранения данных в EEPROM за последнюю мс.
Стивенв