Перейти к содержанию
    

Сделал новую ревизию платы, в части МК изменилось только, что BOOT1 теперь идет на EN вход внешнего DC/DC. Вроде бы не должно никак мешать, когда контроллер в сбросе или загрузчике BOOT1 притянут к земле резистором 10К.

 

Однако, теперь после загрузки кода по USART через встроенный загрузчик, происходит странное. Сразу после загрузки МК работает как должно. Если снять питание и снова подать, то поведение как у чистого МК со стертым флешем. Но если не дергая питания, перейти в загрузчик сделав BOOT0=1 и сброс а затем (ничего на загружая) вернуть BOOT0=0 и снова сделать сброс, то стартует прошитый ранее код из флеш. Один только сброс не помогает.

 

Похоже, на то, что я что-то недоиницилизирую, но и здесь я изменял только настройки тактирования под новую частоту кварца. И раньше такого не было никогда.

 

Пробовал зажигать светодиоды перед всей инициализацией, прямо в обработчике reset прерывания. Ничего не увидел, даже туда не доходит.

 

Не знаю на что подумать, что проверить.

Изменено пользователем amaora

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не знаю на что подумать, что проверить.

Может, попробовать как-то переформулировать вопрос и отказаться от нетехнической терминологии?

 

Будто вы описываете процесс загрузки кода в ОЗУ, и МК соответствующим образом себя ведет.

Пока проблема не видна и не понятна.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кажется, внутренний pull-down это особенность BOOT0, про BOOT1 никто не обещал...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну не бывает чудес.

" Если снять питание и снова подать…" ядро успевает зафиксировать "1" на Boot0 (это быстро - 4 такта SYSCLK): явно в обвеске "залипуха".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может, попробовать как-то переформулировать вопрос и отказаться от нетехнической терминологии?

 

Будто вы описываете процесс загрузки кода в ОЗУ, и МК соответствующим образом себя ведет.

Пока проблема не видна и не понятна.

 

Код есть во flash, но при подаче питания он не запускается. Если зайти в загрузчик и выйти, то начинает запускаться, все становится нормально.

 

Кажется, внутренний pull-down это особенность BOOT0, про BOOT1 никто не обещал...

 

На обоих выводах есть резисторы на землю, по 10К.

 

Ну не бывает чудес.

" Если снять питание и снова подать…" ядро успевает зафиксировать "1" на Boot0 (это быстро - 4 такта SYSCLK): явно в обвеске "залипуха".

 

Тогда МК был бы в загрузчике, а он в этом состоянии не отвечает по USART.

 

Может быть не надо было в воздухе оставлять NJTRST? Как это может повлиять?

 

Добавка: Похоже что-то программное, т.к. вижу, что запускается генерация на OSC_IN/OSC_OUT, если стереть flash то этого нет. Есть разница от того как собрать исходники, с -flto или без. Без не работает уже никак, что странно.

Изменено пользователем amaora

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотрел через отладку по 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сделал новую ревизию платы, в части МК изменилось только, что BOOT1 теперь идет на EN вход внешнего DC/DC. Вроде бы не должно никак мешать, когда контроллер в сбросе или загрузчике BOOT1 притянут к земле резистором 10К.

Может начать с самого начала?

Предполагаю, что на старой ревизии платы всё работало.

Осциллографом посмотреть сигнал BOOT1, Посмотреть документацию на DC/DC, нет ли там на входе ENABLE pull-up резистора, который пересиливает Ваши 10к.

По симптомам очень похоже, что при сбросе через отладчик сигнал не успевает подняться от нулевого уровня из за емкости дорожки и всё работает. А при подаче питания BOOT1 уже равен 1.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может начать с самого начала?

Не надо…

"Во всём виноваты программисты" ;) а у ТС всё в порядке.

Изменено пользователем Obam

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Перешел на 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, с этого начинаются проблемы.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Была подобная ситуация, только такое поведение наблюдалось когда BOOT1 был затянут в 1 (system memory), но ПО запускал через отладку, причина была в срабатывании необрабатываемого прерывании.

 

ИМХО, причина не в компиляторе, я бы на Вашем месте залогировал все обработчики прерываний, даже те которые не используете, и те которые не маскируемые.

 

Возможно Вы эти этапы уже прошли, но я бы прошелся по следующим шагам:

1. Временно выключил основной функционал прошивки, оставить только светодиодную индикацию, чтобы понимать, что ПО работает, частотой моргания диода подтвердить рабочую частоту. Если на плате нет диода, дергаем какой-либо пин, контролируем его каким либо осцилоскопом.

2. Зашить и проверить работоспособность ПО на первом устройстве, рабочем устройстве!

3. Зашить второе устройство убедиться в НЕ работоспособности.

3.1 Если вдруг случайно заработает, добавляем пошагово необходимый функционал, ищем причину.

4. Если Вы пишите что добавлен только резистор, чтобы убедиться что проблема в нем, демонтировав его, порезать линию управления EN (DC\DC)

4.1 Резистора нет, но ПО НЕ грузится искать другие отличия в схеме.

5. Без резистора ПО грузится? Снять и опубликовать на форуме осциллограммы сигналов: питание, reset, boot1.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В любом электротехникуме есть предмет на первом курсе - Поиск неисправностей в электрических устройствах. Записаться и прослушать его. Или посмотреть на youtub'e.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Причина все таки в компиляторе, точнее в моем его непонимании. Новые версии зачем-то собирают PIC код, хотя я указываю -static. Появились новые секции, .got и .got.plt, а я их не обработал в ld скрипте. Была не инициализированная память.

 

Но зачем это все? Не понимаю, я же не shared object собираю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

amaora, Вы их где берёте?

Вроде б на launchpad'е всё тихо и спокойно (а 7-й версии нет совсем).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...