реклама на сайте
подробности

 
 
7 страниц V  < 1 2 3 4 > »   
Reply to this topicStart new topic
> Глюки компилятора IAR?, Важно! Код прошивки по непонятным причинам не стартует в МК AVR.
singlskv
сообщение Jan 12 2008, 18:21
Сообщение #16


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(zltigo @ Jan 12 2008, 17:49) *
Повторяю - код должен быть работоспособным ПРИ ЛЮБОЙ ОПТИМИЗАЦИИ а не только без оптимизации или при оптимизации по размеру.

Это не совсем правда,
бывает что нужно записать значение в регистр и потом в течении нескольких тактов в другой,
без оптимизации это может не работать,
хотя автор:
Цитата
Код рабочий smile.gif
конечно ЖЖЕТ!!!
Автор, если у Вас например прерывание вызывается каждые 1000тактов и
требует 1500тактов на обработку, виноват компилятор ???
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 12 2008, 18:56
Сообщение #17


Гуру
******

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



Цитата(singlskv @ Jan 12 2008, 20:21) *
прерывание вызывается каждые 1000тактов и требует 1500тактов на обработку, виноват компилятор ???
Конечно! Ведь в нем не предусмотрена большая зеленая кнопка "ХОЧУ!" lol.gif


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
DiMonstr
сообщение Jan 12 2008, 19:56
Сообщение #18


Частый гость
**

Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706



Цитата(singlskv @ Jan 12 2008, 21:21) *
Автор, если у Вас например прерывание вызывается каждые 1000тактов и
требует 1500тактов на обработку, виноват компилятор ???


В данном случае ДА! На асме этот же код работает без оптимизации, а программа на СИ как уже всем известно в мнемонике она в 1,5-2 раза больше по размеру. Это можно посмотреть в отладчике хоть в AvrStudio, хоть в штатном ИАРовском. Зачем же Вы спорите товарищи? Я разве не прав???


А у кого-нибудь есть на ходу рабочая плата/макет с МК ATMEGA8? Я тогда здесь исходники выложу, а вы посмотрите. beer.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 12 2008, 20:00
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(singlskv @ Jan 12 2008, 20:21) *
Это не совсем правда,

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Baser
сообщение Jan 12 2008, 20:11
Сообщение #20


Просто Che
*****

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



Цитата(DiMonstr @ Jan 12 2008, 21:52) *
В данном случае ДА! На асме этот же код работает без оптимизации, а программа на СИ как уже всем известно в мнемонике она в 1,5-2 раза больше по размеру. Это можно посмотреть в отладчике хоть в AvrStudio, хоть в штатном ИАРовском. Зачем же Вы спорите товарищи? Я разве не прав???

Насчет обвинения компилятора неправы БЕЗУСЛОВНО, а насчет увеличения кода неправы ЧАСТИЧНО.
Если у вас есть некие критические секции программы, они должны быть написаны более тщательно, чем обычно. И уж без заглядывания в листинг при этом не обойтись smile.gif
А насчет увеличения размера кода в 1,5-2 раза это как сказать. Если в два раза, то это просто плохое знание Си. Некоторые конструкции компилятор может оттранслировать так что вам и не снилось написать на ассемблере, а может вас не понять и нагородить ерунды. Использование одинаковых кусков кода тоже в ИАРе реализовано отлично.

Если же вам все равно не хватает быстродействия, то никто не мешает вам написать критичные функции на ассемблере.

p.s. а мнемонику и отладчики вы вообще не к месту приплели sad.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 12 2008, 20:12
Сообщение #21


Гуру
******

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



Цитата(DiMonstr @ Jan 12 2008, 21:56) *
А у кого-нибудь есть на ходу рабочая плата/макет с МК ATMEGA8? Я тогда здесь исходники выложу, а вы посмотрите. beer.gif
Есть. А вы потом не откажетесть от
Цитата
Цитата
...В общем есть предложение поспорить на ящик пива, что компилятор снова не при чем, а виноваты недостаток знаний и опыта.
Да запросто!
?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
DiMonstr
сообщение Jan 12 2008, 20:21
Сообщение #22


Частый гость
**

Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706



Цитата(Сергей Борщ @ Jan 12 2008, 23:12) *
Есть. А вы потом не откажетесть от
Да запросто! ?

Лады. Но выложить смогу только в понедельник, сейчас нет на руках исходников.
Go to the top of the page
 
+Quote Post
AndyBig
сообщение Jan 12 2008, 22:58
Сообщение #23


Иногдящий
****

Группа: Свой
Сообщений: 691
Регистрация: 28-02-05
Пользователь №: 2 931



Если контроллер не успевает выполнять все функции хотя бы на среднем уровне оптимизации, значит пора подумать о другом контроллере. Если код без оптимизации не влазит в контроллер, значит пора подумать о другом контроллере smile.gif.
Иначе все это получается шаманством, на которое в серьезном проекте расчитывать просто нельзя. Имхо smile.gif
Go to the top of the page
 
+Quote Post
DiMonstr
сообщение Jan 20 2008, 15:26
Сообщение #24


Частый гость
**

Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706



Выкладываю исходники проекта. Попробуйте прошить контроллер и прочитать содержимое EEPROM. Что можно предпринять по оптимизации проекта, с учетом вышеизложенных проблем?
Прикрепленные файлы
Прикрепленный файл  pwrc.rar ( 286.74 килобайт ) Кол-во скачиваний: 62
 
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 20 2008, 16:58
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(DiMonstr @ Jan 20 2008, 19:26) *
Что можно предпринять по оптимизации проекта, с учетом вышеизложенных проблем?

Я вообще не экспериментирую с оптимизацией. Сразу включаю максимальную. Ведь вам изначально известно что надо оптимизировать длину или скорость. Я её включаю и больше не трогаю. Иногда только опции некоторые например cross call. Но это к работоспособности никакого отношения не имеет. То же самое, наверное, вам скажут и другие. Менять оптимизацию для получения работоспособного кода - это всё равно что пинать шины если заглох автомобиль. Совсем уж от безысходности. Бывает, что ты некоректно что-то сделал с точки зрения компилятора. Естественно по незнанию. В этом случае лучше локализовать ошибку и просмотреть выходной листинг. Как правило всё сразу становится на свои места.
Самые распространнённые в этом случае ошибки это ошибки связанные с volatile и с приведением типов.
Go to the top of the page
 
+Quote Post
DiMonstr
сообщение Jan 20 2008, 17:23
Сообщение #26


Частый гость
**

Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706



Цитата(SasaVitebsk @ Jan 20 2008, 19:58) *

Никак не могу найти причину такого поведения программы. Может я уже зацыклился? По выходному листингу всё вроде нормально. Посмотрите кто-нибудь свежим взглядом на программу? Подскажите где возможна исключительная ситуация.
Go to the top of the page
 
+Quote Post
aesok
сообщение Jan 20 2008, 17:34
Сообщение #27


Знающий
****

Группа: Участник
Сообщений: 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 routine
When 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;
Go to the top of the page
 
+Quote Post
DiMonstr
сообщение Jan 20 2008, 18:39
Сообщение #28


Частый гость
**

Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706



Цитата(aesok @ Jan 20 2008, 20:34) *

Правильно ли я понял, что глобальные переменные используемые в циклах подпрограмм прерываниий необходимо объявлять с ключевым словом volatile?
Спасибо.

Я к проекту подключил командный файл линкера lnkm8s.xcl. Может стоит изменить размеры стэков, как думаете?

Товарищи! Какие ещё будут нарекания по программе? help.gif

Сообщение отредактировал DiMonstr - Jan 20 2008, 18:40
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 20 2008, 19:01
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 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 было извлечено, а дальше обработка не осуществлялась, так как для компилятора в ней "не было смысла". smile.gif
Go to the top of the page
 
+Quote Post
forever failure
сообщение Jan 21 2008, 03:50
Сообщение #30


Местный
***

Группа: Участник
Сообщений: 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;
}
Если так поменять, тогда вообще никакого свитча не понадобится, и размер кода заметно уменьшиться. Такие места есть ещё. И ещё много чего интересного и занимательного есть, из-за чего этот код рабочим не является, и, похоже, никогда таковым не был.
Go to the top of the page
 
+Quote Post

7 страниц V  < 1 2 3 4 > » 
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 14th July 2025 - 13:28
Рейтинг@Mail.ru


Страница сгенерированна за 0.01518 секунд с 7
ELECTRONIX ©2004-2016