artemkad 88 19 июля, 2006 Опубликовано 19 июля, 2006 (изменено) · Жалоба При чтении ЕЕPROM в прерывании нет сохранения регистров адреса/данных(EEAR EEDR). Или что то-же самое - не защищаются от прерываний участок с момента записи EEAR EEDR до собственно подачи комманды чтения/записи. Результат - при работе с ЕЕPROM в прерывании возможна ситация когда разрушаются адрес или данные в операции чтения/записи из основного цикла. В связи с редкостью подобного события возможен крайне трудноуловимый глюк :angry2: ... Изменено 19 июля, 2006 пользователем ArtemKAD Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
arttab 0 20 июля, 2006 Опубликовано 20 июля, 2006 · Жалоба Какая версия IAR? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 20 июля, 2006 Опубликовано 20 июля, 2006 · Жалоба При чтении ЕЕPROM в прерывании нет сохранения регистров адреса/данных(EEAR EEDR). Или что то-же самое - не защищаются от прерываний участок с момента записи EEAR EEDR до собственно подачи комманды чтения/записи.Грабли не в компиляторе. Вопрос первый: Зачем запрещать прерывания если программа уже находится в прерывании? Из него плавно вытекает второй: как компилятор определит что в одном случае функция вызвана из прерывания и запрещать не нужно а в другом случае из фона и запрещать нужно? В том виде в каком оно есть все прекрасно работает из фона _без_ лишних накладных расходов - запретов/разрешений прерываний и сохранения/восстановления регистров. Если уж вы решили извратиться и работать с eeprom в прерывании (что само по себе уже глюк, только алгоритма) то уж будьте добры возьмите на себя труд сделать все эти лишние действия вручную и там где по-вашему они необходимы. P.S. А еще он за пивом не бегает, вот это меня бесит больше всего. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rryybb 0 20 июля, 2006 Опубликовано 20 июля, 2006 · Жалоба При чтении ЕЕPROM в прерывании нет сохранения регистров адреса/данных(EEAR EEDR). Или что то-же самое - не защищаются от прерываний участок с момента записи EEAR EEDR до собственно подачи комманды чтения/записи. Результат - при работе с ЕЕPROM в прерывании возможна ситация когда разрушаются адрес или данные в операции чтения/записи из основного цикла. В связи с редкостью подобного события возможен крайне трудноуловимый глюк :angry2: ... Предпочитаю работать с EEPROM вот так из основного цикла программы, когда знаю что, все прерывания запрещены и не что мне не помешает: void EEPROM_write(unsigned int adres,unsigned char data) { while(EECR & (1<<1)); EEAR=adres; EEDR=data; EECR |= (1<<2); EECR |= (1<<1); } unsigned char EEPROM_read(unsigned int adres) { while(EECR & (1<<1)); EEAR=adres; EECR |= (1<<0); return EEDR; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artemkad 88 20 июля, 2006 Опубликовано 20 июля, 2006 · Жалоба Какая версия IAR? Последняя не профи. Вопрос первый: Зачем запрещать прерывания если программа уже находится в прерывании? Из него плавно вытекает второй: как компилятор определит что в одном случае функция вызвана из прерывания и запрещать не нужно а в другом случае из фона и запрещать нужно? Компилятор должен был запретить прерывания при всех обращениях в основном цикле... Как - это уже отдельная тема. У компилятора более чем один способ решить этот вопрос. Если уж вы решили извратиться и работать с eeprom в прерывании (что само по себе уже глюк, только алгоритма) Ну, не знал, что чтение в прерывании флагов сохраняемых в EEPROM в каком-то другом месте это глюк :cranky: ... Предпочитаю работать с EEPROM вот так из основного цикла программы, когда знаю что, все прерывания запрещены и не что мне не помешает: void EEPROM_write(unsigned int adres,unsigned char data) { while(EECR & (1<<1)); EEAR=adres; EEDR=data; EECR |= (1<<2); EECR |= (1<<1); } unsigned char EEPROM_read(unsigned int adres) { while(EECR & (1<<1)); EEAR=adres; EECR |= (1<<0); return EEDR; } Вы не поверите - компилятор делает так-же ... Вот только представте, что произойдет если EEPROM_write было вызвано при не запрещенных прерываниях, а в прерывании вызвано EEPROM_read. И это самое прерывание попало между EEAR=adres; и EEDR=data; Результат ясен? Тоже самое когда без запрета прерывания будет вызван EEPROM_read. Только там последствия сразу не столь разрушительные.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TomaT 0 20 июля, 2006 Опубликовано 20 июля, 2006 · Жалоба Может и бывает нужда такая, но я не очень понимаю зачем рабочие флаги используемые в прерывании тащить из EEPROM? ИМХО это изврат. Почему их нельзя объявить в ОЗУ, проинициализировать из EEPROM'a и по мере надобности аккуратно сливать их туда в фоне? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rryybb 0 20 июля, 2006 Опубликовано 20 июля, 2006 · Жалоба Вы не поверите - компилятор делает так-же ... Вот только представте, что произойдет если EEPROM_write было вызвано при не запрещенных прерываниях, а в прерывании вызвано EEPROM_read. И это самое прерывание попало между EEAR=adres; и EEDR=data; Результат ясен? Почему не поверю, поверю. Эти функции я взял в своё время из каково-то даташата. Но как я писал выше, при работе с EEPROM у меня всегда гарантировано, запрещены прерывания. Во вторых я пытаюсь, как можно меньше его использовать. Если его использую то как правила храню две копии данных с расчитыным для них CRC что-то типа: struct DATA { unsigned char data1; unsigned char data2; unsigned char data3; unsigned char data_crc; }data; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 20 июля, 2006 Опубликовано 20 июля, 2006 · Жалоба Компилятор должен был запретить прерывания при всех обращениях в основном цикле... Как - это уже отдельная тема. У компилятора более чем один способ решить этот вопрос.Огласите хотя бы один способ. Если уж вы решили извратиться и работать с eeprom в прерывании (что само по себе уже глюк, только алгоритма) Ну, не знал, что чтение в прерывании флагов сохраняемых в EEPROM в каком-то другом месте это глюк :cranky: ... Теперь знаете - вы сами на него напоролись. Для обхода приходится запрещать прерывания в основном цикле, хотя без этого можно было обойтись. Обращение к eeprom требует ожидания готовности eeprom, а ожидание чего-либо находясь в прерывании - ошибка алгоритма. TomaT абсолютно прав. Копии данных, которые могут потребоваться в прерывании надо держать в ОЗУ. И грабли сразу исчезнут. А главное, компилятор сразу станет не виноват. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artemkad 88 20 июля, 2006 Опубликовано 20 июля, 2006 · Жалоба Компилятор должен был запретить прерывания при всех обращениях в основном цикле... Как - это уже отдельная тема. У компилятора более чем один способ решить этот вопрос.Огласите хотя бы один способ. PUSH/POP-нуть глобальные временные регистры EEAR, EEDR... Если уж вы решили извратиться и работать с eeprom в прерывании (что само по себе уже глюк, только алгоритма) Ну, не знал, что чтение в прерывании флагов сохраняемых в EEPROM в каком-то другом месте это глюк :cranky: ... Теперь знаете - вы сами на него напоролись. Для обхода приходится запрещать прерывания в основном цикле, хотя без этого можно было обойтись. Обращение к eeprom требует ожидания готовности eeprom, а ожидание чего-либо находясь в прерывании - ошибка алгоритма. Даже при разрешенных прерываниях? Даже если ожидаемое событие все равно глобально должно поменять весь алгоритм работы? :blink: TomaT абсолютно прав. Копии данных, которые могут потребоваться в прерывании надо держать в ОЗУ. И грабли сразу исчезнут. Исправить эти грабли не сложно - сложнее на них не наступить особенно когда о "такой малости" в доках ни слова... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 20 июля, 2006 Опубликовано 20 июля, 2006 · Жалоба Компилятор должен был запретить прерывания при всех обращениях в основном цикле... Как - это уже отдельная тема. У компилятора более чем один способ решить этот вопрос.Огласите хотя бы один способ. PUSH/POP-нуть глобальные временные регистры EEAR, EEDR... Он это должен сделать тогда и только тогда когда вызов идет из прерывания. Во всех остальных случаях это будут ненужные накладные расходы. Как компилятор определит, что вызов делается из прерывания? Обращение к eeprom требует ожидания готовности eeprom, а ожидание чего-либо находясь в прерывании - ошибка алгоритма. Даже при разрешенных прерываниях? Даже если ожидаемое событие все равно глобально должно поменять весь алгоритм работы? :blink: ?? Ожидается готовность eeprom. Что значит при разрешенных прерываниях? Мы уже внутри обработчика. Исправить эти грабли не сложно - сложнее на них не наступить особенно когда о "такой малости" в доках ни слова...Нет, компилятор тут не при чем. Он физически не может тут ничем помочь. Если уж если вам так хочется поизвращаться - напишите обертку для функции чтения из прерывания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xemul 0 20 июля, 2006 Опубликовано 20 июля, 2006 · Жалоба Даже если ожидаемое событие все равно глобально должно поменять весь алгоритм работы? :blink: И что? Взвести флажок и спокойно его обработать как асинхронное событие. Подобная обработка непосредственно в прерывании гарантирует Вам кучку головной боли, хотя, конечно, событие будет обработано на несколько микросекунд раньше:). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artemkad 88 20 июля, 2006 Опубликовано 20 июля, 2006 · Жалоба Компилятор должен был запретить прерывания при всех обращениях в основном цикле... Как - это уже отдельная тема. У компилятора более чем один способ решить этот вопрос.Огласите хотя бы один способ. PUSH/POP-нуть глобальные временные регистры EEAR, EEDR... Он это должен сделать тогда и только тогда когда вызов идет из прерывания. Во всех остальных случаях это будут ненужные накладные расходы. Как компилятор определит, что вызов делается из прерывания? Вы сами руцями указываете ему, что процедура является обработчиком... Обращение к eeprom требует ожидания готовности eeprom, а ожидание чего-либо находясь в прерывании - ошибка алгоритма. Даже при разрешенных прерываниях? Даже если ожидаемое событие все равно глобально должно поменять весь алгоритм работы? :blink: ?? Ожидается готовность eeprom. Что значит при разрешенных прерываниях? Мы уже внутри обработчика. Именно так. Внутри обработчика (предворительно исключив собственную рекурсию если она могла быть) разрешается прерывание. Чего тут непонятного :blink: ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 20 июля, 2006 Опубликовано 20 июля, 2006 (изменено) · Жалоба Вы сами руцями указываете ему, что процедура является обработчиком... Ну так напишите обертку и вручную используйте. Компилятор-то тут при чем? ?? Ожидается готовность eeprom. Что значит при разрешенных прерываниях? Мы уже внутри обработчика. Именно так. Внутри обработчика (предворительно исключив собственную рекурсию если она могла быть) разрешается прерывание. Чего тут непонятного :blink: ? Опс. Еще и вложенные прерывания организовать там, где можно просто тупо взять данные из копии в ОЗУ. Тогда не удивительно, что "грабли" :-) Изменено 20 июля, 2006 пользователем Сергей Борщ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artemkad 88 20 июля, 2006 Опубликовано 20 июля, 2006 · Жалоба Вы сами руцями указываете ему, что процедура является обработчиком... Ну так напишите обертку и вручную используйте. Компилятор-то тут при чем? "Грабли" на то и грабли - мирный инструмент пока не получишь от него по носу... :a14: Я уже говорил - исправить не сложно, сложно заметить... ?? Ожидается готовность eeprom. Что значит при разрешенных прерываниях? Мы уже внутри обработчика. Именно так. Внутри обработчика (предворительно исключив собственную рекурсию если она могла быть) разрешается прерывание. Чего тут непонятного :blink: ? Опс. Еще и вложенные прерывания организовать там, где можно просто тупо взять данные из копии в ОЗУ. Тогда не удивительно, что "грабли" :-) Это не "грабли" - при вложении прерываний сразу ожидаешь неприятностей и особо обращаешь внимание на это место. Ну а по поводу "там, где можно просто тупо взять" - просто и тупо иногда обработка того прерывания и без ЕЕPROM занимает сотни милисекунд. Оставлять запрещенными прерывания на подобное время мне как-то влом . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 21 июля, 2006 Опубликовано 21 июля, 2006 · Жалоба Судя по всему, никто из отвечавших здесь не заглянул сюда. Что касается компилятора, то он и не должен строить предположения насчёт прерываний. Для него EEPROM и система прерываний - две разные сути. Если пользователю вдруг захотелось эти сути объединить в своей задаче (требованиях), то пусть он (пользователь) этим и займётся, причём тут компилятор. Кроме того, работа с EEPROM может влиять\зависеть не только от системы прерываний, но и на\от системы самопрограммирования. Что прикажете компилятору делать в этом случае? Опять будете обвешивать его ярлыками с "граблями" за то что не оправдал Ваших надежд? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться