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

 
 
 
Reply to this topicStart new topic
> Проблемная опция Use Link-Time code generation, RVCT., генерит неправильный код, stm32
baralgin
сообщение May 13 2010, 19:23
Сообщение #1


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

Группа: Участник
Сообщений: 92
Регистрация: 23-12-08
Из: Кишинёв
Пользователь №: 42 680



Столкнулся с проблемой при включении этой опции в настройках Keil'а (MDK-4.10). Судя по описанию это поззволяет компилятору "глубже" проводить оптимизиацию. В общем суть проблемы: есть функция, запускаемая прямо из main():

Код
void HardTest_Run()
{
    int counter = 0;
    while( counter < 100 )
    {
        while( !ready );
        ready = false;

        if( !isV15Valid( CalcValue(sums_saved.V15) ) )
        {
            lcd_manualSet(26,16,12);
//            lcd_setState(LCD_STATE_EHA);
            counter = 0;
        }
        else
        {
            counter++;
            int dig = 9 - (counter / 10) % 10;
            lcd_manualSet(dig, dig , dig);
        }
    }
}


переменная ready (volatile bool) периодически меняется функцией этого же модуля, которая вызывается из другого модуля обработчиком прерывания. При закоментированной строчке   lcd_setState(LCD_STATE_EHA); срабатывает if(!isV15Valid(...)) - хотя не должен. Если же закоментировать lcd_manualSet и раскомментировать lcd_setState, то if не срабатывает (как и должно быть). Самое смешное, что обе эти функции(lcd_xxx) по сути делают одно и тоже:

Код
void lcd_manualSet(uint_fast8_t d0, uint_fast8_t d1, uint_fast8_t d2)
{
    point1_on = false;
    point2_on = false;
    dig0 = d0;
    dig1 = d1;
    dig2 = d2;
}

void lcd_setState(uint_fast8_t state)
{
    point1_on = false;
    point2_on = false;
    dig2 = some_states[state][0];
    dig1 = some_states[state][1];
    dig0 = some_states[state][2];
}


где массив some_states константный.

В итоге этот код работает без проблем, если не ставить галочку "Use Link-Time code generation" , иначе только с плясками типа замены одной функции на другую(lcd_xxx). Чувствую что проблема где-то в коде, но не знаю какому типу ошибок характерны такие глюки.

ps: Стэк и кучу увеличивал, да и судя по статистике компилятора там с лихвой числа.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 13 2010, 19:39
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Нет, так не пойдет, слишком много вопросов: что такое isV15Valid, как объявлен тип bool и т.д. и т.п. Выделите "глюк" в компактный и самодостаточный пример.
Go to the top of the page
 
+Quote Post
baralgin
сообщение May 13 2010, 20:16
Сообщение #3


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

Группа: Участник
Сообщений: 92
Регистрация: 23-12-08
Из: Кишинёв
Пользователь №: 42 680



aaarrr
Код
volatile bool ready = false;

static bool isV15Valid(int val)
{
    return ( val > HardTest_V15_Min && val < HardTest_V15_Max );
}

static int CalcValue(int val)
{
    return (( val + (ADC_SCAN_COUNT / 2) ) / ADC_SCAN_COUNT);
}
HardTest_V15_Min, HardTest_V15_Max, ADC_SCAN_COUNT - константы.
Я и так уже выделил(функции упрощены). Я не знаю на каком этапе это произошло, т.к. вёл массовый рефакторинг, заворачивая всё что нужно и не нужно в классы. Но как выяснилось не в них дело, сейчас их нет, а глюк есть.

Добавил плотную задержку перед вызовом HardTest_Run() и заработало... Перед вызовом этой функции в общем то происходит инициализация переферии, в том числе и запуск АЦП на периодическое сканирование. Задержка сделана так:
Код
    volatile int xxx = 1000000;
    while( --xxx > 0 );

Причём она существенна(по ощущениям десятые доли секунды). Уменьшение xxx хотябы на один ноль и проблема "цветёт". В общем Немного прояснилось - завтра буду дальше разбираться...
Go to the top of the page
 
+Quote Post
baralgin
сообщение May 16 2010, 12:40
Сообщение #4


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

Группа: Участник
Сообщений: 92
Регистрация: 23-12-08
Из: Кишинёв
Пользователь №: 42 680



После долгих и мучительных танцев с известным музыкальным инструментом причину выяснил: компилятор слишком агрессивно соптимизировал переменную sums_saved.V15. Придётся все переменные структуры объявлять как volatile, во избежании. А их много...

Формально, кажется, что компилятор прав: в данном модуле есть функция модифицирующая переменные структуры sums_saved, но она вызывается из прерывания(к тому же из другого модуля). Но всё равно возникает ряд вопросов:
1) Оптимизация 03, time. Проблема возникает только при активации опции из названия топика.
2) Непонятное исчезновение проблемы в зависимости от того, что именно вызывается внутри злополучного if. Причём танцы вокруг функций модуля lcd меня окончательно запутали. Чертовщина просто smile.gif .
3) несколько раз полностью перерабатывал модуль меняя логику и порядок проверки параметров(и даже порядок объявления переменных и имена идентификаторов): проблема возникает строго в одном месте(V15), хотя кроме этого проверяются и другие параметры.
4) непонятно каким образом помогает гиганская задержка из предыдущего поста - никакой логики я не вижу. На данном этапе программы всё предельно просто(большую часть программы я просто отключил).
5) Под IAR 4.41 всё работает без проблем(естественно тоже при максимальной оптимизации на скорость).

Собственно мне скорость не критична(в реальном изделлии будет O3,size), но всё равно хочется не зависить от компилятора совсем...

ps: это типа крик души smile.gif : неужели придётся всё volatil'ить, что каким-нибудь боком связано с прерываниями...
Go to the top of the page
 
+Quote Post
igorsk
сообщение May 16 2010, 15:09
Сообщение #5


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

Группа: Участник
Сообщений: 84
Регистрация: 22-03-10
Пользователь №: 56 131



Цитата(baralgin @ May 16 2010, 13:40) *
ps: это типа крик души smile.gif : неужели придётся всё volatil'ить, что каким-нибудь боком связано с прерываниями...

А это, имхо, всегда хорошая идея.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение May 16 2010, 15:11
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(igorsk @ May 16 2010, 19:09) *
А это, имхо, всегда хорошая идея.

Нет, это всегда плохая идея - ставить volatile где надо и не надо, не разбираясь.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение May 16 2010, 15:31
Сообщение #7


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(baralgin @ May 16 2010, 18:40) *
неужели придётся всё volatil'ить

Есть другой выход - не использовать Link-Time code generation. Особенно если
Цитата(baralgin @ May 16 2010, 18:40) *
скорость не критична

smile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 16 2010, 17:58
Сообщение #8


Гуру
******

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



Цитата(igorsk @ May 16 2010, 18:09) *
А это, имхо, всегда хорошая идея.

Глупее трудно придумать. Это называется полностью расписаться в собственной некомпетентности.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 23:08
Рейтинг@Mail.ru


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