реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Непредусмотренное изменение регистра, Странное поведение похожее на баг компилятора
Didro
сообщение Jun 10 2012, 08:48
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 94
Регистрация: 9-04-07
Пользователь №: 26 893



Добрый день,

работаю с AT90CAN32. В основной программе обнаружил странную ошибку и в процессе выяснения обстоятельств получил вот такой пример, её иллюстрирующий:

CODE
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "twi_master.h"

unsigned char sendbuf[2] = {0b0011011<<1, 0xB4};

int main(void) {
CLKPR = 0x80;
CLKPR = 0x00;
DDRB = 0xFF;
DDRE |= (1<<PE2);
sei();

TWI_Master_Initialise();
TWI_Start_Transceiver_With_Data(sendbuf, 2);


unsigned char cntr=1;
while(1) {
if (fint) {fint = 0; TWI_Start_Transceiver_With_Data(sendbuf, 2); }

//_delay_us(30); если раскомментировать эту строку
//__asm__ __volatile__ ("ldir25, 0x61" :sm.gif;
//или если раскомментировать эту строку, то проблема себя не проявляет

volatile unsigned char tvar2876;
tvar2876 = 0x61;
if (tvar2876 != 0x61) {
PORTB = tvar2876;
PORTE|=1<<2;_delay_us(200);PORTE&=~(1<<2);_delay_us(200);
}

}
return 0;
}


Реализация функций работы с TWI взяты из AppNote315 (файлы TWI_Master.h и TWI_Master.c, приложены: Прикрепленный файл  TWI_Master.h.txt ( 5.98 килобайт ) Кол-во скачиваний: 365
Прикрепленный файл  TWI_Master.c.txt ( 11.93 килобайт ) Кол-во скачиваний: 310
).

Проблема заключается в том, что на PORTB выводится число 0х61 - т.е. срабатывает сравнение tvar2876 != 0x61, хотя очевидно, что такого быть не должно. Имя переменной tvar2876 выбрано случайным (специально, чтоб не думалось, что эта переменная где-то объявлена как external в других модулях).

Делаю следующий вывод по asm-листингу: Прикрепленный файл  AVR_Transmission.lss.txt ( 107.48 килобайт ) Кол-во скачиваний: 482
регистр r24, участвующий в операции сравнения меняется где-то в TWI-функциях (побочный эффект).

В чем может быть проблема ? Ранее с таким не сталкивался.

Компилировал AVR Studio 4 (Winavr2010aug), AVR Studio 6. Оптимизации выключены -O0
Спасибо

Сообщение отредактировал IgorKossak - Jun 10 2012, 14:01
Причина редактирования: [codebox] для длинного кода!!!
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jun 10 2012, 10:15
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Ага меняется , он сохраняется только в прерывании . Во всех других функциях его не заталкивают в stack. Но больше всего меня напрягло вот это
Вход:
Код
           push    r29
    push    r28

Выход:
Код
          pop    r0
    pop    r0
    pop    r0
    pop    r0
                pop    r28
    pop    r29
     5ca:    08 95           ret


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
zombi
сообщение Jun 10 2012, 13:26
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(ILYAUL @ Jun 10 2012, 13:15) *
Но больше всего меня напрягло вот это

А что именно тут напрягает?
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jun 10 2012, 16:55
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(zombi @ Jun 10 2012, 17:26) *
А что именно тут напрягает?

pop r0


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
zombi
сообщение Jun 10 2012, 17:18
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(ILYAUL @ Jun 10 2012, 19:55) *
pop r0

Там же сразу после PUSH
Код
rcall    .+0
rcall    .+0

Но зачем оно надо я хз.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jun 10 2012, 17:47
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Studio интерпретирует команду rcall 0 в
Код
RCALL     PC-0x00EC
- с любой точки на reset. Но там похоже IAR


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 10 2012, 21:50
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (zombi @ Jun 10 2012, 20:18) *
Но зачем оно надо я хз.
Самый быстрый, короткий и атомарный способ зарезервировать на стеке 2 байта.
QUOTE (ILYAUL @ Jun 10 2012, 20:47) *
Studio интерпретирует команду rcall 0
Там команда rcall .+0, а это несколько другое.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jun 11 2012, 18:02
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(Сергей Борщ @ Jun 11 2012, 01:50) *
Самый быстрый, короткий и атомарный способ зарезервировать на стеке 2 байта.
Там команда rcall .+0, а это несколько другое.

А зачем , этот резерв . Смысл?
Да я понимаю , что это несколько другое. Studio принимает и такое rcall .0 плюс перед 0 категорически отказывается принимать. Но результат тот же - перезагрузка . Только зачем тогда столько pop r0 , может существует обратная иструкция rcall .-0


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Александр Куличо...
сообщение Jun 12 2012, 11:10
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017



Насколько я помню, в этих аппнотах (вернее, в реализации) была проблема с тем, что если вызвать 2 сеанса передачи последовательно один за другим, то программа генерирует старт-условие на линии не дожидаясь завершения формирования стопа от предыдущего сеанса. Связано это с тем, что прерывание по приему TWI co статусом "stop received" приходит сразу как только обнаружен фронт на SDA ( при SCL=1), а не после фронта + tимп. Поэтому нужно после событие стопа на линии подождать tимп, а затем пробывать начать новую передачу. (уже подзабыл, чему должно быть равно tимп - 1/2 или 1/4 такта)

З.Ы. Извиняюсь за немного сумбурное объяснение

Update: Извините, не сразу вник в суть проблемы.
Вы говорите, что
Цитата
регистр r24, участвующий в операции сравнения меняется где-то в TWI-функциях (побочный эффект).

Но там кроме r24 есть еще и Y+50. Может, у Вас просто память где-то портится.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 7th July 2025 - 09:20
Рейтинг@Mail.ru


Страница сгенерированна за 0.0146 секунд с 7
ELECTRONIX ©2004-2016