|
|
  |
Глюки компилятора IAR?, Важно! Код прошивки по непонятным причинам не стартует в МК AVR. |
|
|
|
Jan 12 2008, 18:21
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(zltigo @ Jan 12 2008, 17:49)  Повторяю - код должен быть работоспособным ПРИ ЛЮБОЙ ОПТИМИЗАЦИИ а не только без оптимизации или при оптимизации по размеру. Это не совсем правда, бывает что нужно записать значение в регистр и потом в течении нескольких тактов в другой, без оптимизации это может не работать, хотя автор: Цитата Код рабочий  конечно ЖЖЕТ!!! Автор, если у Вас например прерывание вызывается каждые 1000тактов и требует 1500тактов на обработку, виноват компилятор ???
|
|
|
|
|
Jan 12 2008, 19:56
|
Частый гость
 
Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706

|
Цитата(singlskv @ Jan 12 2008, 21:21)  Автор, если у Вас например прерывание вызывается каждые 1000тактов и требует 1500тактов на обработку, виноват компилятор ??? В данном случае ДА! На асме этот же код работает без оптимизации, а программа на СИ как уже всем известно в мнемонике она в 1,5-2 раза больше по размеру. Это можно посмотреть в отладчике хоть в AvrStudio, хоть в штатном ИАРовском. Зачем же Вы спорите товарищи? Я разве не прав??? А у кого-нибудь есть на ходу рабочая плата/макет с МК ATMEGA8? Я тогда здесь исходники выложу, а вы посмотрите.
|
|
|
|
|
Jan 12 2008, 20:11
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(DiMonstr @ Jan 12 2008, 21:52)  В данном случае ДА! На асме этот же код работает без оптимизации, а программа на СИ как уже всем известно в мнемонике она в 1,5-2 раза больше по размеру. Это можно посмотреть в отладчике хоть в AvrStudio, хоть в штатном ИАРовском. Зачем же Вы спорите товарищи? Я разве не прав??? Насчет обвинения компилятора неправы БЕЗУСЛОВНО, а насчет увеличения кода неправы ЧАСТИЧНО. Если у вас есть некие критические секции программы, они должны быть написаны более тщательно, чем обычно. И уж без заглядывания в листинг при этом не обойтись А насчет увеличения размера кода в 1,5-2 раза это как сказать. Если в два раза, то это просто плохое знание Си. Некоторые конструкции компилятор может оттранслировать так что вам и не снилось написать на ассемблере, а может вас не понять и нагородить ерунды. Использование одинаковых кусков кода тоже в ИАРе реализовано отлично. Если же вам все равно не хватает быстродействия, то никто не мешает вам написать критичные функции на ассемблере. p.s. а мнемонику и отладчики вы вообще не к месту приплели
|
|
|
|
|
Jan 12 2008, 20:12
|

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

|
Цитата(DiMonstr @ Jan 12 2008, 21:56)  А у кого-нибудь есть на ходу рабочая плата/макет с МК ATMEGA8? Я тогда здесь исходники выложу, а вы посмотрите.  Есть. А вы потом не откажетесть от Цитата Цитата ...В общем есть предложение поспорить на ящик пива, что компилятор снова не при чем, а виноваты недостаток знаний и опыта. Да запросто! ?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 12 2008, 20:21
|
Частый гость
 
Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706

|
Цитата(Сергей Борщ @ Jan 12 2008, 23:12)  Есть. А вы потом не откажетесть от Да запросто! ? Лады. Но выложить смогу только в понедельник, сейчас нет на руках исходников.
|
|
|
|
|
Jan 20 2008, 15:26
|
Частый гость
 
Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706

|
Выкладываю исходники проекта. Попробуйте прошить контроллер и прочитать содержимое EEPROM. Что можно предпринять по оптимизации проекта, с учетом вышеизложенных проблем?
Прикрепленные файлы
pwrc.rar ( 286.74 килобайт )
Кол-во скачиваний: 62
|
|
|
|
|
Jan 20 2008, 17:23
|
Частый гость
 
Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706

|
Цитата(SasaVitebsk @ Jan 20 2008, 19:58)  Никак не могу найти причину такого поведения программы. Может я уже зацыклился? По выходному листингу всё вроде нормально. Посмотрите кто-нибудь свежим взглядом на программу? Подскажите где возможна исключительная ситуация.
|
|
|
|
|
Jan 20 2008, 17:34
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(SasaVitebsk @ Jan 20 2008, 19:58)  Самые распространнённые в этом случае ошибки это ошибки связанные с volatile ... Я не нашел в Вашей програме ни одного "volatile". Прочитайте вот это и добавте "volatile" для тех переменных для которых надо. Сорри что текст на англискон. My program doesn't recognize a variable updated within an interrupt routineWhen using the optimizer, in a loop like the following one: Код uint8_t flag; ... ISR(SOME_vect) { flag = 1; } ...
while (flag == 0) { ... } the compiler will typically access flag only once, and optimize further accesses completely away, since its code path analysis shows that nothing inside the loop could change the value of flag anyway. To tell the compiler that this variable could be changed outside the scope of its code path analysis (e. g. from within an interrupt routine), the variable needs to be declared like: Код volatile uint8_t flag;
|
|
|
|
|
Jan 20 2008, 18:39
|
Частый гость
 
Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706

|
Цитата(aesok @ Jan 20 2008, 20:34)  Правильно ли я понял, что глобальные переменные используемые в циклах подпрограмм прерываниий необходимо объявлять с ключевым словом volatile? Спасибо. Я к проекту подключил командный файл линкера lnkm8s.xcl. Может стоит изменить размеры стэков, как думаете? Товарищи! Какие ещё будут нарекания по программе?
Сообщение отредактировал DiMonstr - Jan 20 2008, 18:40
|
|
|
|
|
Jan 20 2008, 19:01
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Приведу пример для понимания происходящего допустим есть переменные глобальные Код volatile uint8_t AvarFuelWt, AvarCAN=0, // Счётчик секунд задержки на потерю топлива и CAN CAN_Temp, // Значение температуры двигателя по CAN CAN_POil; // Значение давления масла двигателя по CAN В прерывании есть такой код Код if((timesec--)==0) { timesec=FPWM; Flag.fSecond=1; AvarFuelWt++; AvarCAN++; } В голове следующий код Код if(AvarCAN>2) // Обработка потери CAN CAN_Temp=CAN_POil=0; // Обнулить значение Смысл обработки прост - если сообщений нет более 2 секунд, то обнулить значения (иначе при потере CAN сохраняются последние принятые значения). Вот что получим при компиляции Код 540 if(AvarCAN>2) // Обработка потери CAN \ ??main_16: \ 00000182 8D05 LDD R16, Z+29 \ 00000184 3003 CPI R16, 3 \ 00000186 F018 BRCS ??main_17 541 CAN_Temp=CAN_POil=0; // Обнулить значение \ 00000188 E000 LDI R16, 0 \ 0000018A 8F07 STD Z+31, R16 \ 0000018C 8F06 STD Z+30, R16 Уберём volatile. Код volatile uint8_t AvarFuelWt, AvarCAN=0; // Счётчик секунд задержки на потерю топлива и CAN uint8_t CAN_Temp, // Значение температуры двигателя по CAN CAN_POil; // Значение давления масла двигателя по CAN Получим следующее. Код 545 if(AvarCAN>2) // Обработка потери CAN \ ??main_16: \ 00000182 8D05 LDD R16, Z+29 546 CAN_Temp=CAN_POil=0; // Обнулить значение 547 // Обработка АЦП и выставление положения стрелок Как видите значение AvarCAN было извлечено, а дальше обработка не осуществлялась, так как для компилятора в ней "не было смысла".
|
|
|
|
|
Jan 21 2008, 03:50
|
Местный
  
Группа: Участник
Сообщений: 256
Регистрация: 6-03-05
Из: Екатеринбург
Пользователь №: 3 112

|
Кто нить ещё смотрел этот проект? Впечатление в целом, если коротко - ужоснах. Конечно, брёвна в чужих глазах все мастера замечать, но в данном случае, автор действительно жжёт. (Автор, не обижайтесь, воспримите это как конструктивную критику). Первое замечание в общем - код жутко неоптимален. ИАР, конечно многомощный комипилятор, но расчитывать на то, что он всё это дело оптимально разгребёт, не стоит. Пример в частности: в функции main есть switch (channel), в котором по каждой метке выполняется почти один и тот же код: case 0x01: { DebuggingData(); if (Value > MinValue & Value < MaxValue) /*<- здесь действительно побитовое И требуется ?*/ { MeanValue_CH1 = MeanValue_CH1 + Value; /* в каждой метке свитча своя только переменная MeanValue_CH* можно было бы объявить массив этих переменных и обращатся в ним по индексу: */ // MeanValue_CH[channel] += Value; if (MeanCount_CHx == StepMeanVoltage) { MeanValueVoltage[channel] = MeanValue_CH1 / StepMeanVoltage; // MeanValueVoltage[channel] = MeanValue_CH[channel] / StepMeanVoltage; MeanValue_CH1 = NULL; /* почему, кстати, целочисленной переменной присваивается значание указателя ? */ } break; } ALARM_PROCCESS = TRUE; break; } Если так поменять, тогда вообще никакого свитча не понадобится, и размер кода заметно уменьшиться. Такие места есть ещё. И ещё много чего интересного и занимательного есть, из-за чего этот код рабочим не является, и, похоже, никогда таковым не был.
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|