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

Rst7

Модератор
  • Постов

    4 619
  • Зарегистрирован

  • Победитель дней

    2

Весь контент Rst7


  1. Новичок на С

    Можно, однако это раздувает код, т.к. все локальные переменные превращаются в статические. А само сохранение регистров (и последующее восстановление) остается и никуда не девается. А так убиваем двух зайцев - код уменьшаем, улучшаем читаемость этого всего дела, т.к. весь алгоритм лежит последовательно, а не по кусочкам, выполнить то, выполнть это... Аналогично - все превращается в автомат и совершенно не читабельно. Тем более, что эта программа (это стек TCP/IP) как понимаете не самоцель, а лишь маленькая часть большой программы, а вы предлагаете весь софт писать вот так? ЗЫ Наверное, надо другую тему организовать под названием "Какие у сапожников взгляды на искусство" ;)
  2. Новичок на С

    1. Возможно вы заметили, что IPreciver есть не конечный автомат, а обычный код, скажем так, поток (нить, thread) выполнения. Посему есть ответ и на вопрос 2 - весь сыр-бор - это организация двух (точнее трех) задач - main, IPreciver, IPtransmitter. Из них IPxxx - это задачи, которые передают управление в основную задачу только тогда, когда им надо ждать символ из входного потока (IPreciver) или ждать окончания передачи символа в выходной поток (IPtransmiter). И получают они управление по соответствующим прерываниям. Почему так - объясняю. Представте, что вам надо получить в буфер 20 байт. Как вы пишете это без использования прерываний: char s[20]; char *p=s; char i=20; do { *p++=rxchar(); }while(--i); Просто и понятно. Теперь представте это как автомат. Необходимо хранить указатели, состояние, и т.д. Каждое прерывание их необходимо загрузить, потом выгрузить. Весьма накладно, когда обработчик большой и сложный - как например TCP/IP. Поэтому, в том проекте, который мы обсуждаем, сделана такая многозадачка с использованием функций исключительно библиотеки. Т.е. что получается с сохранением контекста: 1. Обработчик прерываний штатно сохраняет все scratch-регистры, т.к. есть вызов функции в обработчике (функция setjmp и longjmp). Также обработчик сохраняет SREG и если AVR большой, всяческие RAMPZ. Точнее сохраняет компилятор. 2. Функция setjmp сохраняет все localstore-регистры,оба указателя стека SP и Y, а также PC. В результате имеем полностью сохраненный контекст задачи в двух местах - часть регистров лежит в CSTACK задачи, остальное - в jmp_buf. Назад - аналогично. Прелести метода в том, что ни одной асмовской комманды нет. Единственное колдовство - инициализация задачи прямо в jmp_buf. При анализе суммарного кода почти нет потерь на на переключение, если сравнивать чисто с асм-вариантом - буквально 1 лишний CALL.
  3. Новичок на С

    Гм, да можно было и у меня спросить... Приятно, когда на твоих исходниках люди учатся ;)
  4. Я знаю ;) Задача не моя ;) Просто я предложил человеку, как возложить на компилятор вопрос подсчета.
  5. __delay_cycles(сколько тактов) в IAR'е решат ваши проблемы ;)
  6. И снова DS18B20

    Обоснуй! ЗЫ У меня это дело в измерителе уже года 4 работает, если бы оно в 10 раз врало - хрен бы я метрологию прошел ;)
  7. И снова DS18B20

    Плохо смотрите. Там конечно не написано так же прямо, как я написал. Там есть табличка (пардон за форматирование): Temperature/Data Relationships Table 2 MSb 2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4 LSB MSb S S S S S 2^6 2^5 2^4 MSB (unit = °C) TEMPERATURE DIGITAL OUTPUT DIGITAL OUTPUT (Binary) (Hex) +125°C 0000 0111 1101 0000 07D0h +85°C 0000 0101 0101 0000 0550h* +25.0625°C 0000 0001 1001 0001 0191h +10.125°C 0000 0000 1010 0010 00A2h +0.5°C 0000 0000 0000 1000 0008h 0°C 0000 0000 0000 0000 0000h -0.5°C 1111 1111 1111 1000 FFF8h -10.125°C 1111 1111 0101 1110 FF5Eh -25.0625°C 1111 1110 0110 1111 FF6Fh -55°C 1111 1100 1001 0000 FC90h *The power on reset register value is +85°C.
  8. И снова DS18B20

    Берешь эти 2 байта как целое со знаком (int) и делишь на 16 (или двигаешь вправо на 4, например t>>=4). Теперь Т у тебя температура в целых градусах Цельсия со знаком.
  9. Похоже баг CPU core ATTiny26

    2 разных, один с L, другой без.
  10. Похоже баг CPU core ATTiny26

    Попробовал на Tiny2313 - все пучком, на порту 0x55. Имя порта, естественно, пришлось заменить с A на B.
  11. Похоже баг CPU core ATTiny26

    Грузил в AVRStudio, смотрел на дизасм, трассировал, сравнивал код с даташитом. Все правильно. А если пойти другим путем, тестовый Ваш код запустить на другом камне, вернее другого типа - тини13,14, 15 или любом другом тини? Какие там будут результаты? На Т15 - безъидейно - нет Х регистра и sram. Щас попробую на Tiny2313 запустить. Других нет.
  12. Похоже баг CPU core ATTiny26

    Грузил в AVRStudio, смотрел на дизасм, трассировал, сравнивал код с даташитом. Все правильно.
  13. Похоже баг CPU core ATTiny26

    Я тоже сделал код: #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
  14. Похоже баг CPU core ATTiny26

    Понимаете, доверие к фирме 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 байт, следовательно, старший байт игнорируется (см. посты выше). Все очень прозрачно написано. Как Вы думаете, я не на живом камне третий день е....сь? :angry2: Про код, который я написал - это проверочная вставка, для того, чтобы убедится, что именно камень. Код компилирован правильно, т.е. так, как я написал - один к одному, без всяких изменений.
  15. Похоже баг CPU core ATTiny26

    В эмуляторе все так и есть, но ведь в реальном чипе вполне возможна загрузка константы 0 при выходе за границу максимального адреса. Вы же читаете с несуществующего адреса, что уже само по себе неправильно и может привести к любым непредсказуемым последствиям. Вы невнимательно читаете мои посты. Я уже привел перевод из документации Atmel, который черным по белому говорит, что то, что я ожидаю, должно произойти и не должно привести к каким-либо непредсказуемым последствиям. Так надо.
  16. Похоже баг CPU core ATTiny26

    Вообщем так. Вытащил свежий 8-bit AVR Instruction Set от 11/05. В нем открытым текстом написано: LD - Load Indirect from Data Space to Register using Index X .... Регистр-указатель X может быть неизменен или может быть пост-икрементирован или пред-декрементирован .... Имейте в виду, что только младший байт X-указателя изменяется в устройствах с размером области данных не более 256 байт. Для этих устройств старший байт указателя НЕ ИСПОЛЬЗУЕТСЯ ПРИ ВЫПОЛНЕНИИ ИНСТРУКЦИИ И МОЖЕТ БЫТЬ ИСПОЛЬЗОВАН ДЛЯ ДРУГИХ ЦЕЛЕЙ (большие буквы - мои ;) Перевод тоже)... ЧТД. Значит таки глюк в ядре. Обидно.
  17. Похоже баг CPU core ATTiny26

    Не я обращаюсь к невалидным адресам. ИАР С в старшем байте X хранит переменную (как Вы на Tiny2313). Когда он использует X+ (при этом в младшем байте валидный поинтер), старший байт (и соответственно, переменная) портится. На прошлых процах такого не было.
  18. Похоже баг CPU core ATTiny26

    Я ожидаю, что при выполнении сл. действий: X=0x380; LD R16,X+; будет в регистровой паре X число 0x381. Этого не происходит. Так вот, у меня при попытке сменить канал сразу или через 2-3 команды после запуска АЦП на однократное преобразование результат преобразования был испорчен. Пришлось отказаться от переключения канала до окончания преобразования. Было это год назад. Это не имеет отношения к обсуждаемому вопросу. :angry2:
  19. Похоже баг CPU core ATTiny26

    Вы не заметили, что после использования X, следующей коммандой я переношу R27 в R16, ведь меня интересует именно состояние XH!!!!!! И оно должно быть 3, а в камне - 0. Именно этого я и ожидаю. А нет, запарывает R27 (XH). Кстати, старший байт не грузится для использования указателя. Там переменная, которую положил туда ИАР. Еще раз повторюсь - то что на асме написано - это тестовый кусок, выжимка кода, чтобы точно проверить, что регистр запарывается.
  20. Похоже баг CPU core ATTiny26

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

    Не имеет он права IMHO. И ИАР придерживается тогоже мнения - не сохраняет R27 при модели tiny. А ИАРовцы в плотную с Atmel'ом работают, так что я думаю - не имеет правов он таких. Кстати, например, LD ...,Z в Tiny15 портит ZH - об этом напрямик в даташите написанно. Щас нашел другой проц. Правда Tiny26L. Тот же эффект. Вопрос к тем, кто писал "У меня все работает" - вы что, уже на камне проверили?
  22. Похоже баг CPU core ATTiny26

    Оптимизация не влияет. Написана руками тестовая функция, которую я и привел в первом посте. Как видно, она запрещает прерывания, грузит в 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) в полный рост как глобальные переменные использую - и все в порядке.
  23. Похоже баг CPU core ATTiny26

    Во-первых без разницы. Во-вторых, просто LD ...,X+ запарывает R27, даже если в R26 не 0xFF. Вот и все. В-третьих, это тестовый кусок. А как компилятор положит - я не могу контролировать. Сам то код я починил, руками R27 сохраняю и восстанавливаю, но дело не в этом, а в том, что в ядре глюк. ЗЫ Прерывания запрещены.
  24. Похоже баг 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
  25. Хм, "Исскуство программирования" том, который "Сортировка и поиск", "Бинарный поиск" -> log2(30000)=15 обращений к базе для сравнения? О какой плисине может идти речь????
×
×
  • Создать...