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

Похоже баг CPU core ATTiny26

Наступил на неприятность:

 

char TestR26(void)

{

asm("CLI");

asm("PUSH R26 ");

asm("PUSH R27 ");

asm("LDI R26,0x80");

asm("LDI R27,0x03"); //Обратите внимание на значение!!!

asm("LD R16,X+");

asm("MOV R16,R27");

asm("POP R27 ");

asm("POP R26 ");

asm("SEI");

}

 

Результат должен быть 3, а получается 0. Странно.

 

Наступил, когда у меня начало запарывать R27, в котором IAR положил переменную, а при вызове функций не сохранял (как собственно и должно быть) - модель ведь tiny.

 

Вообщем в Атмел я уже отписал, посмотрим, как среагируют.

 

PS Все таки сомнения гложут, посмотрите всE, вроде 3 - должно получиться на выходе (R16), а выходит 0

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


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

Попробуй вначале записать адрес r27, а потом r26

...
asm("LDI R27,0x03");
asm("LDI R26,0x80"); 
...

 

Во-первых без разницы.

 

Во-вторых, просто LD ...,X+ запарывает R27, даже если в R26 не 0xFF. Вот и все.

 

В-третьих, это тестовый кусок. А как компилятор положит - я не могу контролировать. Сам то код я починил, руками R27 сохраняю и восстанавливаю, но дело не в этом, а в том, что в ядре глюк.

 

ЗЫ Прерывания запрещены.

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


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

У иеня всё равотает. ищите проблемы в друой месте програмы (IAR оптимизасия и подробнее)

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


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

У иеня всё равотает. ищите проблемы в друой месте програмы (IAR оптимизасия и подробнее)

 

Оптимизация не влияет. Написана руками тестовая функция, которую я и привел в первом посте. Как видно, она запрещает прерывания, грузит в X 0x380, грузит в R16 по X с автоникрементом (что приводит к попаданию в R16 содержимого ячейки SRAM с адресом 0x80), и возвращает значение ст. байта X. Результат далее не важен в этом месте, он передается на мастер прибор для отображения. В этом месте (в выводе) все замечательно передается - это я, чтобы не было дурных идей, типа не работает дальше, говорю. Факт в том, что результат = 0. А с разрешенными прерываниями (правда, при этом мой код в другое место ложится) результат = 1.

 

Конкретно в иаровском коде идея следующая:

 

main()

{

 

...

//здесь R27 используется как локальная переменная

...

foo1();

....

//И здесь R27 - таже лок. переменная, ее значение используется

 

}

 

 

foo1()

{

 

 

p=txbuf;

// 00000008 .... LDI R26, txbuf //Это присвоение указателя

 

...

c=*p++; //Для p используется X, p - точно не 255

//Код соответственно

// 00000014 916D LD R22, X+ //ЗДЕСЬ ЗАПАРЫВАЕТСЯ R27

...

}

 

На входе foo1 сохраняется только R26, как и должно быть, на выходе - восстанавливается. А в R27 - дупло.

 

Когда я все это выяснил - была написана тестовая процедура, как видите - на асме и с запрещенными прерываниями, для локализации эффекта. Эффект есть. Не может не есть ;)

 

Вот такая фигня.

 

А например в 4433 (у меня на нем давно прибор один сделан) c этим все в порядке, я там на асме все написал, но старшие байты указателей (XH, YH, ZH) в полный рост как глобальные переменные использую - и все в порядке.

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


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

Ошибка мне кажется в написании самой тестовой функции

char TestR26(void)

{

asm("CLI");

asm("PUSH R26 ");

asm("PUSH R27 ");

asm("LDI R26,0x80");

asm("LDI R27,0x03"); //Обратите внимание на значение!!!

asm("LD R16,X+");

asm("MOV R16,R27");

asm("POP R27 ");

asm("POP R26 ");

asm("SEI");

}

В R16 возвращается результат (char), а так как ты ничего не возвращаешь - у тебя в R16 будет писаться 0.

Нужно явно вернуть значение.

 

P.S. При проуверке не подтвердилось.

Изменено пользователем Георгий

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


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

В Attiny26 всего 128 байт памяти (RAM) и контролер имеет полное право портить R27 в соответствии со своим ядром.

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


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

Проверил этот кусок у себя - нормально. Так что даже мое предположение не срабатывает. Глюк где то не тут.

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


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

В Attiny26 всего 128 байт памяти (RAM) и контролер имеет полное право портить R27 в соответствии со своим ядром.

 

Не имеет он права IMHO. И ИАР придерживается тогоже мнения - не сохраняет R27 при модели tiny. А ИАРовцы в плотную с Atmel'ом работают, так что я думаю - не имеет правов он таких. Кстати, например, LD ...,Z в Tiny15 портит ZH - об этом напрямик в даташите написанно.

 

Щас нашел другой проц. Правда Tiny26L. Тот же эффект.

 

Вопрос к тем, кто писал "У меня все работает" - вы что, уже на камне проверили?

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


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

>> Вопрос к тем, кто писал "У меня все работает" - вы что, уже на камне проверили?

 

Я на ATmega16 запустил т с JTAG'ом смотрел. (нет у меня tiny26).

Видимо, надо было на tiny26 смотреть...

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


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

>> Вопрос к тем, кто писал "У меня все работает" - вы что, уже на камне проверили?

 

Я на ATmega16 запустил т с JTAG'ом смотрел. (нет у меня tiny26).

Видимо, надо было на tiny26 смотреть...

 

Ха, если бы оно в ядре, которое small, не работало, уже бы Atmel гнилыми помидорами закидали. В том то и дело, что на камне надо на T26 смотреть.

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


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

Зачем, при памяти в 128 байт грузить указатель 16-разрядным числом? Хватит и младшего байта. С помощью его (к примеру R26 - XL) можно адресовать до 256 ячеек памяти, для тех кто не знает :-). При этом, какой бы ни был старший байт адреса все равно мы попадает по нужному адресу. Это проверено мной, правда на ATtiny2313. Там все прекрасно адресуется при загрузке адреса в один регистр. Написано все было на асме в АВРСтудио, при чем в качестве указателей использовались все три регистра, способные, в данном случае быть указателями - XL, YL и ZL. Ни каких глюков в прошитом МК и готовом устройстве не было...

 

И с какой стати Вы взяли, что результат должен быть 3? Вы грузите в R16 число из ячейки по адресу 0х80 !!!

 

Запарывать старший регистр будет когда в младшем регистре 0xFF, и применяется команда с инкрементом регистра-указателя, или когда в младшем регистре 0x00, и применяется команда с декрементом регистра-указателя

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


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

Зачем, при памяти в 128 байт грузить указатель 16-разрядным числом? Хватит и младшего байта. С помощью его (к примеру R26 - XL) можно адресовать до 256 ячеек памяти, для тех кто не знает :-). При этом, какой бы ни был старший байт адреса все равно мы попадает по нужному адресу. Это проверено мной, правда на ATtiny2313. Там все прекрасно адресуется при загрузке адреса в один регистр. Написано все было на асме в АВРСтудио, при чем в качестве указателей использовались все три регистра, способные, в данном случае быть указателями - XL, YL и ZL. Ни каких глюков в прошитом МК и готовом устройстве не было...

 

И с какой стати Вы взяли, что результат должен быть 3? Вы грузите в R16 число из ячейки по адресу 0х80 !!!

 

Вы не заметили, что после использования X, следующей коммандой я переношу R27 в R16, ведь меня интересует именно состояние XH!!!!!! И оно должно быть 3, а в камне - 0.

 

Запарывать старший регистр будет когда в младшем регистре 0xFF, и применяется команда с инкрементом регистра-указателя, или когда в младшем регистре 0x00, и применяется команда с декрементом регистра-указателя

 

Именно этого я и ожидаю. А нет, запарывает R27 (XH).

 

Кстати, старший байт не грузится для использования указателя. Там переменная, которую положил туда ИАР. Еще раз повторюсь - то что на асме написано - это тестовый кусок, выжимка кода, чтобы точно проверить, что регистр запарывается.

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


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

Добрый день.

Вы гденибудь читали в документации, что обращение к памяти SRAM по адресу 0x0380 будет обрабатываться также как обращение по адресу 0х0080 ? Я такого там не видел, думаю, что претензии в этом случае неправомерны.

 

Зато, и это уже обсуждалось на другом форуме, в Tiny26 есть другие грабли:

1. напряжение встроенного опорного источника имеет очень широкий разброс от экземпляра к экземпляру до 2,8 в

2. в документации написано:

If a different data channel is selected while

a conversion is in progress, the ADC will finish the current conversion before performing

the channel change.

Так вот, у меня при попытке сменить канал сразу или через 2-3 команды после запуска АЦП на однократное преобразование результат преобразования был испорчен. Пришлось отказаться от переключения канала до окончания преобразования. Было это год назад.

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


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

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

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

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

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

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

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

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

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

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