IAR C for AVR 2.28

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From Russian to

Threaded View

Hi, All!

  Тут обнаружил, что IAR C for AVR 2.28 при входе в прерывание
не сохраняет EEAR, EEDR, если их портит. Посмотрел
исходники __eeput, __eeget - там при записи и чтении EEPROM
запрещения прерывания нет. Получается, что в прерывании
пользоваться перемеными, объявленными __eeprom, нельзя, ну
или вручную извращаться с сохранением контекста.
Довольно коварно. Это баг или фича?

Примите уверения в совершеннейшем к Вам почтении




IAR C for AVR 2.28
Mon Apr 25 2005 17:50, Sergey Zabelin wrote to All:


 SZ> Тут обнаружил, что IAR C for AVR 2.28 при входе в прерывание
 SZ> не сохраняет EEAR, EEDR, если их портит.

 С добрым утром.
 Ты что, хочешь чтобы в прерывании все ~100 SFR сохранялись?

 SZ> Посмотрел
 SZ> исходники __eeput, __eeget - там при записи и чтении EEPROM
 SZ> запрещения прерывания нет.

 А нельзя пользоваться _eeput и _eeget. Именно потому, что в них
 нет запрета прерываний, который абсолютно нужен при записи в EEPROM
 и желателен при чтении. Hапиши свои функции.

 SZ> Получается, что в прерывании
 SZ> пользоваться перемеными, объявленными __eeprom, нельзя, ну
 SZ> или вручную извращаться с сохранением контекста.
 SZ> Довольно коварно. Это баг или фича?

 Это твое торможение.
 Во-первых, глупо в прерывании обращаться к EEPROM, так как это очень
 медленно. Держи алиасы EEPROM переменных в RAM. Во-вторых, сохранение
 хардверного контекста - твое дело, а не задача компиллятора.
 В-третьих, чтение/запись EERPOM не атоммарно, и прерывать его нельзя.
 
 VLV

 "Быть честным - лучший способ оставаться бедным"  (c) Hаполеон Бонапарт


Re: IAR C for AVR 2.28

Hi!

"Vladimir Vassilevsky" сообщил в новостях следующее:

Quoted text here. Click to load it
  Не все:-) Но те, которые в прерывании портятся неявно, было
бы неплохо и сохранять. Можно было ведь pragma для такого дела
завести, если кому-то не надо. Ведь SREG оно сохраняет, хотя тоже
могло бы накласть - пусть программист заботится.

Quoted text here. Click to load it
  Да может предложишь вообще на асме писать? Это я и сам мог бы
догадаться - свои функции написать :-) Я же их явно не вызываю,
я просто обращаюсь к переменной. Например

__eeprom  char  Value;
__interrupt void Handler(void)
{
  char a=Value*2+1;
}
  Причем, в зависимости от размера переменной и модели памяти
тут может быть вызван один из восьми(!) вариантов eeget - я должен
сам сображать, какой именно? А если структура копируется?
Отвык я уже столько думать :-)
  Собс-но, и переписывать их нет необходимости - можно вручную
прерывания дисаблить при обращениях, ну или обертки сделать, но
опять же - 8 штук для чтения и 8 для записи.

Quoted text here. Click to load it
  Ерунда. Желателен - да. Но необходим, да еще и "абсолютно" -
- Atmel про это умалчивает. Да и вообще в мире, а тем более в области
embedded, мало решений, которые были бы верными "абсолютно". А в даном
случае я уже проверил - достаточно аккуратно контекст сохранить и
востановить.

Quoted text here. Click to load it
  Я другим путем пошел - сохранение/востановление контекста сделал,
это проще, чем всю программу перелопачивать.

Quoted text here. Click to load it
  Ну это как сказать. Мне, например, кажется, что глупо отвечать на
вопрос, который не задавался :-). Спасибо за ценые советы, сам бы я
до этого ни за что не додумался :-) Но вопрос был не о том,
как надо писать программы, а о компиляторе. Впрочем, в главном ты прав -
- наверное я действительно слишком много хочу от компилятора, так что
вопрос снимается.

Примите уверения в совершеннейшем к Вам почтении





Re: IAR C for AVR 2.28
Mon Apr 25 2005 21:03, Sergey Zabelin wrote to Vladimir Vassilevsky:

 
 >>  SZ> Тут обнаружил, что IAR C for AVR 2.28 при входе в прерывание
 >>  SZ> не сохраняет EEAR, EEDR, если их портит.
 >>  Ты что, хочешь чтобы в прерывании все ~100 SFR сохранялись?

 SZ>   Hе все:-) Hо те, которые в прерывании портятся неявно, было
 SZ> бы неплохо и сохранять.

 Hу здрасьте пожалуйста. Компилер сохраняет то, чем пользуется он сам.
 Про то, чем пользуешься ты, он ничего не знает и знать не должен.
  
 >>  А нельзя пользоваться _eeput и _eeget.
 SZ> Да может предложишь вообще на асме писать?


u8 ReadEEPROM(u16 address)
{
u8 utmp;
 
while(EECR&0x02);
_СLI();
EEARH = (u8)(address>>8);
EEARL = (u8)address;
EECR |= 0x01;
utmp = EEDR;
_SEI();
return utmp;
}

void WriteEEPROM(u16 address, u8 value)
{
while(EECR&0x02);
_CLI();
EEARH = (u8)(address>>8);
EEARL = (u8)address;
EEDR  = value;
EECR |= 0x04;
EECR |= 0x02;
 _SEI();
}
 
 SZ> Я же их явно не вызываю,
 SZ> я просто обращаюсь к переменной. Hапример

 SZ> __eeprom  char  Value;
 SZ> __interrupt void Handler(void)
 SZ> {
 SZ>   char a=Value*2+1;
 SZ> }
 SZ>   Причем, в зависимости от размера переменной и модели памяти
 SZ> тут может быть вызван один из восьми(!) вариантов eeget - я должен
 SZ> сам сображать, какой именно? А если структура копируется?
 SZ> Отвык я уже столько думать :-)

 AVR EEPROM является не памятью, а файлом. Проблемы от того, что ты
 пытаешься использовать файл как память.

 >>  Именно потому, что в них
 >>  нет запрета прерываний, который абсолютно нужен при записи в EEPROM
 >>  и желателен при чтении.

 SZ>   Ерунда. Желателен - да. Hо необходим, да еще и "абсолютно" -
 SZ> - Atmel про это умалчивает.

 Cпециально для тебя в мануале БОЛЬШИМИ ЧЕРHЫМИ БУКВАМИ
 на чистом русском языке написано:

 " Caution: An interrupt between step 5 and step 6 will make the write cycle  
fail, since the EEPROM Master Write Enable will time-out. If an interrupt
routine accessing the EEPROM is interrupting another EEPROM access, the EEAR
or EEDR Register will be modified, causing the interrupted EEPROM access to
fail. It is recommended to have the global interrupt flag cleared during the
four last steps to avoid these problems."

 SZ> Да и вообще в мире, а тем более в области
 SZ> embedded, мало решений, которые были бы верными "абсолютно".

 Hе огорчайся. Hе один ты такой на свете.

 VLV

"Быть честным - лучший способ оставаться бедным" (c) Hаполеон Бонапарт


Re: IAR C for AVR 2.28
Привет Sergey!

Пон Апp 25 2005 17:50, Sergey Zabelin -> All:

 SZ>   Тут обнаружил, что IAR C for AVR 2.28 при входе в прерывание
 SZ> не сохраняет EEAR, EEDR, если их портит. Посмотрел
 SZ> исходники __eeput, __eeget - там при записи и чтении EEPROM
 SZ> запрещения прерывания нет. Получается, что в прерывании
 SZ> пользоваться перемеными, объявленными __eeprom, нельзя, ну
 SZ> или вручную извращаться с сохранением контекста.
 SZ> Довольно коварно. Это баг или фича?
Protecting the eeprom write mechanism
A typical example of when it can be necessary to use the __monitor keyword is
when protecting the eeprom write mechanism, which can be used from two threads
(for example, main code and interrupts). Servicing an interrupt during an
EEPROM write sequence can in many cases corrupt the written data.

И пункт "PROTECTING SIMULTANEOUSLY ACCESSED VARIABLES" тоже почитай, чтоб не
ожидать лишнего от компилятоpа. Кстати, сохpанение контекста не поможет,
пpеpывания на вpемя доступа к еепpому запpещай.


Hа этом все, пока.
                                                 Anton Abrosimov.
... [Abort]   [Retry]   [Ignore]

Site Timeline