|
|
|
IAR сошел с ума. |
|
|
|
Jul 6 2018, 08:59
|
Профессионал
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075
|
Цитата(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); возвращает тот же мусор
|
|
|
|
|
Jul 6 2018, 09:10
|
Местный
Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140
|
Цитата(Jenya7 @ Jul 6 2018, 12:08) хм...да на строчке return count; вижу правильное значение. а в len уже мусор. ничего не понимаю. Да чего там понимать. len живёт в регистрах, отладчик её не видит просто напросто. Пройдитесь отладчиком по ассемблерному коду начиная от return count и посмотрите как по регистрам это значение передаётся из функции. Версия иар какая? И это, чтобы на стеке выделять память под массив неизвестного размера надо иметь стальные яйца. Не надо!!!
|
|
|
|
|
Jul 6 2018, 09:16
|
Профессионал
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075
|
Цитата(scifi @ Jul 6 2018, 14:12) Оптимизация? Не знаю, как сейчас в яре, но вообще иногда замечал, что при оптимизации отладочная информация корёжится, и отладчик врёт. По-честному он должен был бы сказать "извините, из-за оптимизации не могу показать значение переменной". и вылетает в хард фолт. а жить с этим как? нет товарищи - IAR мне без оптимизации не нужен - вся его сила в оптимизации. иначе я бы сидел на цветастом эклипсе. я их маму в белых тапках видел.
Сообщение отредактировал Jenya7 - Jul 6 2018, 09:18
|
|
|
|
|
Jul 6 2018, 09:18
|
Гуру
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136
|
Цитата(Jenya7 @ Jul 6 2018, 12:14) и вылетает в хард фолт. а жить с этим как? Хотите отлаживать оптимизированный код - учите инструкции Thumb. А иначе жить с этим никак. Кстати, оч. простой обработчик Hard Fault вот такой: Код void hard_fault_handler(void) { int volatile w = 1; while (w); } При попадании туда в отладчике делаем w=0 и в окне дизассемблера потихоньку возвращаемся из обработчика. Возвращаемся туда, где произошла неприятность, и пытаемся понять, что пошло не так.
|
|
|
|
|
Jul 6 2018, 09:27
|
Профессионал
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075
|
Цитата(scifi @ Jul 6 2018, 14:18) Хотите отлаживать оптимизированный код - учите инструкции Thumb. А иначе жить с этим никак. Кстати, оч. простой обработчик Hard Fault вот такой: Код void hard_fault_handler(void) { int volatile w = 1; while (w); } При попадании туда в отладчике делаем w=0 и в окне дизассемблера потихоньку возвращаемся из обработчика. Возвращаемся туда, где произошла неприятность, и пытаемся понять, что пошло не так. при чем тут отладчик? он при оптимизации и на обычной прошивке выпадает в хард фолт
|
|
|
|
|
Jul 6 2018, 09:27
|
Местный
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264
|
Код 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 везде и всюду, но народ требует крови и зрелищ
Сообщение отредактировал Arlleex - Jul 6 2018, 09:30
|
|
|
|
|
Jul 6 2018, 09:37
|
Профессионал
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075
|
Цитата(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 везде и всюду, но народ требует крови и зрелищ если я объявляю 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);
Сообщение отредактировал Jenya7 - Jul 6 2018, 09:39
|
|
|
|
|
Jul 6 2018, 09:40
|
Местный
Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140
|
Цитата(Jenya7 @ Jul 6 2018, 12:37) если я объявляю volatile char usart1_rx_buf[RX1_BUFFERSIZE]; то IAR ругается во многих случаях И заполняете его в прерываниях, ку? А вы тоже на стек его, чтобы интересней было
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|