сборка stm32 с нуля успешно прошивает, но не запускается на плате

Я новичок в создании проектов с нуля с помощью mcu. Я взял старый файл проекта, который успешно работает в среде сборки eclipse/gdb, где IDE делает всю сборку за меня, и попытался реализовать свою собственную сборку с помощью open-ocd и цепочки инструментов: arm-none-eabi. Мне удалось прошить устройство, однако плата не запускает код. Я надеялся, что у меня может отсутствовать какой-то очевидный важный файл, но я не пришел к такому выводу.

Больше всего меня беспокоит то, что у меня нет правильной настройки для моего файла start_up.c или файла linker.ld, хотя я не нашел причин так полагать. Я использую доску обнаружения stm32L476. Вот ссылка на техпаспорт, если кому-то интересно: 32bit-mcus-stmicroelectronics.pdf" rel="nofollow noreferrer">https://www.st.com/resource/en/reference_manual/dm00083560-stm32l47xxx-stm32l48xxx-stm32l49xxx-and-stm32l4axxx-advanced-armbased-32bit-mcus -stmicroelectronics.pdf

Мои источники моей проблемы находятся здесь, в github: https://github.com/landonbr/stm32-fun< /а>


person Landon Brown    schedule 24.12.2020    source источник
comment
Никто не хочет лезть в ваш гитхаб, чтобы ответить на вопрос. Разместите соответствующий код прямо здесь.   -  person TomServo    schedule 24.12.2020


Ответы (1)


Я настоятельно рекомендую вам не использовать C для начальной загрузки C. И настоятельно рекомендую не использовать структуры между доменами компиляции.

• 96 Кбайт по адресу 0x2000 0000 (SRAM1) • 32 Кбайт по адресу 0x1000 0000 с аппаратной проверкой четности (SRAM2).

На устройствах STM32L49x/L4Ax SRAM2 имеет псевдоним по адресу 0x2004 0000, предлагая непрерывное адресное пространство с SRAM1.

Это STM32L47 да? Так что это не относится.

08000000 <vector>:
 8000000:   20020000    andcs   r0, r2, r0
 8000004:   0800043b    stmdaeq r0, {r0, r1, r3, r4, r5, r10}
 8000008:   08000435    stmdaeq r0, {r0, r2, r4, r5, r10}
 800000c:   08000435    stmdaeq r0, {r0, r2, r4, r5, r10}

0x200000 = 128 Кбайт. Попробуйте что-нибудь маленькое, просто для начала 0x20001000. Или перейти на 96K. 0x20018000

Он не сломан (ну, это может быть зависит от регистра и поля), но чище делать чтение-изменение-запись отдельно от регистра, чтобы регистр переходил только из одного режима в другой, а не дважды переключал режимы.

GPIOB->MODER &= ~(3UL<<4);    // Clear mode bits​
GPIOB->MODER |= 1UL<<4;       // Set mode to output​


tmp = GPIOB->MODER
tmp &= ~(3UL<<4);    // Clear mode bits​
tmp |= 1UL<<4;       // Set mode to output​
GPIOB->MODER = tmp

Может быть хорошей идеей делать что-то одно за раз. Либо просто включите светодиод, либо мигните светодиодом, используя задержку на основе счетчика (это не мертвый код). Затем позже возитесь с кнопками или таймерами или чем-то еще.

Взгляните на регистр gpio BSRR вместо ODR. Облегчает жизнь.

Это мертвый код,

    if(Upush%2!=0){
        GPIOE->ODR &= ~(1UL << 8);
        for(int i=125000; i!=0; i--){}
        GPIOE->ODR |= (1UL << 8);
        for (int i=125000; i!=0; i--){}
    }

Он компилируется в это в основном

    if(Upush%2!=0){
        GPIOE->ODR &= ~(1UL << 8);
        GPIOE->ODR |= (1UL << 8);
    }

Что слишком быстро, чтобы увидеть без прицела. И вы не можете точно определить время в цикле, поэтому оно не равно 2 Гц.

В вашем случае вы не оптимизировали так, чтобы цикл был там, он появляется, по крайней мере, с gnu, который я использую.

Конечно, вы должны начать с этого:

    while(1){
        GPIOE->BSRR = 1<<(8+16);
        for(volatile int i=125000; i!=0; i--){}
        GPIOE->BSRR = 1<<(8+ 0);
        for (volatile int i=125000; i!=0; i--){}
    }

как ваша основная программа после инициализации этого контакта gpio. Без каких-либо кнопок джойстика. Заставьте это работать и убедитесь, что ваш основной скелет хорош, а затем добавляйте к нему что-то. (кнопки заметок сложны / болезненны, так как вы часто хотите их устранить. Скорее всего, не в этом случае, а в целом)

person old_timer    schedule 24.12.2020