Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Похоже баг CPU core ATTiny26
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Rst7
Наступил на неприятность:

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
Rash
Попробуй вначале записать адрес r27, а потом r26
Код
...
asm("LDI R27,0x03");
asm("LDI R26,0x80");
...
Rst7
Цитата(Rash @ Jan 18 2006, 11:28) *
Попробуй вначале записать адрес r27, а потом r26
Код
...
asm("LDI R27,0x03");
asm("LDI R26,0x80");
...


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

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

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

ЗЫ Прерывания запрещены.
solidreg
У иеня всё равотает. ищите проблемы в друой месте програмы (IAR оптимизасия и подробнее)
Rst7
Цитата(solidreg @ Jan 18 2006, 11:58) *
У иеня всё равотает. ищите проблемы в друой месте програмы (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 - дупло.

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

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

А например в 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. При проуверке не подтвердилось.
solidreg
Попробуйте вобще без IAR'a. Только ASM. Интересно какие результаты будут.
Maxim
В Attiny26 всего 128 байт памяти (RAM) и контролер имеет полное право портить R27 в соответствии со своим ядром.
Георгий
Проверил этот кусок у себя - нормально. Так что даже мое предположение не срабатывает. Глюк где то не тут.
Rst7
Цитата(Maxim @ Jan 18 2006, 12:38) *
В Attiny26 всего 128 байт памяти (RAM) и контролер имеет полное право портить R27 в соответствии со своим ядром.


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

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

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

Я на ATmega16 запустил т с JTAG'ом смотрел. (нет у меня tiny26).
Видимо, надо было на tiny26 смотреть...
Rst7
Цитата(solidreg @ Jan 18 2006, 13:10) *
>> Вопрос к тем, кто писал "У меня все работает" - вы что, уже на камне проверили?

Я на ATmega16 запустил т с JTAG'ом смотрел. (нет у меня tiny26).
Видимо, надо было на tiny26 смотреть...


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

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

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

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


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

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


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

Кстати, старший байт не грузится для использования указателя. Там переменная, которую положил туда ИАР. Еще раз повторюсь - то что на асме написано - это тестовый кусок, выжимка кода, чтобы точно проверить, что регистр запарывается.
Gennadiy_
Добрый день.
Вы гденибудь читали в документации, что обращение к памяти 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 команды после запуска АЦП на однократное преобразование результат преобразования был испорчен. Пришлось отказаться от переключения канала до окончания преобразования. Было это год назад.
Rst7
Цитата(Gennadiy_ @ Jan 18 2006, 15:22) *
Добрый день.
Вы гденибудь читали в документации, что обращение к памяти SRAM по адресу 0x0380 будет обрабатываться также как обращение по адресу 0х0080 ? Я такого там не видел, думаю, что претензии в этом случае неправомерны.


Я ожидаю, что при выполнении сл. действий:

X=0x380;
LD R16,X+;

будет в регистровой паре X число 0x381. Этого не происходит.

Цитата
Зато, и это уже обсуждалось на другом форуме, в 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 команды после запуска АЦП на однократное преобразование результат преобразования был испорчен. Пришлось отказаться от переключения канала до окончания преобразования. Было это год назад.


Это не имеет отношения к обсуждаемому вопросу. angry.gif
prottoss
Цитата(Rst7 @ Jan 18 2006, 20:19) *
Цитата(prottoss @ Jan 18 2006, 14:27) *

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


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


Извиняюсь, не заметил. Но все-таки в Tiny2313, на асме, я пользовался всего одним регистром в качестве указателя, при этом в старших половинах указателей хранил глобальные переменные программы, и все работало на ура...



Цитата(Rst7 @ Jan 18 2006, 20:39) *
Я ожидаю, что при выполнении сл. действий:

X=0x380;
LD R16,X+;

будет в регистровой паре X число 0x381. Этого не происходит.


Вообще-то ячейки SRAM с адресом 0x380 в ATtiny26 не существует, если уж подходить к этому вопросу принципиально, и МК имеет полное право заглючить с данным указателем. В даташите на рассматриваемый МК ничего не сказано по поводу обращений к несуществующим адресам. там сказано про 16-разрядные указатели при обращении к памяти, и что область памяти расположена с 0х0060 по 0х00DF. Вы пробовали обращаться к валидным адресам?
prottoss
Цитата(Rst7 @ Jan 18 2006, 20:39) *
Я ожидаю, что при выполнении сл. действий:

X=0x380;
LD R16,X+;

будет в регистровой паре X число 0x381. Этого не происходит.


А Вы пробовали обращаться по валидному адресу (0х0000 - 0х00DF)? В даташите ничего не сказано об обращении по несуществующим адресам, соответсвенно МК имеет полное право глючить. Зато там сказано про формировании адреса с помощью регистровой пары.
Rst7
Цитата(prottoss @ Jan 18 2006, 15:52) *
Извиняюсь, не заметил. Но все-таки в Tiny2313, на асме, я пользовался всего одним регистром в качестве указателя, при этом в старших половинах указателей хранил глобальные переменные программы, и все работало на ура...
...
Вообще-то ячейки SRAM с адресом 0x380 в ATtiny26 не существует, если уж подходить к этому вопросу принципиально, и МК имеет полное право заглючить с данным указателем. В даташите на рассматриваемый МК ничего не сказано по поводу обращений к несуществующим адресам. там сказано про 16-разрядные указатели при обращении к памяти, и что область памяти расположена с 0х0060 по 0х00DF. Вы пробовали обращаться к валидным адресам?


Не я обращаюсь к невалидным адресам. ИАР С в старшем байте X хранит переменную (как Вы на Tiny2313). Когда он использует X+ (при этом в младшем байте валидный поинтер), старший байт (и соответственно, переменная) портится. На прошлых процах такого не было.
Rst7
Вообщем так. Вытащил свежий 8-bit AVR Instruction Set от 11/05. В нем открытым текстом написано:

LD - Load Indirect from Data Space to Register using Index X
....
Регистр-указатель X может быть неизменен или может быть пост-икрементирован или пред-декрементирован .... Имейте в виду, что только младший байт X-указателя изменяется в устройствах с размером области данных не более 256 байт. Для этих устройств старший байт указателя НЕ ИСПОЛЬЗУЕТСЯ ПРИ ВЫПОЛНЕНИИ ИНСТРУКЦИИ И МОЖЕТ БЫТЬ ИСПОЛЬЗОВАН ДЛЯ ДРУГИХ ЦЕЛЕЙ (большие буквы - мои wink.gif Перевод тоже)...


ЧТД. Значит таки глюк в ядре. Обидно.
beer_warrior
А портиться только после Х+/Х- ?
При обычном использовании порядок?
Не пробовали тот же фокус с Y и Z?

Попробую завтра поиграться.
defunct
Цитата(Rst7 @ Jan 18 2006, 15:39) *
Я ожидаю, что при выполнении сл. действий:

X=0x380;
LD R16,X+;

будет в регистровой паре X число 0x381. Этого не происходит.


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

По большому счету, скажите зачем использовать IAR для камня с 2kb Flash и 128 байт RAM?
Rst7
Цитата(defunct @ Jan 18 2006, 21:10) *
Цитата(Rst7 @ Jan 18 2006, 15:39) *

Я ожидаю, что при выполнении сл. действий:

X=0x380;
LD R16,X+;

будет в регистровой паре X число 0x381. Этого не происходит.


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


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

Цитата
По большому счету, скажите зачем использовать IAR для камня с 2kb Flash и 128 байт RAM?


Так надо.
defunct
Цитата(Rst7 @ Jan 19 2006, 08:35) *
Вы невнимательно читаете мои посты. Я уже привел перевод из документации Atmel, который черным по белому говорит, что то, что я ожидаю, должно произойти и не должно привести к каким-либо непредсказуемым последствиям.


Понимаете, доверие к фирме Atmel у меня будет чуть-чуть повыше чем к Вам и намного выше чем к глючному IAR. Тема поднятая Вами достаточно серьезная. Либо Вы обнаружили баг ядра, который впоследствии появится в errata, либо баг IAR, либо третий наиболее неприятный вариант - вам померещилось.

В том самом даташите имеется допущение:
Not all variants of this instruction is available in all devices. Refer to the device specific instruction set summary.
Полагаю оно относится к Tiny15, но кто знает, может быть и к tiny26 оно тоже относится. Хотя буду откровенен, считаю, что оно не относится к tiny26.

Для чистоты эксперимента, предлагаю Вам скомпилировать Ваш код в AVR Studio, и проверить на реальном чипе. Если XH точно также затрется, тогда это явно баг ядра, если нет, тогда это явный баг IAR'а, и тогда следует писать в IAR, а не в Atmel.

PS: такой эксперимент я уже проделал, угадайте результат.
Rst7
Цитата(defunct @ Jan 19 2006, 10:28) *
Цитата(Rst7 @ Jan 19 2006, 08:35) *

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


Понимаете, доверие к фирме Atmel у меня будет чуть-чуть повыше чем к Вам и намного выше чем к глючному IAR. Тема поднятая Вами достаточно серьезная. Либо Вы обнаружили баг ядра, который впоследствии появится в errata, либо баг IAR, либо третий наиболее неприятный вариант - вам померещилось.

В том самом даташите имеется допущение:
Not all variants of this instruction is available in all devices. Refer to the device specific instruction set summary.
Полагаю оно относится к Tiny15, но кто знает, может быть и к tiny26 оно тоже относится. Хотя буду откровенен, считаю, что оно не относится к tiny26.


Перевожу то, что вы процитировали: Не все варианты этой инструкции доступны во всех устройтвах.

Все описаные варианты данной инструкции доступны в Tiny26. Памяти данных у нее не более 256 байт, следовательно, старший байт игнорируется (см. посты выше). Все очень прозрачно написано.

Цитата
Для чистоты эксперимента, предлагаю Вам скомпилировать Ваш код в AVR Studio, и проверить на реальном чипе. Если XH точно также затрется, тогда это явно баг ядра, если нет, тогда это явный баг IAR'а, и тогда следует писать в IAR, а не в Atmel.

PS: такой эксперимент я уже проделал, угадайте результат.


Как Вы думаете, я не на живом камне третий день е....сь? angry.gif Про код, который я написал - это проверочная вставка, для того, чтобы убедится, что именно камень. Код компилирован правильно, т.е. так, как я написал - один к одному, без всяких изменений.
defunct
Цитата(Rst7 @ Jan 19 2006, 10:39) *
Как Вы думаете, я не на живом камне третий день е....сь? angry.gif Про код, который я написал - это проверочная вставка, для того, чтобы убедится, что именно камень. Код компилирован правильно, т.е. так, как я написал - один к одному, без всяких изменений.


Сделал нехитрый дивайс - разъем для ISP и 2 светодиода. Воткнул tiny26, написал такой код:

Код
.include "tn26def.inc"

START:
    ldi  YL, $FF
    out  DDRA, YL
    ldi  XH, $3
    ldi  XL, $81
    ldi  YL, $50
    st   X+,  YL
    inc  YL
    st   X+, YL

    ldi  XH, $3
    ldi  XL, $81
    ld   YL, X+

    cpi  XH, 3
    brne _show_red_led

_show_green_led:
    sbi  PortA, 1
    rjmp _halt

_show_red_led:
    sbi  PortA, 0

_halt:
    rjmp _halt


скомпилировал в AVR-Studio,
светится зеленый...

Что я делаю не так? Чип маркирован ATMEL 0442 ATTINY26-16PI, с обратной стороны - 4H2020 35570C 1-U0442
Rst7
Я тоже сделал код:
Код
#include "iotiny26.h"
    NAME    main

        PUBLIC  main

        ORG $0
        RJMP    main

        RSEG    CODE
main
    ldi    r16,0xFF
        out    DDRA,r16
        ldi    r16,0
        out    PORTA,r16
    ldi    r26,0x60
        ldi    r27,0x55
        ld    r16,x+
        out    PORTA,r27
dead_loop
    rjmp    dead_loop

    END     main


Что должно быть на порту А? Правильно - 01010101. Смотрим на лапы - 00000000. Убираем "ld r16,x+". На порту A - 01010101.

Что я делаю неправильно?

2 камня, с L и без L
ObitJr
Бинарники смотрели ? Может криво компилятор генерит...
Rst7
Цитата(ObitJr @ Jan 19 2006, 13:55) *
Бинарники смотрели ? Может криво компилятор генерит...


Грузил в AVRStudio, смотрел на дизасм, трассировал, сравнивал код с даташитом. Все правильно.
prottoss
Цитата(Rst7 @ Jan 19 2006, 19:07) *
Цитата(ObitJr @ Jan 19 2006, 13:55) *

Бинарники смотрели ? Может криво компилятор генерит...


Грузил в AVRStudio, смотрел на дизасм, трассировал, сравнивал код с даташитом. Все правильно.



А если пойти другим путем, тестовый Ваш код запустить на другом камне, вернее другого типа - тини13,14, 15 или любом другом тини? Какие там будут результаты?
Rst7
Цитата(prottoss @ Jan 19 2006, 15:07) *
Цитата(Rst7 @ Jan 19 2006, 19:07) *
Цитата(ObitJr @ Jan 19 2006, 13:55) *

Бинарники смотрели ? Может криво компилятор генерит...


Грузил в AVRStudio, смотрел на дизасм, трассировал, сравнивал код с даташитом. Все правильно.



А если пойти другим путем, тестовый Ваш код запустить на другом камне, вернее другого типа - тини13,14, 15 или любом другом тини? Какие там будут результаты?


На Т15 - безъидейно - нет Х регистра и sram. Щас попробую на Tiny2313 запустить. Других нет.
Rst7
Попробовал на Tiny2313 - все пучком, на порту 0x55. Имя порта, естественно, пришлось заменить с A на B.
KRS
А вы пробовали другой экземпляр Tiny26
у меня как то раз была битая мега (один бит в регистре r14) не работал глюков было....
Rst7
Цитата(KRS @ Jan 19 2006, 16:01) *
А вы пробовали другой экземпляр Tiny26
у меня как то раз была битая мега (один бит в регистре r14) не работал глюков было....


2 разных, один с L, другой без.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.