Коллеги, всем мяу!
Переношу проект из Keil в Eclipse, компилятор меняется на GCC. Почти всё работает, но периодически программа падает в HardFault, и путём отладки было обнаружено, что попадание в HardFault происходит при делении переменной типа long long int на константу типа int.
При этом в Keil никаких проблем с компиляцией и выполнением этого кода не было, а вот GCC компилирует его так, что контроллер после этого падает в HardFault.
Кто-нибудь сталкивался с этим?
Благодарю за внимание.
Если я где-то ошибаюсь, прошу от меня этого не скрывать. Заранее очень признателен
[uquote=">TEHb<",url="/forum/viewtopic.php?p=4606040#p4606040"]А точно именно хардфолт? Там по умолчанию на множество прерываний одна и та же затычка, скорее всего.[/uquote]Не обязательно именно из-за той же самой "затычки". Если программист не предпринимал попыток разделения fault-ов на разные типы (Bus fault, Usage fault, etc.) и обработки их по-отдельности; или если невозможно возбуждение соответствующего специфичного fault-а по иным причинам, то будет проводиться эскалация разных типов fault-ов в HF:
В архитектуре Cortex-M эскалация fault-а до Hard fault происходит в следующих случаях:
При возникновении fault-а в режиме обработки исключения:
Если возникло исключение (например, BusFault, UsageFault или MemManageFault) в контексте уже выполняющегося обработчика исключений и этот fault не может быть обработан корректно, то он эскалируется до HardFault. Это предотвращает рекурсивные вызовы исключений, которые могут привести к зависанию системы.
Когда в системе не разрешено определенное исключение:
Если произошло исключение типа BusFault, UsageFault или MemManageFault, но соответствующее ему исключение отключено (например, бит EN в регистре управления исключениями сброшен), то оно будет эскалировано до HardFault.
Ошибка стека (Stack overflow):
Если в результате переполнения стека или другого сбоя в работе стека происходит повреждение данных в стеке (например, некорректный возвратный адрес), это также может вызвать HardFault.
Доступ к защищенной памяти:
Если процессор пытается обратиться к области памяти, доступ к которой запрещен (например, из-за защиты памяти в системе), и этот доступ приводит к возникновению MemManageFault или BusFault, которые не могут быть обработаны корректно, то также происходит эскалация до HardFault.
Ошибка во время fetch команды (Prefetch):
Если произошел BusFault при извлечении команды из памяти, это автоматически эскалируется до HardFault, так как процессор не может продолжить выполнение программы без этой команды.
Ошибка из-за некорректной конфигурации MPU (Memory Protection Unit):
Если MPU неправильно сконфигурирован, это может привести к возникновению MemManageFault, который эскалируется до HardFault, если проблема не может быть разрешена.
Таким образом, эскалация до HardFault служит последним рубежом защиты, когда система сталкивается с критической ошибкой, которую не удается обработать штатными методами.
Ледокот писал(а):HardFault происходит при делении переменной типа long long int на константу типа int
Никаких проблем с делением у GCC нет. У меня несколько ПЛК крутятся очень давно, так там при вычислении времени цикла как раз делается такое деление.
С нюансами кода от Кейла под ARM не знаком, ибо не использую его. Коллеги выше верно указали на необходимость обработки исключения и выяснения того, какое на самом деле исключение возникает.