|
|
  |
IAR-CVAVR и глюки с прерываниями, настройки IAR? |
|
|
|
Nov 13 2007, 20:03
|
Участник

Группа: Новичок
Сообщений: 57
Регистрация: 31-07-06
Пользователь №: 19 217

|
В CVAVR был с помощью CodeWizardAVR проект, в котором по таймеру менялось значение одного из портов. Практически без изменений этот же проект был перенесен в IAR. При тестировании в AVRStudio4 обе программы вели себя полностью одинаково и корректно. Однако в микроконтроллере корректно работала только программа, написанная в CVAVR. В IAR программа выполнялась, но без вызова прерывания. Контроллер прошивался в обоих случаях через CVAVR STK200. Поскольку в симуляторе обе программы работали корректно, то ошибка скорее всего возникает при создании hex файла. Формат вывода выставлен как Intel standart. В чем может быть проблема и какие настройки надо изменить, чтобы все работало нормально?
|
|
|
|
|
Nov 13 2007, 23:40
|

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

|
Цитата(Dmitriy_V @ Nov 13 2007, 22:03)  В чем может быть проблема В программе и настройках. Посмотрите размер стеков, хотя он не должен влиять на вызов прерываний, скорее на работоспособность всей программы. Показывайте код, будем смотреть. Можете выкинуть все, кроме инициализации, прерывания и пустого цикла в main(). Только сначала сами убедитесь, что в таком виде программа не работает. Если вдруг заработает - постепенно добваляйте код, пока не перестанет работать.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 14 2007, 07:28
|
Участник

Группа: Новичок
Сообщений: 58
Регистрация: 11-01-07
Пользователь №: 24 311

|
точно-точно, со стеками в ИАР-е надо дружить
|
|
|
|
|
Nov 15 2007, 19:34
|
Участник

Группа: Новичок
Сообщений: 57
Регистрация: 31-07-06
Пользователь №: 19 217

|
Цитата(Сергей Борщ @ Nov 14 2007, 03:40)  Показывайте код, будем смотреть. Спасибо за участие и советы. Привожу код для CVAVR и IAR. Код, по-моему, проще не куда. Я его сделал после того, как два дня убил на отладку своей программы. В общем, то что мне надо, я уже переделал под CVAVR, но в симуляторе IAR заметно лидировал по тактам выполнения работы программы. Жалко терять скорость выполнения, она и так близка к критичной. IAR: Код ... CVAVR: Код ... Исправил, больше так не делайте. IgorKossak
Сообщение отредактировал IgorKossak - Nov 16 2007, 07:20
Прикрепленные файлы
src.rar ( 1.83 килобайт )
Кол-во скачиваний: 41
|
|
|
|
|
Nov 16 2007, 11:34
|
Участник

Группа: Новичок
Сообщений: 57
Регистрация: 31-07-06
Пользователь №: 19 217

|
Цитата(Сергей Борщ @ Nov 16 2007, 00:26)  А вы листинг смотрели? 99%, что цикл while (flag); ассемблировался в RJMP $-2. А ошибка ваша вот: volatile unsigned char flag; P.S. А такие большие куски кода надо прикладывать в виде файлов. Исправьте, пока не поздно, а то модераторы по шапке надают Огромное спасибо, буду пробовать. Листинг, конечно, смотрел, я его сам и писал  . По поводу Код while(flag); : если он неправильно ассемблируется, то что можно использовать вместо него для задержки до срабатывания прерывания? По поводу ошибки: никогда не думал, что оптимизация может зайти так далеко. Можно еще вопросик не по теме? У меня в целевой программе есть переменная типа Int. При передачи нужно как можно быстрее передавать побайтно значение этой переменной. В настоящий момент данные передаются следующим образом: Код PORTA=A_int; ... PORTA=(A_int>>8) ... . Как мне кажется, такая передача не оптимальна. По-идее, можно зарезервировать определенные регистры под переменную и выводить уже регистры: Код PORTA=r15; ... PORTA=r15 . Подскажите пожалуйста, будет ли такой алгоритм более быстрым по сравнению с первым и каким образом можно зарезервировать регистры под переменную? Когда я пытался осуществить резервирование, IAR говорил что-то о необходимости в изменении каких-то настроек. Заранее благодарен. P.S. За большие вставки извиняюсь, не знал, больше не повторится.
|
|
|
|
|
Nov 16 2007, 12:32
|
Участник

Группа: Свой
Сообщений: 40
Регистрация: 29-08-05
Из: новосибирск
Пользователь №: 8 054

|
в опциях проекта C/C++ Compiler - Code - поле Register utilization резервируешь сколько тебе нужно байт (сильно не увлекайся) а потом в тексте пишешь что-то вроде __regvar __no_init unsigned char FLASH @ 15; // переменная FLASH в регистре 15
|
|
|
|
|
Nov 16 2007, 15:45
|

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

|
Цитата(Dmitriy_V @ Nov 16 2007, 13:34)  Листинг, конечно, смотрел, я его сам и писал  . Недопонял. Листинг генерит компилятор - там ассемблерный текст, в который скомпилился ваш исходник. Цитата(Dmitriy_V @ Nov 16 2007, 13:34)  По поводу Код while(flag); : если он неправильно ассемблируется, то что можно использовать вместо него для задержки до срабатывания прерывания? Он компилируется правильно. Вы неправильно написали исходный код - не указали компилятору (с помощью квалификатора volatile), что flag может в любой момент измениться где-то еще (в прерывании). Он видит, что перед циклом вы присвоили flag=1 и дальше сорвершенно правомерно решает, что поскольку внутри цикла flag не меняется, то и проверять его снова не имеет смысла. И поэтому цикл вырождается в бесконечный. Если же вы укажите flag как volatile - компилятор будет вынужден на каждом проходе цикла считывать flag снова. И ваш цикл будет работать так, как вы и задумали.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 17 2007, 14:00
|
Участник

Группа: Новичок
Сообщений: 57
Регистрация: 31-07-06
Пользователь №: 19 217

|
Цитата(Сергей Борщ @ Nov 16 2007, 19:45)  Недопонял. Листинг генерит компилятор - там ассемблерный текст, в который скомпилился ваш исходник. У нас разные понятия о листинге программы. Поскольку я не силен в ассемблере (знаю только в общих чертах), то для меня листинг - это то, что я написал на C. Спасибо за разъяснения по ошибке. Теперь более понятно, получается, что CVAVR по-умолчанию считает все переменные volatile и поэтому работает правильно. Удручает при этом, что в симуляторе обе программы ведут себя одинаково. Впредь буду все глобальные переменные, используемые в прерывании, отмечать как volatile. Еще раз спасибо. Цитата(vvs5 @ Nov 16 2007, 16:32)  в опциях проекта C/C++ Compiler - Code - поле Register utilization резервируешь сколько тебе нужно байт (сильно не увлекайся) а потом в тексте пишешь что-то вроде __regvar __no_init unsigned char FLASH @ 15; // переменная FLASH в регистре 15 Мне нужна всего одна переменная типа int. Спасибо за разъяснения, теперь понятно где чего резервировать.
|
|
|
|
|
Nov 17 2007, 14:41
|

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

|
Цитата(Dmitriy_V @ Nov 17 2007, 16:00)  У нас разные понятия о листинге программы. Поскольку я не силен в ассемблере (знаю только в общих чертах), то для меня листинг - это то, что я написал на C. Во избежание дальнейших недоразумений - это называется исходным текстом, исходниками, source. А ассемблер надо знать хотя бы на уровне чтения листингов со словарем - т.е посмотреть, что же нагенерил компилятор и поставив себя на место процессора прокрутить в голове интересующий участок кода. Цитата(Dmitriy_V @ Nov 17 2007, 16:00)  получается, что CVAVR по-умолчанию считает все переменные volatile и поэтому работает правильно. У него просто более слабый опримизатор, видимо не способный вынести из цикла вычисления, которые не влияют на остальные операции в цикле. Цитата(Dmitriy_V @ Nov 17 2007, 16:00)  Удручает при этом, что в симуляторе обе программы ведут себя одинаково. В симуляторе в обоих программах вызывается прерывание? Тогда надо копать глубже. Если не победите к понедельнику, гляну на результат компиляции.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 17 2007, 15:52
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Dmitriy_V @ Nov 16 2007, 15:34)  У меня в целевой программе есть переменная типа Int. При передачи нужно как можно быстрее передавать побайтно значение этой переменной. В настоящий момент данные передаются следующим образом: Код PORTA=A_int; ... PORTA=(A_int>>8) ... . Можно не волноваться по данному поводу. IAR правильно поймёт вашу операцию и скомпилирует это в две команды МК. То есть эти два оператора будут соответствовать двум операторам ассемблера и выполнятся за два такта. Ну не считая конечно времени обращения к ячейкам. А время обращения зависит от типа применённой переменной A_int. Если она статическая, то время уйдёт примерно 7 тактов. Если это у вас в п/п, то переменная будет размещена в регистрах. PS: Ассемблер не страшен.  Можно посмотреть результирующий листинг и посмотреть описание инструкций МК.
|
|
|
|
|
Nov 21 2007, 19:51
|
Участник

Группа: Новичок
Сообщений: 57
Регистрация: 31-07-06
Пользователь №: 19 217

|
Цитата(Сергей Борщ @ Nov 17 2007, 18:41)  В симуляторе в обоих программах вызывается прерывание? Тогда надо копать глубже. Если не победите к понедельнику, гляну на результат компиляции. С volatile все заработало. На самом деле в симуляторе я смотрел cof файл. В этом, наверное, и кроется результат несовпадения.
|
|
|
|
|
Nov 22 2007, 11:22
|

Местный
  
Группа: Свой
Сообщений: 243
Регистрация: 22-09-04
Из: Burbach, Germany
Пользователь №: 704

|
Цитата(Dmitriy_V @ Nov 16 2007, 15:34)  У меня в целевой программе есть переменная типа Int. При передачи нужно как можно быстрее передавать побайтно значение этой переменной. Как вариант - использование объединения: Код union{ uchar Bytes[2]; uint Word; }Val16; ... //где-то в программе... Val16.Word=0x1234; PORTA=Val16.Bytes[0]; // PORTA=0x34 PORTB=Val16.Bytes[1]; // PORTB=0x12
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|