AHTOXA 18 28 февраля, 2014 Опубликовано 28 февраля, 2014 · Жалоба Вот только не надо передёргивать! Тут есть история и всегда можно посмотреть о чём и когда шла речь. Во-первых - вызов перегруженного члена класса не может осуществляться BL, а только командами BLX; BX; LDR PC, ...; (возможно ещё TBB/TBH) - почитайте последние сообщения тут, чтобы понять почему. Ох, ну что же вы такой упёртый-то. Ну давайте почитаем. Вот исходное сообщение, с которого всё началось (выделение жирным - моё): Выпадаю в Hard Fault Exception. описал обработчик, получил вывод [skip] LR = 0x8002c09 PC = 0x20001498 Вот мой ответ: Посмотрите команду, которая находится перед 0x8002c08, возможно дело в ней. juvf посмотрел: перед 0x8002c09 такой код LDR R1, [R1] LDR R1,[R1, #0x8] BLX R1 CMP R0,#0 [skip] падает в перегруженном операторе -- if(--(*(MyClass*)p) ) { } Видите, всё именно так, как я описал. В регистре LR - адрес, следующий после адреса проблемного вызова. То есть, по сути, мы уже нашли место возникновения проблемы: Команда BLX R1 должна прыгать на код вашего перегруженного оператора, а вместо этого прыгает в ОЗУ. Да, похоже, что память портится. И тут, как чёрт из табакерки, выскочили вы, и начали умничать. Я бы уже давно перестал отвечать на ваши петушиные наскоки, но всё надеялся, что вы перечитаете тему, переосмыслите и признаете свою неправоту. Однако теперь вижу, что это бесполезно. Думаю, что в этом ответе я предельно чётко подытожил описание проблемы и её решение. Надеюсь, это поможет кому-то, кто будет читать эту тему потом. Что касаемо дальнейшей дискуссии с вами, то я не вижу в ней никакого смысла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 28 февраля, 2014 Опубликовано 28 февраля, 2014 · Жалоба Я с вами тоже :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 18 28 февраля, 2014 Опубликовано 28 февраля, 2014 · Жалоба Давайте жить дружно :beer: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 18 30 марта, 2017 Опубликовано 30 марта, 2017 · Жалоба stm32L052 падает в HF пытаюсь сделать обработчик HF и вывести содержимое регистров. вставляю в обработчик asm volatile ( "TST LR, #4 \n " "ITE EQ \n" "MRSEQ R0, MSP \n" "MRSNE R0, PSP \n" "B hardfault_handler " ); - не компилиться. пишет Updating build tree... stm32l0xx_it.c Error[Og006]: Error in inline assembly: "Error[401]: Operand syntax error" ...\Src\stm32l0xx_it.c 107 Error[Og006]: Error in inline assembly: "Error[438]: This instruction is not available in the selected cpu/core" ...\Src\stm32l0xx_it.c 108 Error while running C/C++ Compiler на строчку "TST LR, #4" и "ITE EQ". Погуглив гдето на форумах было задето, что возможно это из-за того, что препроцессор в режиме Thumb. Но как его на ARM переключить? Собираю в ИАРе сгенерированный проект из куба. в настройках выбран Thumb и выбор режима ARM или Thumb заблокирован. Как можно отловить HF? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 30 марта, 2017 Опубликовано 30 марта, 2017 · Жалоба Error[Og006]: Error in inline assembly: "Error[401]: Operand syntax error" ...\Src\stm32l0xx_it.c 107 Error[Og006]: Error in inline assembly: "Error[438]: This instruction is not available in the selected cpu/core" ...\Src\stm32l0xx_it.c 108 Это Cortex-M0(+)/Cortex-M1. У них нет инструкции ITE. Для них надо вот так: void HardFault_Handler(void) { asm volatile ( " MOV R0, LR \n" " CMP R0, #4 \n" " BNE hf_psp%= \n" "hf_msp%=: \n" " MRS R0, MSP \n" " B hard_fault_handler \n" "hf_psp%=: \n" " MRS R0, PSP \n" " B hard_fault_handler \n" : // no output : [param]"r" (0) // dummy param : // no clobbers ); } (Это для gcc, для IAR-а сами подправьте). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 30 марта, 2017 Опубликовано 30 марта, 2017 · Жалоба препроцессор в режиме Thumb. Препроцессор только в одном режиме может работать - в режиме си. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 18 31 марта, 2017 Опубликовано 31 марта, 2017 · Жалоба Препроцессор только в одном режиме может работать - в режиме си. опечатался, процессор Это Cortex-M0(+)/Cortex-M1. У них нет инструкции ITE.Спасибо АНТОХА!!! В очередной раз выручил. для иара (кубовски проект) в файле stm32l0xx_it.c нужно в юзеркод вставить так /* USER CODE BEGIN 0 */ void hard_fault_handler (unsigned int * hardfault_args) { unsigned int stacked_r0; unsigned int stacked_r1; unsigned int stacked_r2; unsigned int stacked_r3; unsigned int stacked_r12; unsigned int stacked_lr; unsigned int stacked_pc; unsigned int stacked_psr; stacked_r0 = ((unsigned long) hardfault_args[0]); stacked_r1 = ((unsigned long) hardfault_args[1]); stacked_r2 = ((unsigned long) hardfault_args[2]); stacked_r3 = ((unsigned long) hardfault_args[3]); stacked_r12 = ((unsigned long) hardfault_args[4]); stacked_lr = ((unsigned long) hardfault_args[5]); stacked_pc = ((unsigned long) hardfault_args[6]); stacked_psr = ((unsigned long) hardfault_args[7]); printf ("[Hard fault handler]\n"); printf ("R0 = 0x%x\n", stacked_r0); printf ("R1 = 0x%x\n", stacked_r1); printf ("R2 = 0x%x\n", stacked_r2); printf ("R3 = 0x%x\n", stacked_r3); printf ("R12 = 0x%x\n", stacked_r12); printf ("LR = 0x%x\n", stacked_lr); printf ("PC = 0x%x\n", stacked_pc); printf ("PSR = 0x%x\n\n", stacked_psr); printf ("Execute code from 0x%x\n\n", stacked_pc); printf ("See command befor 0x%x\n\n", stacked_lr); for(;;); } /* USER CODE END 0 */ ... void HardFault_Handler(void) { /* USER CODE BEGIN HardFault_IRQn 0 */ asm volatile ( " MOV R0, LR \n" " CMP R0, #4 \n" " BNE hf_psp \n" "hf_msp: \n" " MRS R0, MSP \n" " B hard_fault_handler \n" "hf_psp: \n" " MRS R0, PSP \n" " B hard_fault_handler \n" : // no output : [param]"r" (0) // dummy param : // no clobbers ); /* USER CODE END HardFault_IRQn 0 */ while (1) { } /* USER CODE BEGIN HardFault_IRQn 1 */ /* USER CODE END HardFault_IRQn 1 */ } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 31 марта, 2017 Опубликовано 31 марта, 2017 · Жалоба А что, на брейкпойнте в точке входа в HF и под JTAGом, нельзя посмотреть содержимое регистров без портянки из printf-ов? Просто интересуюсь… Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 31 марта, 2017 Опубликовано 31 марта, 2017 · Жалоба Можно. Только, когда ошибка появляется в рабочем приборе, вдалеке от отладчика, вот тогда нужно пересылать информацию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 31 марта, 2017 Опубликовано 31 марта, 2017 · Жалоба "…в рабочем приборе, вдалеке от отладчика…" Тогда тут то, чем зебра заканчивается… дистанционно добавлять в прошивку диагностику HF :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 18 31 марта, 2017 Опубликовано 31 марта, 2017 · Жалоба А что, на брейкпойнте в точке входа в HF и под JTAGом, нельзя посмотреть содержимое регистров без портянки из printf-ов? Просто интересуюсь… По мойму нельзя. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 31 марта, 2017 Опубликовано 31 марта, 2017 · Жалоба "…в рабочем приборе, вдалеке от отладчика…" Тогда тут то, чем зебра заканчивается… дистанционно добавлять в прошивку диагностику HF :( Программа выдала симптомы, а диагноз выполняет и лечение назначает программист, глядя в исходник сотворенного. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Шаманъ 1 31 марта, 2017 Опубликовано 31 марта, 2017 · Жалоба По мойму нельзя. Можно. Более того есть смысл оформить обработчик так: void Default_Handler(void) { volatile int i = 1; while (i) { } } Тогда можно переменную i в отладчике поменять на 0 и пройтись до выхода из HardFault, выйдет как раз в место его возникновения, бывает очень удобно. Можно конечно адрес из стека вытащить, но так проще, удобней, нагляднее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 31 марта, 2017 Опубликовано 31 марта, 2017 · Жалоба Можно. Только, когда ошибка появляется в рабочем приборе, вдалеке от отладчика, вот тогда нужно пересылать информацию. Все HF следует отлавливать еще на этапе отладки и прогона на месте, иначе грош-цена такому коду. А вот для фиксации различных событий и т. п. следует использовать самописный или готовый журнал событий, который писать на внешнюю или внутр. флэшку. В этом случае можно спокойно проанализировать записи в журнале за некий период работы, просто переслав разработчику соотв. файл журнала событий. Для этого никуда ездить не нужно. Если есть доступ в сеть, то можно научить девайс писать журнал сразу наружу, да хоть на "облако" )) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 31 марта, 2017 Опубликовано 31 марта, 2017 · Жалоба Тогда можно переменную i в отладчике поменять на 0 и пройтись до выхода из HardFault, выйдет как раз в место его возникновения, бывает очень удобно. Можно конечно адрес из стека вытащить, но так проще, удобней, нагляднее. У Cortex есть неточные ошибки с памятью (Imprecise Bus Fault). Так Вы их место не найдёте. А через регистры - найдёте. Да и очень неудобно каждый раз вспоминать где какой стек, лучше иметь готовый код. Не зря же даже в винде подобный обработчик сделали с регистрами и стеком (синий экран). Вот у меня как раз подобный для Cortex есть ;) Все HF следует отлавливать еще на этапе отладки и прогона на месте, иначе грош-цена такому коду. А вот для фиксации различных событий и т. п. следует использовать самописный или готовый журнал событий, который писать на внешнюю или внутр. флэшку. Это конечно всё хорошо и правильно. Но на практике почему-то случаются такие ошибки (в том числе и HF), которые проявляются почему-то только у заказчика :laughing: Вот тут-то фиксация в журнал спасает (а особенно - в энергонезависимый). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться