Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: IAR сошел с ума.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
Jenya7
Все работало вдруг началась проблема.
Принимаю команду с терминала
Код
if (usart1_rx_ready)
{
   usart1_rx_ready = 0;
   PARSER_ParseCommand(usart1_rx_buf);
}
ставлю точку останова на PARSER_ParseCommand(usart1_rx_buf); - вижу пришла красивая команда с '\0' в конце.
захожу внутрь функции
Код
uint32_t PARSER_ParseCommand(char *str)
{
    uint32_t com_found = 0;
    uint32_t len = 0;
    
    len = strlen(str);
    
    char temp_str[len];
strlen вычисляет длину строки - 504588880 - и естественно при алокации - char temp_str[len] - выпадаем в хард фолт.
Ну и кто он (IAR) после этого?
jcxz
Цитата(Jenya7 @ Jul 6 2018, 11:17) *
[/code]uint32_t len = 0;
len = strlen(str);
char temp_str[len];[/code]

Как он у вас вообще такой бред скомпилил?? wacko.gif
Jenya7
Цитата(jcxz @ Jul 6 2018, 13:25) *
Как он у вас вообще такой бред скомпилил?? wacko.gif


этот бред давно работает. непонятно почему сейчас перестал.

поставте галку VLA в настройках
scifi
Цитата(jcxz @ Jul 6 2018, 11:25) *
Как он у вас вообще такой бред скомпилил?? wacko.gif

C99 это разрешает. Проверял - реально на стеке выделяет места сколько попросишь.
jcxz
Цитата(Jenya7 @ Jul 6 2018, 11:29) *
этот бред давно работает. непонятно почему сейчас перестал.

Видимо какие-то новые расширения стандарта си...
Причина любого HF не компилятор, а кривые руки программиста.
scifi
Цитата(Jenya7 @ Jul 6 2018, 11:17) *
strlen вычисляет длину строки - 504588880 - и естественно при алокации - char temp_str[len] - выпадаем в хард фолт.

Есть такая версия: буфер наполняется в фоне (прерывания или как-то ещё), поэтому на момент вычисления длины строки там не совсем то, что было вначале.
jcxz
Цитата(scifi @ Jul 6 2018, 11:32) *
C99 это разрешает. Проверял - реально на стеке выделяет места сколько попросишь.

Товарищу сначала хотя-бы со стандартным си научиться работать. laughing.gif
Плюшки новых стандартов даже я не применяю, хоть и никогда не валю вину на IAR.
Jenya7
ок. ничего не выделяю. никаких массивовю просто
Код
uint32_t len = strlen(str);
выдает какие то не реальные цифры.

jcxz
Цитата(Jenya7 @ Jul 6 2018, 11:36) *
ок. ничего не выделяю. никаких массивовю просто
Код
uint32_t len = strlen(str);
выдает какие то не реальные цифры.

У Вас нет эмулятора? Пошагать внутрь strlen и посмотреть что происходит - не судьба?
Написать обработчик HF тоже видимо не судьба. Ну тогда да, конечно, в этом только IAR и может быть виноват..... laughing.gif
Jenya7
Цитата(scifi @ Jul 6 2018, 13:33) *
Есть такая версия: буфер наполняется в фоне (прерывания или как-то ещё), поэтому на момент вычисления длины строки там не совсем то, что было вначале.


я поставил точку останова в прием буфера - ничего не приходит.

Цитата(jcxz @ Jul 6 2018, 13:38) *
У Вас нет эмулятора? Зайти внутрь strlen и посмотреть что происходит - не судьба?


там асемблерные инструкции. я по ним мало что могу сказать.
VladislavS
Цитата(Jenya7 @ Jul 6 2018, 11:36) *
ок. ничего не выделяю. никаких массивовю просто
Код
uint32_t len = strlen(str);
выдает какие то не реальные цифры.

С размером стека порядок?

Переходите на С++, он вам так в ногу стрелять не даст.
Цитата
Error[Pe028]: expression must have a constant [note]: the value of variable "len" (declared at line XX) cannot be used as a constant



ЗЫ: Постой, постой! Что-то похожее припоминаю... Если не подключен string.h, он какую-то лажу вместо функций работы со строками подставлял. Прямо в этом модуле #include <string.h> добавь.
jcxz
Цитата(Jenya7 @ Jul 6 2018, 11:39) *
там асемблерные инструкции. я по ним мало что могу сказать.

Открыть "Cortex-M3/M4F Instruction Set" и посмотреть описание тех, всего нескольких команд, что там используются - никак?
Jenya7
Цитата(VladislavS @ Jul 6 2018, 13:41) *
С размером стека порядок?

Переходите на С++, он вам так в ногу стрелять не даст.


я все закрыл. все. strlen все равно возвращает мусор.
VladislavS
Цитата(Jenya7 @ Jul 6 2018, 11:45) *
я все закрыл. все. strlen все равно возвращает мусор.

Прямо в этом модуле #include <string.h> добавь. Попробуй, это не долго.
scifi
Цитата(Jenya7 @ Jul 6 2018, 11:39) *
там асемблерные инструкции. я по ним мало что могу сказать.

Какой занятный код. Тестируют пачками по 4 байта. Должно быть, на ассемблере накодили.
Jenya7
Цитата(VladislavS @ Jul 6 2018, 13:56) *
Прямо в этом модуле #include <string.h> добавь. Попробуй, это не долго.


переписал strlen.
Код
uint32_t StrlLen(char *str)
{
    uint32_t count = 0;
    while (*str != '\0')
    {
        str++;
        count++;
    }
    return count;
}
uint32_t len = StrlLen(str); возвращает тот же мусор
VladislavS
А на строке return count; какое значение count?

Сдаётся мне, в том месте где вы смотрите len в момент отладки её уже нет. Либо оптимизировалась, либо потёрлась.
Jenya7
Цитата(VladislavS @ Jul 6 2018, 14:04) *
А на строке return count; какое значение count?

Сдаётся мне, в том месте где вы смотрите len в момент отладки её уже нет. Либо оптимизировалась, либо потёрлась.

хм...да на строчке return count; вижу правильное значение. а в len уже мусор. ничего не понимаю.

фига се!!! отключил оптимизацию - все нормально - len принимает правильное значение. это что - с оптимизацией надо попрощаться? не судьба?
VladislavS
Цитата(Jenya7 @ Jul 6 2018, 12:08) *
хм...да на строчке return count; вижу правильное значение. а в len уже мусор. ничего не понимаю.

Да чего там понимать. len живёт в регистрах, отладчик её не видит просто напросто. Пройдитесь отладчиком по ассемблерному коду начиная от return count и посмотрите как по регистрам это значение передаётся из функции.

Версия иар какая?

И это, чтобы на стеке выделять память под массив неизвестного размера надо иметь стальные яйца. Не надо!!!
scifi
Цитата(Jenya7 @ Jul 6 2018, 12:08) *
хм...да на строчке return count; вижу правильное значение. а в len уже мусор. ничего не понимаю.

Оптимизация?
Не знаю, как сейчас в яре, но вообще иногда замечал, что при оптимизации отладочная информация корёжится, и отладчик врёт. По-честному он должен был бы сказать "извините, из-за оптимизации не могу показать значение переменной".
Jenya7
Цитата(VladislavS @ Jul 6 2018, 14:10) *
Да чего там понимать. len живёт в регистрах, отладчик её не видит просто напросто. Пройдитесь отладчиком по ассемблерному коду начиная от return count и посмотрите как по регистрам это значение передаётся из функции.

Версия иар какая?

версия 7.7. без оптимизации работает
scifi
Цитата(VladislavS @ Jul 6 2018, 12:10) *
Да чего там понимать. len живёт в регистрах, отладчик её не видит просто напросто.

На самом деле компилятор способен сообщать отладчику, что переменная в регистре. Видимо, поленились и не сделали.
Jenya7
Цитата(scifi @ Jul 6 2018, 14:12) *
Оптимизация?
Не знаю, как сейчас в яре, но вообще иногда замечал, что при оптимизации отладочная информация корёжится, и отладчик врёт. По-честному он должен был бы сказать "извините, из-за оптимизации не могу показать значение переменной".


и вылетает в хард фолт. а жить с этим как?

нет товарищи - IAR мне без оптимизации не нужен - вся его сила в оптимизации. иначе я бы сидел на цветастом эклипсе.

я их маму в белых тапках видел.
scifi
Цитата(Jenya7 @ Jul 6 2018, 12:14) *
и вылетает в хард фолт. а жить с этим как?

Хотите отлаживать оптимизированный код - учите инструкции Thumb. А иначе жить с этим никак. Кстати, оч. простой обработчик Hard Fault вот такой:
Код
void hard_fault_handler(void)
{
  int volatile w = 1;
  while (w);
}

При попадании туда в отладчике делаем w=0 и в окне дизассемблера потихоньку возвращаемся из обработчика. Возвращаемся туда, где произошла неприятность, и пытаемся понять, что пошло не так.
Jenya7
Цитата(scifi @ Jul 6 2018, 14:18) *
Хотите отлаживать оптимизированный код - учите инструкции Thumb. А иначе жить с этим никак. Кстати, оч. простой обработчик Hard Fault вот такой:
Код
void hard_fault_handler(void)
{
   int volatile w = 1;
   while (w);
}

При попадании туда в отладчике делаем w=0 и в окне дизассемблера потихоньку возвращаемся из обработчика. Возвращаемся туда, где произошла неприятность, и пытаемся понять, что пошло не так.

при чем тут отладчик? он при оптимизации и на обычной прошивке выпадает в хард фолт
Arlleex
Код
if (usart1_rx_ready)
{
   usart1_rx_ready = 0;
   PARSER_ParseCommand(usart1_rx_buf);
}
uint32_t PARSER_ParseCommand(char *str)
{
    uint32_t com_found = 0;
    uint32_t len = 0;
    len = strlen(str);
}

usart1_rx_ready есть volatile-переменная?
PARSER_ParseCommand() определена как функция, возвращающая значение. Если явно от нее ничего не требуется, значит и пишите (void)PARSER_ParseCommand(...), тем более когда применяются оптимизирующие ключи компиляции.
Сам буфер usart1_rx_buf должен иметь модификатор volatile, поскольку является буфером приема сырых данных и важно дать понять оптимизатору, чтобы не борогозил особо.
Еще в uint32_t PARSER_ParseCommand(char *str) я бы добавил uint32_t PARSER_ParseCommand(volatile char *str) для соответствия типов, тогда уж.
Вот теперь можно начинать включать оптимизацию и смотреть. Я, конечно, не сторонник ставить volatile везде и всюду, но народ требует крови и зрелищ biggrin.gif
scifi
Цитата(Jenya7 @ Jul 6 2018, 12:16) *
нет товарищи - IAR мне без оптимизации не нужен - вся его сила в оптимизации. иначе я бы сидел на цветастом эклипсе.

Вы будете смеяться, но ловля своих глюков в оптимизированном коде одинаково увлекательна как в яре, так и в эклипсе laughing.gif

Цитата(Jenya7 @ Jul 6 2018, 12:16) *
я их маму в белых тапках видел.

Жизнь - боль cranky.gif
Jenya7
Цитата(Arlleex @ Jul 6 2018, 14:27) *
Код
if (usart1_rx_ready)
{
    usart1_rx_ready = 0;
    PARSER_ParseCommand(usart1_rx_buf);
}
uint32_t PARSER_ParseCommand(char *str)
{
     uint32_t com_found = 0;
     uint32_t len = 0;
     len = strlen(str);
}

usart1_rx_ready есть volatile-переменная?
PARSER_ParseCommand() определена как функция, возвращающая значение. Если явно от нее ничего не требуется, значит и пишите (void)PARSER_ParseCommand(...), тем более когда применяются оптимизирующие ключи компиляции.
Сам буфер usart1_rx_buf должен иметь модификатор volatile, поскольку является буфером приема сырых данных и важно дать понять оптимизатору, чтобы не борогозил особо.
Еще в uint32_t PARSER_ParseCommand(char *str) я бы добавил uint32_t PARSER_ParseCommand(volatile char *str) для соответствия типов, тогда уж.
Вот теперь можно начинать включать оптимизацию и смотреть. Я, конечно, не сторонник ставить volatile везде и всюду, но народ требует крови и зрелищ biggrin.gif


если я объявляю volatile char usart1_rx_buf[RX1_BUFFERSIZE];
то IAR ругается во многих случаях - и мне приходиться делать приведение к типу
Код
memset((char *)usart1_rx_buf, '\0', RX1_BUFFERSIZE);
PARSER_ParseCommand(volatile char *com_str)
uint32_t len = StrLen((char*)com_str);
strcpy (temp_str, (char*)com_str);
VladislavS
Цитата(Jenya7 @ Jul 6 2018, 12:37) *
если я объявляю volatile char usart1_rx_buf[RX1_BUFFERSIZE]; то IAR ругается во многих случаях


И заполняете его в прерываниях, ку?

А вы тоже на стек его, чтобы интересней было sm.gif
Jenya7
Цитата(VladislavS @ Jul 6 2018, 14:40) *
И заполняете его в прерываниях, ку?

А вы тоже на стек его, чтобы интересней было sm.gif


usart1_rx_buf принимает правильные значения, адрес передается правильно нигде не затирается.
переделал на volatile - по прежнему uint32_t len = StrLen(com_str); выдает мусор с оптимизацией.
aaarrr
Цитата(Jenya7 @ Jul 6 2018, 12:45) *
uint32_t len = StrLen(com_str); выдает мусор с оптимизацией.

Содержимое R0 посмотрите после возвращения из StrLen - мусор?
Arlleex
Цитата(Jenya7 @ Jul 6 2018, 13:45) *
usart1_rx_buf принимает правильные значения, адрес передается правильно нигде не затирается.
переделал на volatile - по прежнему uint32_t len = StrLen(com_str); выдает мусор с оптимизацией.

Вы когда оптимизацию включаете - забудьте про адекватность отладчика сразу.
Прочитайте мое сообщение еще раз внимательно. После всех озвученных мной пунктов программа падает в HF?
aaarrr
Цитата(Arlleex @ Jul 6 2018, 12:27) *
Сам буфер usart1_rx_buf должен иметь модификатор volatile, поскольку является буфером приема сырых данных и важно дать понять оптимизатору, чтобы не борогозил особо.

Вот все же не должен - ничего страшного с ним оптимизатор не сделает.
Arlleex
Цитата(aaarrr @ Jul 6 2018, 13:55) *
Вот все же не должен - ничего страшного с ним оптимизатор не сделает.

Согласен, тут я не прав, поспешно сказал.
Но, для укрощения рук оптимизатора указатель на этот буфер (в данном случае аргумент функции) я бы сделал с этим модификатором, на мой взгляд.
Jenya7
Цитата(Arlleex @ Jul 6 2018, 14:52) *
Вы когда оптимизацию включаете - забудьте про адекватность отладчика сразу.
Прочитайте мое сообщение еще раз внимательно. После всех озвученных мной пунктов программа падает в HF?


да.

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

нет что то ахренительно сломалось. глобальные переменные принимают мусорные значения даже при инициализации.

ЧИЗЭС КРАЙСТ! вот я дурак. ошибся и передавал в функцию memcpy(&mot_task, addr, size); неправильный размер. у меня там по ходу убивалось около тысячи переменных в РАМ.

все ж таки жив ИАРка, рулит. надо свой мемкопи написать с проверкой размера.
Сергей Борщ
QUOTE (jcxz @ Jul 6 2018, 11:33) *
Видимо какие-то новые расширения стандарта си...
18 лет прошло. Этот стандарт Си уже не девочка, а вы все "новые".
scifi
Цитата(Jenya7 @ Jul 6 2018, 13:26) *
ЧИЗЭС КРАЙСТ! вот я дурак. ошибся и передавал в функцию memcpy(&mot_task, addr, size); неправильный размер. у меня там по ходу убивалось около тысячи переменных в РАМ.

Семён Семёныч...
Jenya7
Цитата(scifi @ Jul 6 2018, 19:06) *
Семён Семёныч...


ну а где механизмы защиты? на меммув перейти что ли...
Сергей Борщ
QUOTE
IAR сошел с ума.
Мне кажется, кого-то уже пора привлекать за клевету.
Jenya7
Цитата(Сергей Борщ @ Jul 7 2018, 10:46) *
Мне кажется, кого-то уже пора привлекать за клевету.


sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.