jenya7 0 6 июля, 2018 Опубликовано 6 июля, 2018 · Жалоба Прямо в этом модуле #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 29 6 июля, 2018 Опубликовано 6 июля, 2018 · Жалоба А на строке return count; какое значение count? Сдаётся мне, в том месте где вы смотрите len в момент отладки её уже нет. Либо оптимизировалась, либо потёрлась. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 6 июля, 2018 Опубликовано 6 июля, 2018 (изменено) · Жалоба А на строке return count; какое значение count? Сдаётся мне, в том месте где вы смотрите len в момент отладки её уже нет. Либо оптимизировалась, либо потёрлась. хм...да на строчке return count; вижу правильное значение. а в len уже мусор. ничего не понимаю. фига се!!! отключил оптимизацию - все нормально - len принимает правильное значение. это что - с оптимизацией надо попрощаться? не судьба? Изменено 6 июля, 2018 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 6 июля, 2018 Опубликовано 6 июля, 2018 · Жалоба хм...да на строчке return count; вижу правильное значение. а в len уже мусор. ничего не понимаю. Да чего там понимать. len живёт в регистрах, отладчик её не видит просто напросто. Пройдитесь отладчиком по ассемблерному коду начиная от return count и посмотрите как по регистрам это значение передаётся из функции. Версия иар какая? И это, чтобы на стеке выделять память под массив неизвестного размера надо иметь стальные яйца. Не надо!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 6 июля, 2018 Опубликовано 6 июля, 2018 · Жалоба хм...да на строчке return count; вижу правильное значение. а в len уже мусор. ничего не понимаю. Оптимизация? Не знаю, как сейчас в яре, но вообще иногда замечал, что при оптимизации отладочная информация корёжится, и отладчик врёт. По-честному он должен был бы сказать "извините, из-за оптимизации не могу показать значение переменной". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 6 июля, 2018 Опубликовано 6 июля, 2018 · Жалоба Да чего там понимать. len живёт в регистрах, отладчик её не видит просто напросто. Пройдитесь отладчиком по ассемблерному коду начиная от return count и посмотрите как по регистрам это значение передаётся из функции. Версия иар какая? версия 7.7. без оптимизации работает Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 6 июля, 2018 Опубликовано 6 июля, 2018 · Жалоба Да чего там понимать. len живёт в регистрах, отладчик её не видит просто напросто. На самом деле компилятор способен сообщать отладчику, что переменная в регистре. Видимо, поленились и не сделали. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 6 июля, 2018 Опубликовано 6 июля, 2018 (изменено) · Жалоба Оптимизация? Не знаю, как сейчас в яре, но вообще иногда замечал, что при оптимизации отладочная информация корёжится, и отладчик врёт. По-честному он должен был бы сказать "извините, из-за оптимизации не могу показать значение переменной". и вылетает в хард фолт. а жить с этим как? нет товарищи - IAR мне без оптимизации не нужен - вся его сила в оптимизации. иначе я бы сидел на цветастом эклипсе. я их маму в белых тапках видел. Изменено 6 июля, 2018 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 6 июля, 2018 Опубликовано 6 июля, 2018 · Жалоба и вылетает в хард фолт. а жить с этим как? Хотите отлаживать оптимизированный код - учите инструкции Thumb. А иначе жить с этим никак. Кстати, оч. простой обработчик Hard Fault вот такой: void hard_fault_handler(void) { int volatile w = 1; while (w); } При попадании туда в отладчике делаем w=0 и в окне дизассемблера потихоньку возвращаемся из обработчика. Возвращаемся туда, где произошла неприятность, и пытаемся понять, что пошло не так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 6 июля, 2018 Опубликовано 6 июля, 2018 · Жалоба Хотите отлаживать оптимизированный код - учите инструкции Thumb. А иначе жить с этим никак. Кстати, оч. простой обработчик Hard Fault вот такой: void hard_fault_handler(void) { int volatile w = 1; while (w); } При попадании туда в отладчике делаем w=0 и в окне дизассемблера потихоньку возвращаемся из обработчика. Возвращаемся туда, где произошла неприятность, и пытаемся понять, что пошло не так. при чем тут отладчик? он при оптимизации и на обычной прошивке выпадает в хард фолт Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 6 июля, 2018 Опубликовано 6 июля, 2018 (изменено) · Жалоба 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: Изменено 6 июля, 2018 пользователем Arlleex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 6 июля, 2018 Опубликовано 6 июля, 2018 · Жалоба нет товарищи - IAR мне без оптимизации не нужен - вся его сила в оптимизации. иначе я бы сидел на цветастом эклипсе. Вы будете смеяться, но ловля своих глюков в оптимизированном коде одинаково увлекательна как в яре, так и в эклипсе :laughing: я их маму в белых тапках видел. Жизнь - боль :cranky: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 6 июля, 2018 Опубликовано 6 июля, 2018 (изменено) · Жалоба 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: если я объявляю 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); Изменено 6 июля, 2018 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 6 июля, 2018 Опубликовано 6 июля, 2018 · Жалоба если я объявляю volatile char usart1_rx_buf[RX1_BUFFERSIZE]; то IAR ругается во многих случаях И заполняете его в прерываниях, ку? А вы тоже на стек его, чтобы интересней было :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 6 июля, 2018 Опубликовано 6 июля, 2018 · Жалоба И заполняете его в прерываниях, ку? А вы тоже на стек его, чтобы интересней было :) usart1_rx_buf принимает правильные значения, адрес передается правильно нигде не затирается. переделал на volatile - по прежнему uint32_t len = StrLen(com_str); выдает мусор с оптимизацией. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться