Перейти к содержанию
    

"Сколько времени работаю с 'IAR Embedded Workbench 4.10B' и никаких проблем не возникало... Незнаю, как Вы работаете с EEPROM, а я предпочитаю не мудрить и использовать чтение/запись, как к обычным переменным объявленные в EEPROM. Просто посмотрите свой ассемблерный код после компиляции и все станет ясно, что на 'автомате' запрещение и разрешение прерываний там не генерируется. А в прерываниях на которые Вы сетуете необходимо учитывать автоматическое запрещение при входе в прерывание."

 

Да ну ! Насколько я помню аж в 2.28 ну может в 3.10 при таком способе общения с EEPROM компиллер вставляет вызов подпрограмки (встроенной) в которой он и запрещает прерывания !

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А если представить ситуацию, при которой происходит следующее:

Программа читает данные из EEPROM, в случайный момент времени, когда процесс получения данных еще не закончен, возникает прерывание, в теле которого происходит также доступ к EEPROM, однако уже к другим переменным. Что в итоге???? Возможна порча данных или нет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

"Сколько времени работаю с 'IAR Embedded Workbench 4.10B' и никаких проблем не возникало... Незнаю, как Вы работаете с EEPROM, а я предпочитаю не мудрить и использовать чтение/запись, как к обычным переменным объявленные в EEPROM. Просто посмотрите свой ассемблерный код после компиляции и все станет ясно, что на 'автомате' запрещение и разрешение прерываний там не генерируется. А в прерываниях на которые Вы сетуете необходимо учитывать автоматическое запрещение при входе в прерывание."

 

Да ну ! Насколько я помню аж в 2.28 ну может в 3.10 при таком способе общения с EEPROM компиллер вставляет вызов подпрограмки (встроенной) в которой он и запрещает прерывания !

Согласен, ошибался... :( нашел 'злачное место' в коде:

\ ?Subroutine23:

\ 00000000 94F8 CLI

\ 00000002 2D07 MOV R16, R7

\ 00000004 .... LDI R20, LOW(e_pressure)

\ 00000006 .... LDI R21, (e_pressure) >> 8

\ 00000008 .... RCALL __eeput8_16

\ 0000000A 9478 SEI

\ 0000000C 9508 RET

но как я понимаю эта процедура лишь для записи в eeprom...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А если представить ситуацию, при которой происходит следующее:

Программа читает данные из EEPROM, в случайный момент времени, когда процесс получения данных еще не закончен, возникает прерывание, в теле которого происходит также доступ к EEPROM, однако уже к другим переменным. Что в итоге???? Возможна порча данных или нет?

 

Порча данных в самом EEPROM не возможна! А вот полученные данные могут быть не праивльными если между записью адреса в EEAR, установкой бита в EECR и чтением EEDR возникло прерывание, в которм есть чтение EEPROM, вы просто получите байт данных с другого адреса

Но сами данные в EEPROM портится не должны.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я уже подробно говорил об этом.

В аттаче см. исправления для функций работы с EEPROM.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Замечательная дискуссия!

Спасибо всем. Я уже разобрался сам!

Действительно, удалось выяснить, что возникало наложение одной процедуры чтения на другую. Результат был неприятным.

Событие настолько редкое, что порой приходилось ждать по 3 суток его возникновения.

На решение таких задачек даже времени не жалко!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я бы на Вашем месте, учитывая что обращения к EEPROM идет как из обработчика прерывания так и из основного цикла программы поступил бы следующим образом:

 

1. Взял бы даташит на контроллер с которым собираюсь работать.

2. Написал бы функции чтения/записи EEPROM руководствуясь даташитом с запретом прерываний. (ДЛЯ ИСПОЛЬЗОВАНИЯ ИЗ ОСНОВНОГО ЦИКЛА ПРОГРАММЫ)

3. Написал бы аналогичные функции чтения/записи EEPROM без запрета прерываний (ДЛЯ ИСПОЛЬЗОВАНИЯ ВНУТРИ ОБРАБОТЧИКОВ ПРЕРЫВАНИЙ)

4. Использовал бы только свои функции.

 

и не имел бы никаких проблем с затиранием.

 

PS: Доверия к тому, что IAR'е учтена возможность работы с EEPROM внутри обработчика прерывания у меня нет. А если этот момент не учтен, то обращение к EEPROM из обработчика прерывания приведет к разрешению прерываний и как следствие к повторному возбуждению одного и того же обработчика.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

IAR C не только не запрещает прерывания при обращении к EEPROM, мало того - он даже не дожидается окончания записи (проверка окончания предыдущий записи осуществляется перед следующим обращением). Такой алгоритм обеспечивает наибольшую эффективность.

 

Поэтому, чтобы EEPROM не портилась, выходов 2.

1) Обрамлять каждое обращение к EEPROM запретом/разрешением прерываний, причем перед разрешением вручную дожидаться окончания записи

2) В прерывании сохранять/восстанавливать контекст EEPRM/ Вот пример из рабочего проекта:

 

#pragma vector=INT0_vect

__interrupt void USBNHandler(void)

{

char EAddr;

char EData;

//сохраняю контекст EEPROM

while(EECR&0x03); //жду окончания предыдущей записи (сброса EEWE, EERE)

EAddr=EEARL;

EData=EEDR;

 

//...обрабатываю прерывание, читаю-пишу EEPROM

 

//восстанавливаю контекст EEPROM

while(EECR&0x03); //жду сброса EEWE, EERE

EEARL=EAddr;

EEDR=EData;

}

 

Ну и третий, самый разумный подход - отказаться от обращения к EEPROM в прерываниях

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...