kpv 15 13 августа Опубликовано 13 августа · Жалоба смотреть в сторону DWT Data Watchpoint and Trace при старте OpenOCD строка наподобие следующей есть?: Info : cpu: hardware has 6 breakpoints, 4 watchpoints Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
koluna 0 13 августа Опубликовано 13 августа · Жалоба On 8/13/2024 at 3:01 PM, kpv said: смотреть в сторону DWT Data Watchpoint and Trace при старте OpenOCD строка наподобие следующей есть?: Info : cpu: hardware has 6 breakpoints, 4 watchpoints При запуске сервера: koluna@lev:~$ openocd -f interface/jlink.cfg -c "transport select swd" -f target/stm32f1x.cfg Open On-Chip Debugger 0.12.0-rc1 Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html swd Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections Info : J-Link ARM V8 compiled Nov 14 2012 22:34:52 Info : Hardware version: 8.00 Info : VTarget = 3.313 V Info : clock speed 1000 kHz Info : SWD DPIDR 0x1ba01477 Info : [stm32f1x.cpu] Cortex-M3 r1p1 processor detected Info : [stm32f1x.cpu] target has 6 breakpoints, 4 watchpoints Info : starting gdb server for stm32f1x.cpu on 3333 Info : Listening on port 3333 for gdb connections Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 13 августа Опубликовано 13 августа · Жалоба 50 minutes ago, koluna said: koluna@lev:~$ openocd -f interface/jlink.cfg -c "transport select swd" -f target/stm32f1x.cfg Если вы так в консоли и работаете, то вам сюда: https://openocd.org/doc/html/General-Commands.html раздел "15.5 Breakpoint and Watchpoint commands". Но вроде б сейчас все IDE оборудованы соответствующими кнопками?.. Но, по сути, причину ошибки вам уже подсказали - переполнение приёмного буфера. Простейшее (и необходимое!) решение - условие (принято == длина_пакета) меняем на (принято >= длина пакета). И, кстати, банальный вопрос: поле "длина пакета" в заголовке - это длина данных или длина всего пакета вместе с заголовком? Также, как верно заметил jcxz, при таймаутах весь приём напрочь ломается. Если в линии по какой-то причине пропал один байт, вы попадёте в условие проверки таймаута по заголовку следующего пакета, и сразу же пропускаете первый байт заголовка. Хорошо ещё, если пропустите пакет целиком, а не найдёте магические два байта в середине данных... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 13 августа Опубликовано 13 августа · Жалоба 3 часа назад, koluna сказал: Делал так, не выходит из исключения и ведет себя как-то странно... как бы подвисает чтоли... Смотрите содержимое указателя стека и ячеек по адресам, куда указывает указатель - есть ли там адрес точки возврата в нужном месте? И если нет - куда он делся, ведь только что должен был сохраниться при входе в исключение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
koluna 0 13 августа Опубликовано 13 августа · Жалоба On 8/13/2024 at 4:15 PM, esaulenka said: Но вроде б сейчас все IDE оборудованы соответствующими кнопками?.. Code::Blocks у меня. Я не разбирался как к нему отладчик прикручивать. Крайне редко им пользуюсь, обходилось всегда. On 8/13/2024 at 4:15 PM, esaulenka said: Простейшее (и необходимое!) решение - условие (принято == длина_пакета) меняем на (принято >= длина пакета). Да, я пробовал. Не помогает... On 8/13/2024 at 4:15 PM, esaulenka said: И, кстати, банальный вопрос: поле "длина пакета" в заголовке - это длина данных или длина всего пакета вместе с заголовком? Длина всего пакета полностью. On 8/13/2024 at 4:15 PM, esaulenka said: Также, как верно заметил jcxz, при таймаутах весь приём напрочь ломается. Если в линии по какой-то причине пропал один байт, вы попадёте в условие проверки таймаута по заголовку следующего пакета, и сразу же пропускаете первый байт заголовка. Хорошо ещё, если пропустите пакет целиком, а не найдёте магические два байта в середине данных... Да, спасибо, поправлю. Но если бы был таймаут, то мой программный дебаг сообщил бы об этом... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 86 13 августа Опубликовано 13 августа · Жалоба В момент ошибки значение регистра BFAR - какое? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 13 августа Опубликовано 13 августа · Жалоба 1 minute ago, EdgeAligned said: В момент ошибки значение регистра BFAR - какое? Так он говорил уже - сразу за концом памяти. 99% вероятности, что это переполнение массива. 9 minutes ago, koluna said: Да, я пробовал. Не помогает... Я внимательно посмотрел на ваш отладчик (gdb) backtrace #0 HardFault_Handler () at ./src/main.c:116 #1 <signal handler called> #2 0x08001682 in exchTXEHandler () at ./src/libs/exchange/exchange.c:341 #3 <signal handler called> #4 dbgout (level=level@entry=7, format=0x80017c7 <EXCH_process+266> "H\377\367\004\370\262#+\200\252\347\201N") at ./src/libs/dbg/dbg.c:19 #5 0x080017c6 in waitForRequest (exchRes=0x20000f20 <exchRes.7247>, pt=0x20000f2c <ptChild.7246>) at ./src/libs/exchange/exchange.c:175 #6 EXCH_process (pt=0x20001fec) at ./src/libs/exchange/exchange.c:461 давайте читать с конца: - exchange.c, 175 - это какая строчка в приведённом вами waitForRequest() ? - dbgout() как устроен? С exchXXXX() никак не связан (другой уарт, полностью независимый набор флажков и т.д.) ? - exchTXEHandler() что из себя представляет? Что у него в переменных в момент хардфолта? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 86 13 августа Опубликовано 13 августа · Жалоба А теперь смотрим инструкицю, вызвавшую это переполнение. Её адрес - указывается в PC, как написано в мануале. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
koluna 0 13 августа Опубликовано 13 августа · Жалоба On 8/13/2024 at 5:07 PM, esaulenka said: - exchange.c, 175 - это какая строчка в приведённом вами waitForRequest() ? Строка: dbgout(LOG_DEBUG, "[%s()] Wait for packet... ", __func__); Код поменял, сейчас немного по-другому, но тоже самое: (gdb) backtrace #0 HardFault_Handler () at ./src/main.c:139 #1 <signal handler called> #2 0x0800165e in exchTXEHandler () at ./src/libs/exchange/exchange.c:361 #3 <signal handler called> #4 dbgout (level=level@entry=7, format=0x80017cb <EXCH_process+278> "H\377\367\222\370\276#+\200\245\347PN") at ./src/libs/dbg/dbg.c:19 #5 0x080017ca in waitForRequest (exchRes=0x20000f00 <exchRes.7248>, pt=0x20000f0c <ptChild.7247>) at ./src/libs/exchange/exchange.c:187 #6 EXCH_process (pt=0x20001fec) at ./src/libs/exchange/exchange.c:483 #7 0xf4f3f7fc in ?? () Backtrace stopped: previous frame identical to this frame (corrupt stack?) On 8/13/2024 at 5:07 PM, esaulenka said: - dbgout() как устроен? С exchXXXX() никак не связан (другой уарт, полностью независимый набор флажков и т.д.) ? void dbgout(const int32_t level, const char* format, ...) { UNUSED(level); va_list args; va_start(args, format); xvprintf(format, args); va_end(args); } Используется библиотека xprintf, переопределил для нее функцию вывода байта в USART1. Интерфейс, на котором сбои - USART2. Никак они не связаны. On 8/13/2024 at 5:07 PM, esaulenka said: exchTXEHandler() что из себя представляет? Что у него в переменных в момент хардфолта? По сути - в нем проблема или где-то рядом... Передачу запускаю следующей функцией: static PT_THREAD(sendReply(PT* pt)) { PT_BEGIN(pt); txCnt = 0; txComplete = false; exchTxeEnable(); // Запускаем передачу. dbgout(LOG_DEBUG, "[%s()] Send packet %u bytes...\n", __func__, txSize); static bool tmp; do { PT_YIELD(pt); ENTER_CRITICAL(); tmp = txComplete; EXIT_CRITICAL(); } while(!tmp); dbgout(LOG_DEBUG, "[%s()] Send packet was completed.\n", __func__); txComplete = false; dbgout(LOG_DEBUG, "[%s()] Transaction trs: %u\n", __func__, transId); transId++; PT_END(pt); } В txSize размер пакета для передачи. Цикл с ожиданием для эксперимента. Ранее было просто PT_WAIT_UNTIL(pt, txComplete); Функция, вызываемая из обработчика (сейчас без проверки на переполнение): void exchTXEHandler(void) { exchWriteByte(exchBuff[txCnt]); txCnt++; if(txCnt == txSize) { exchTxeDisable(); txComplete = true; } } Вывод отладчика: (gdb) up 2 #2 0x0800165e in exchTXEHandler () at ./src/libs/exchange/exchange.c:361 361 exchWriteByte(exchBuff[txCnt]); (gdb) list 356 // } 357 //} 358 359 void exchTXEHandler(void) 360 { 361 exchWriteByte(exchBuff[txCnt]); 362 txCnt++; 363 364 if(txCnt == txSize) 365 { (gdb) frame #2 0x0800165e in exchTXEHandler () at ./src/libs/exchange/exchange.c:361 361 exchWriteByte(exchBuff[txCnt]); (gdb) info frame Stack level 2, frame at 0x20001f8c: pc = 0x800165e in exchTXEHandler (./src/libs/exchange/exchange.c:361); saved pc = 0xfffffff9 called by frame at 0x20001fac, caller of frame at 0x20001f7c source language c. Arglist at 0x20001f7c, args: Locals at 0x20001f7c, Previous frame's sp is 0x20001f8c Saved registers: r4 at 0x20001f7c, r5 at 0x20001f80, r6 at 0x20001f84, lr at 0x20001f88 On 8/13/2024 at 4:59 PM, EdgeAligned said: В момент ошибки значение регистра BFAR - какое? Да, биты BFARVALID и PRECIS ERR установлены. Да, BFAR содержит корректный адрес: этот адрес 20002000 - RAM. Видимо, что-то оттуда попыталось прочитаться или записаться. Я выводил своим дебагом, там много кода... значение будет некорректным, наверное. Только в отладчике смотреть? Поставил брекпойнт на HardFault_Handler(). Вот информация при остановке: Breakpoint 1, HardFault_Handler () at ./src/main.c:126 126 dbgout(LOG_DEBUG, "\n[%s()] !!! System fault !!!\n", __func__); (gdb) list 121 // LR_read = *((uint32_t*) ((uint32_t) MSP_read + 5 * 4)); 122 // PC_read = *((uint32_t*) ((uint32_t) MSP_read + 6 * 4)); 123 124 125 126 dbgout(LOG_DEBUG, "\n[%s()] !!! System fault !!!\n", __func__); 127 dbgout(LOG_DEBUG, "[%s()] HFSR=x%08X\n", __func__, SCB->HFSR); 128 dbgout(LOG_DEBUG, "[%s()] CFSR=x%08X\n", __func__, SCB->CFSR); 129 dbgout(LOG_DEBUG, "[%s()] BFAR=x%08X\n", __func__, SCB->BFAR); 130 (gdb) info frame Stack level 0, frame at 0x20001f5c: pc = 0x8000354 in HardFault_Handler (./src/main.c:126); saved pc = 0xfffffff1 called by frame at 0x20001f7c source language c. Arglist at 0x20001f5c, args: Locals at 0x20001f5c, Previous frame's sp is 0x20001f5c pc = 0x8000354 - по этому адресу сбойная инструкция? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
koluna 0 13 августа Опубликовано 13 августа · Жалоба Посмотрел листинг, не знаю, там черт ногу сломи - как интерпретировать... Как я понял, строка 0354 4FEA5000 lsr r0, r0, #1? 110:./src/libs/exchange/exchange.c **** if (temp == 0) 1563 .loc 1 110 36 is_stmt 0 view .LVU502 1564 0340 80EA0201 eor r1, r0, r2 111:./src/libs/exchange/exchange.c **** { 1565 .loc 1 111 16 view .LVU503 1566 0344 C907 lsls r1, r1, #31 1567 0346 03F1FF33 add r3, r3, #-1 1568 .LVL87: 119:./src/libs/exchange/exchange.c **** } 1569 .loc 1 119 22 view .LVU504 1570 034a 48BF it mi 1571 034c 80F48C70 eormi r0, r0, #280 1572 .LVL88: 119:./src/libs/exchange/exchange.c **** } 1573 .loc 1 119 22 view .LVU505 1574 .LBE126: 108:./src/libs/exchange/exchange.c **** { 1575 .loc 1 108 9 view .LVU506 1576 0350 13F0FF03 ands r3, r3, #255 1577 .LBB127: 119:./src/libs/exchange/exchange.c **** } 1578 .loc 1 119 22 view .LVU507 1579 0354 4FEA5000 lsr r0, r0, #1 1580 .LVL89: 121:./src/libs/exchange/exchange.c **** } 1581 .loc 1 121 13 is_stmt 1 view .LVU508 121:./src/libs/exchange/exchange.c **** } 1582 .loc 1 121 18 is_stmt 0 view .LVU509 1583 0358 4FEA5202 lsr r2, r2, #1 1584 .LVL90: 121:./src/libs/exchange/exchange.c **** } 1585 .loc 1 121 18 view .LVU510 1586 .LBE127: 108:./src/libs/exchange/exchange.c **** { 1587 .loc 1 108 49 is_stmt 1 view .LVU511 108:./src/libs/exchange/exchange.c **** { 1588 .loc 1 108 35 view .LVU512 108:./src/libs/exchange/exchange.c **** { 1589 .loc 1 108 9 is_stmt 0 view .LVU513 Как объяснить ситуацию, когда после перепрошивки МК Hard Fault всегда возникает сразу? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 86 13 августа Опубликовано 13 августа · Жалоба 0x8000354 - это адрес обработчика, скорее всего HardFault Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 45 13 августа Опубликовано 13 августа · Жалоба 21 minutes ago, koluna said: Только в отладчике смотреть? То, что тут написано по вытаскиванию информации из стэка и регистров, отладчик вытаскивает автоматом и чуть ли не в физию тебе тычет адресом сбойной команды и её операндами, причём прям в программе и дизасме встаёт на строки со сбойной командой. После такого причина ошибки в большинстве случаев очевидна, или понятно, куда рыть. Так сейчас работает gdb в Кубе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 86 13 августа Опубликовано 13 августа · Жалоба 6 минут назад, koluna сказал: когда после перепрошивки МК Hard Fault всегда возникает сразу? Ура, теперь вы сломали код так, что он сбоит всегда, а не время от времени 🙂 Это уже прогресс. Теперь осталось вспомнить, что изменили в коде, что привело к такому результату? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
koluna 0 13 августа Опубликовано 13 августа · Жалоба On 8/13/2024 at 5:58 PM, EdgeAligned said: Ура, теперь вы сломали код так, что он сбоит всегда, а не время от времени 🙂 Это уже прогресс. Теперь осталось вспомнить, что изменили в коде, что привело к такому результату? Оно давно так уже... наверное, изначально даже... просто не сразу заметил и сообщил об этом... On 8/13/2024 at 5:56 PM, tonyk_av said: То, что тут написано по вытаскиванию информации из стэка и регистров, отладчик вытаскивает автоматом и чуть ли не в физию тебе тычет адресом сбойной команды и её операндами, причём прям в программе и дизасме встаёт на строки со сбойной командой. После такого причина ошибки в большинстве случаев очевидна, или понятно, куда рыть. Так сейчас работает gdb в Кубе. Все бы ничего, наверное, но я через CLI отлаживаю и у меня пару вопросов: (gdb) backtrace #0 HardFault_Handler () at ./src/main.c:139 #1 <signal handler called> #2 0x0800165e in exchTXEHandler () at ./src/libs/exchange/exchange.c:361 #3 <signal handler called> #4 dbgout (level=level@entry=7, format=0x80017cb <EXCH_process+278> "H\377\367\222\370\276#+\200\245\347PN") at ./src/libs/dbg/dbg.c:19 #5 0x080017ca in waitForRequest (exchRes=0x20000f00 <exchRes.7248>, pt=0x20000f0c <ptChild.7247>) at ./src/libs/exchange/exchange.c:187 #6 EXCH_process (pt=0x20001fec) at ./src/libs/exchange/exchange.c:483 #7 0xf4f3f7fc in ?? () Backtrace stopped: previous frame identical to this frame (corrupt stack?) Что значат строки <signal handler called>. Видимо, строка Backtrace stopped: previous frame identical to this frame (corrupt stack?) говорит о том, что что-то пошло не так? Ранее, когда пользовался отладчиком, мне хватало информации, чтобы быстро найти ошибку. А сейчас слишком много нового и непонятного... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 13 августа Опубликовано 13 августа · Жалоба 25 минут назад, koluna сказал: Ранее, когда пользовался отладчиком, мне хватало информации, чтобы быстро найти ошибку. А сейчас слишком много нового и непонятного... Вроде бы вся информация и ответы "где баг" вам уже дана. Неужто до сих пор не исправили?? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться