|
Не стартует STM32F405 |
|
|
|
Jun 25 2017, 19:29
|
Местный
  
Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778

|
Сделал новую ревизию платы, в части МК изменилось только, что BOOT1 теперь идет на EN вход внешнего DC/DC. Вроде бы не должно никак мешать, когда контроллер в сбросе или загрузчике BOOT1 притянут к земле резистором 10К.
Однако, теперь после загрузки кода по USART через встроенный загрузчик, происходит странное. Сразу после загрузки МК работает как должно. Если снять питание и снова подать, то поведение как у чистого МК со стертым флешем. Но если не дергая питания, перейти в загрузчик сделав BOOT0=1 и сброс а затем (ничего на загружая) вернуть BOOT0=0 и снова сделать сброс, то стартует прошитый ранее код из флеш. Один только сброс не помогает.
Похоже, на то, что я что-то недоиницилизирую, но и здесь я изменял только настройки тактирования под новую частоту кварца. И раньше такого не было никогда.
Пробовал зажигать светодиоды перед всей инициализацией, прямо в обработчике reset прерывания. Ничего не увидел, даже туда не доходит.
Не знаю на что подумать, что проверить.
Сообщение отредактировал amaora - Jun 26 2017, 12:24
|
|
|
|
|
Jun 26 2017, 12:31
|
Местный
  
Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778

|
Цитата(adnega @ Jun 25 2017, 23:40)  Может, попробовать как-то переформулировать вопрос и отказаться от нетехнической терминологии?
Будто вы описываете процесс загрузки кода в ОЗУ, и МК соответствующим образом себя ведет. Пока проблема не видна и не понятна. Код есть во flash, но при подаче питания он не запускается. Если зайти в загрузчик и выйти, то начинает запускаться, все становится нормально. Цитата Кажется, внутренний pull-down это особенность BOOT0, про BOOT1 никто не обещал... На обоих выводах есть резисторы на землю, по 10К. Цитата Ну не бывает чудес. " Если снять питание и снова подать…" ядро успевает зафиксировать "1" на Boot0 (это быстро - 4 такта SYSCLK): явно в обвеске "залипуха". Тогда МК был бы в загрузчике, а он в этом состоянии не отвечает по USART. Может быть не надо было в воздухе оставлять NJTRST? Как это может повлиять? Добавка: Похоже что-то программное, т.к. вижу, что запускается генерация на OSC_IN/OSC_OUT, если стереть flash то этого нет. Есть разница от того как собрать исходники, с -flto или без. Без не работает уже никак, что странно.
Сообщение отредактировал amaora - Jun 26 2017, 14:38
|
|
|
|
|
Jun 26 2017, 17:46
|
Местный
  
Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778

|
Посмотрел через отладку по SWD, что там происходит. В зависимости от того как собрать ломается в разных местах. Например с теми настройками, что я обычно использую (-O2 -flto), падаем в коде FreeRTOS, а именно в prvPortStartFirstTask. Код static void prvPortStartFirstTask( void ) { __asm volatile( " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ " ldr r0, [r0] \n" " ldr r0, [r0] \n" " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ " cpsie i \n" /* Globally enable interrupts. */ " cpsie f \n" " dsb \n" " isb \n" " svc 0 \n" /* System call to start first task. */ " nop \n" ); } Код Breakpoint 2, 0x08004158 in prvPortStartFirstTask.lto_priv.84 () at freertos/port.c:490 490 } (gdb) disassemble Dump of assembler code for function prvPortStartFirstTask.lto_priv.84: 0x08004154 <+0>: ldr r0, [pc, #476]; (0x8004334) 0x08004156 <+2>: ldr r0, [r0, #0] => 0x08004158 <+4>: ldr r0, [r0, #0] 0x0800415a <+6>: msr MSP, r0 0x0800415e <+10>: cpsie i 0x08004160 <+12>: cpsie f 0x08004162 <+14>: dsb sy 0x08004166 <+18>: isb sy 0x0800416a <+22>: svc 0 0x0800416c <+24>: nop End of assembler dump. (gdb) info registers r0 0xbfa91300 -1079438592 r1 0xf00000 15728640 ... То есть прочитали из SCB->VTOR какую-то непонятную 0xbfa91300, хотя там должно быть 0x8000000. Я даже вручную это туда записываю в коде инициализации, который к этому моменту уже выполнен. Начал разбираться, что там на самом деле пишется в тот VTOR, оказалось именно тот мусор вместо начала flash. Дальше заменил строку, Код //SCB->VTOR = (unsigned long) &ldSvectors; SCB->VTOR = (unsigned long) 0x80000000; запускаю и получаю, Код 0x0800be28 <+156>: ldr r4, [pc, #108]; (0x800be98 <halStart+268>) 0x0800be2a <+158>: add r2, pc 0x0800be2c <+160>: mov.w r6, #2147483648; 0x80000000 0x0800be30 <+164>: str r0, [r2, #0] 0x0800be32 <+166>: ldr.w r0, [r3, #136]; 0x88 0x0800be36 <+170>: ldr r2, [pc, #100]; (0x800be9c <halStart+272>) 0x0800be38 <+172>: orr.w r0, r0, #15728640; 0xf00000 => 0x0800be3c <+176>: str.w r0, [r3, #136]; 0x88 0x0800be40 <+180>: str r6, [r3, #8] 0x0800be42 <+182>: ldr r0, [r3, #12] 0x0800be44 <+184>: movw r6, #63743; 0xf8ff 0x0800be48 <+188>: ands r0, r6 0x0800be4a <+190>: orrs r2, r0 0x0800be4c <+192>: str r2, [r3, #12] 0x0800be4e <+194>: ldr r3, [r5, #0] 0x0800be50 <+196>: orr.w r3, r3, #240; 0xf0 0x0800be54 <+200>: str r3, [r5, #0] 0x0800be56 <+202>: ldr r3, [r1, #48]; 0x30 0x0800be58 <+204>: orr.w r3, r3, #7 0x0800be5c <+208>: str r3, [r1, #48]; 0x30 0x0800be5e <+210>: ldr r3, [r4, #0] 0x0800be60 <+212>: bic.w r3, r3, #64512; 0xfc00 0x0800be64 <+216>: orr.w r3, r3, #21504; 0x5400 0x0800be68 <+220>: str r3, [r4, #0] ---Type <return> to continue, or q <return> to quit---q Quit (gdb) si 155 SCB->VTOR = (unsigned long) 0x80000000; 1: *((int* ) 0xE000ED08) = 0 (gdb) si NVIC_SetPriorityGrouping () at hal/cmsis/core_cm4.h:1467 1467 reg_value = SCB->AIRCR; /* read old register configuration */ 1: *((int* ) 0xE000ED08) = -2147483648 (gdb) (gdb) info registers r0 0xf00000 15728640 r1 0x40023800 1073887232 r2 0x5fa0300 100270848 r3 0xe000ed00 -536810240 r4 0x40020400 1073873920 r5 0x40007000 1073770496 r6 0x80000000 -2147483648 r7 0x0 0 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x0 0 r12 0x0 0 sp 0x1000fff4 0x1000fff4 lr 0x800bf6f 0x800bf6f <ccmComp+8> pc 0x800be42 0x800be42 <halStart+182> xpsr 0x61000000 1627389952 fpscr 0x0 0 msp 0x1000fff4 0x1000fff4 psp 0x0 0x0 special 0x0 0 Как вот так может быть? Наверно уже устал, надо еще раз самому это перечитать. Да, все верно, только дальше продолжает падать, но теперь уже иначе, корректного указателя стека нет, стало сложнее. На этот раз где-то в pvPortMalloc, точнее определить сложно, надо глазами анализировать код и содержимое стека. Может это GCC, я его недавно обновлял на 6.3.0.
Сообщение отредактировал amaora - Jun 26 2017, 18:12
|
|
|
|
|
Jun 27 2017, 04:17
|
Частый гость
 
Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612

|
Цитата(amaora @ Jun 25 2017, 23:29)  Сделал новую ревизию платы, в части МК изменилось только, что BOOT1 теперь идет на EN вход внешнего DC/DC. Вроде бы не должно никак мешать, когда контроллер в сбросе или загрузчике BOOT1 притянут к земле резистором 10К. Может начать с самого начала? Предполагаю, что на старой ревизии платы всё работало. Осциллографом посмотреть сигнал BOOT1, Посмотреть документацию на DC/DC, нет ли там на входе ENABLE pull-up резистора, который пересиливает Ваши 10к. По симптомам очень похоже, что при сбросе через отладчик сигнал не успевает подняться от нулевого уровня из за емкости дорожки и всё работает. А при подаче питания BOOT1 уже равен 1.
|
|
|
|
|
Jun 27 2017, 07:25
|

Знающий
   
Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663

|
Цитата(amiller @ Jun 27 2017, 08:17)  Может начать с самого начала? Не надо… "Во всём виноваты программисты"  а у ТС всё в порядке.
Сообщение отредактировал Obam - Jun 27 2017, 07:25
--------------------
Пролетарий умственного труда.
|
|
|
|
|
Jun 28 2017, 16:48
|
Местный
  
Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778

|
Перешел на GCC 7.1.0, попробовал разные варианты оптимизации, ничего не меняется. Сейчас постоянно падает при запуске из GDB. В пределах одной сборки падает стабильно в одном месте. Похоже неполадки в freertos/heap_4.c, pvPortMalloc возвращает некорректные адреса. Но как здесь вход в загрузчик мог повлиять непонятно. Все очень странно. Да и от чего бы этому коду сломаться. Код extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; ... static void prvHeapInit( void ) { BlockLink_t *pxFirstFreeBlock; uint8_t *pucAlignedHeap; size_t uxAddress; size_t xTotalHeapSize = configTOTAL_HEAP_SIZE;
/* Ensure the heap starts on a correctly aligned boundary. */ uxAddress = ( size_t ) ucHeap;
if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) { uxAddress += ( portBYTE_ALIGNMENT - 1 ); uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; } ... Как можно здесь прочитать в uxAddress нулевое значение? Но получается именно так если верить GDB, с этого начинаются проблемы.
|
|
|
|
|
Jun 29 2017, 07:37
|

Частый гость
 
Группа: Свой
Сообщений: 167
Регистрация: 25-12-09
Из: Минск
Пользователь №: 54 460

|
Была подобная ситуация, только такое поведение наблюдалось когда BOOT1 был затянут в 1 (system memory), но ПО запускал через отладку, причина была в срабатывании необрабатываемого прерывании.
ИМХО, причина не в компиляторе, я бы на Вашем месте залогировал все обработчики прерываний, даже те которые не используете, и те которые не маскируемые.
Возможно Вы эти этапы уже прошли, но я бы прошелся по следующим шагам: 1. Временно выключил основной функционал прошивки, оставить только светодиодную индикацию, чтобы понимать, что ПО работает, частотой моргания диода подтвердить рабочую частоту. Если на плате нет диода, дергаем какой-либо пин, контролируем его каким либо осцилоскопом. 2. Зашить и проверить работоспособность ПО на первом устройстве, рабочем устройстве! 3. Зашить второе устройство убедиться в НЕ работоспособности. 3.1 Если вдруг случайно заработает, добавляем пошагово необходимый функционал, ищем причину. 4. Если Вы пишите что добавлен только резистор, чтобы убедиться что проблема в нем, демонтировав его, порезать линию управления EN (DC\DC) 4.1 Резистора нет, но ПО НЕ грузится искать другие отличия в схеме. 5. Без резистора ПО грузится? Снять и опубликовать на форуме осциллограммы сигналов: питание, reset, boot1.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|