Почему файл elf stm32f103 работает хорошо, а бинарный нет? - PullRequest
0 голосов
/ 23 октября 2019

Я пытаюсь запустить мою прошивку внутри stm32f103. Поэтому, когда я использую загрузку и отладку файла эльфа opencod + gdb, все в порядке, моя прошивка работает, и я могу устанавливать и удалять точки останова.

Но это не работает, когда я пытаюсь загрузить эту прошивку (котораябыл собран вместе с файлом elf) с использованием st-flash и записью его в 0x8000000. Хотя я получаю сообщение о том, что «прошивка была успешно загружена».

Я вижу, работает ли мой код, когда мои светодиоды начинают мигать.

BOOT0 подключен к выводу DTR cp2102 черезNPN транзистор, в соответствии с таблицей для включения загрузчика. Я должен установить BOOT0 на высокий уровень. Но мой серийный номер (cp2102) не подключен, когда я загружаю свой fw через st-link. Поэтому я думаю, что вывод DTR плавает или тянет вниз. Где моя ошибка?

Я пытался массово стереть свою флэш-память перед загрузкой, она дает те же результаты

schematic

здесьld файл моего компоновщика:

MEMORY
{
  RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
  CCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 0
  FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
  FLASHB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB0 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB2 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB3 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  MEMORY_ARRAY (xrw)  : ORIGIN = 0x00000000, LENGTH = 0
}

и разделы https://pastebin.ubuntu.com/p/N32zQf9sCm/

Ответы [ 3 ]

0 голосов
/ 25 октября 2019

попробуйте эту

.globl _start
_start:

.word 0x20001000
.word reset
.word loop
.word loop

.thumb_func
reset:
    add r0,#1
    b reset

.thumb_func
loop:
    b loop

сборку, можете использовать руку как угодно (arm-none-eabi, arm-linux-gnueabi и т. Д.)

arm-none-eabi-as so.s -o so.o
arm-none-eabi-ld -Ttext=0x08000000 so.o -o so.elf
arm-none-eabi-objcopy -O binary so.elf so.bin
arm-none-eabi-objdump -D so.elf

so.elf:     file format elf32-littlearm


Disassembly of section .text:

08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000011    stmdaeq r0, {r0, r4}
 8000008:   08000015    stmdaeq r0, {r0, r2, r4}
 800000c:   08000015    stmdaeq r0, {r0, r2, r4}

08000010 <reset>:
 8000010:   3001        adds    r0, #1
 8000012:   e7fd        b.n 8000010 <reset>

08000014 <loop>:
 8000014:   e7fe        b.n 8000014 <loop>

Не то чтобывекторы нечетные, это адрес обработчика или один с ним. Если вы этого не видите, процессор не загрузится.

Вы сказали, что у вас работает openocd + gdb, поэтому либо по этому пути, либо через openocd + telnet, либо если у вас есть другой способ, например, с использованием загрузчика uart. Но используйте сброс или включение питания с установленным boot0 для приложения, а затем подключите его с помощью openocd, не сбрасывая его, затем остановите и изучите r0, возобновите, остановите и проверьте снова, считает ли он, загружался ли этот код и запускался из флэш-памяти.

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

flash.s

.cpu cortex-m0
.thumb

.thumb_func
.global _start
_start:
stacktop: .word 0x20001000
.word reset
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang

.thumb_func
reset:
    bl notmain
    b hang
.thumb_func
hang:   b .

.align

.thumb_func
.globl PUT32
PUT32:
    str r1,[r0]
    bx lr

.thumb_func
.globl GET32
GET32:
    ldr r0,[r0]
    bx lr

.thumb_func
.globl dummy
dummy:
    bx lr

.end

blinker01.c

void PUT32 ( unsigned int, unsigned int );
unsigned int GET32 ( unsigned int );
void dummy ( unsigned int );

#define GPIOCBASE 0x40011000
#define RCCBASE 0x40021000

int notmain ( void )
{
    unsigned int ra;
    unsigned int rx;

    ra=GET32(RCCBASE+0x18);
    ra|=1<<4; //enable port c
    PUT32(RCCBASE+0x18,ra);
    //config
    ra=GET32(GPIOCBASE+0x04);
    ra&=~(3<<20);   //PC13
    ra|=1<<20;      //PC13
    ra&=~(3<<22);   //PC13
    ra|=0<<22;      //PC13
    PUT32(GPIOCBASE+0x04,ra);

    for(rx=0;;rx++)
    {
        PUT32(GPIOCBASE+0x10,1<<(13+0));
        for(ra=0;ra<200000;ra++) dummy(ra);
        PUT32(GPIOCBASE+0x10,1<<(13+16));
        for(ra=0;ra<200000;ra++) dummy(ra);
    }
    return(0);
}

flash.ld

MEMORY
{
    rom : ORIGIN = 0x08000000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > rom
    .rodata : { *(.rodata*) } > rom
    .bss : { *(.bss*) } > ram
}

build

arm-none-eabi-as --warn --fatal-warnings  flash.s -o flash.o
arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding  -mthumb -c blinker01.c -o blinker01.o
arm-none-eabi-ld -o blinker01.elf -T flash.ld flash.o blinker01.o
arm-none-eabi-objdump -D blinker01.elf > blinker01.list
arm-none-eabi-objcopy blinker01.elf blinker01.bin -O binary

изучить векторную таблицу

Disassembly of section .text:

08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000041    stmdaeq r0, {r0, r6}
 8000008:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800000c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000010:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000014:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000018:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800001c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000020:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000024:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000028:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800002c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000030:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000034:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000038:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800003c:   08000047    stmdaeq r0, {r0, r1, r2, r6}

08000040 <reset>:
 8000040:   f000 f80a   bl  8000058 <notmain>
 8000044:   e7ff        b.n 8000046 <hang>

08000046 <hang>:
 8000046:   e7fe        b.n 8000046 <hang>

Выглядит хорошо. Теперь запрограммируйте и выполните сброс.

Ваша схема не синяя таблетка, поэтому отрегулируйте ее соответствующим образом, чтобы включить часы gpio и сделать вывод выводом и так далее для вашего светодиода.

с любой из этих программили ваш собственный, я не использую GDB, бесполезно для него, я использую openocd + Telnet, если что-нибудь. но любой из них должен позволить вам сбросить флэш-память с помощью telnet

mdw 0x00000000 20
mdw 0x08000000 20

, оба должны иметь одинаковые данные. Если нет, то у вас проблема с boot0.

EDIT

Если DTR высокий, то boot0 равен 0 / GND, да? Это то, что требуется для нормальной загрузки. boot0 привязан к низкому уровню и сброшен к верхнему значению при включенном питании или от низкого к высокому.

Вы можете написать программу для принудительной установки DTR тем или иным способом.

int dtr_bit=TIOCM_DTR;
...
dtr_bit=TIOCM_DTR;
ioctl(ser_hand,TIOCMBIC,&dtr_bit);
...
dtr_bit=TIOCM_DTR;
ioctl(ser_hand,TIOCMBIS,&dtr_bit);

с обычными терминами termios. чтобы открыть ручку.

Или если предположить, что DTR поддерживается вашим тупым терминалом (minicom и т. д.), подключите его к Uart, затем включите и / или перезагрузите плату (скрепка, или что у вас есть под рукой).

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

0 голосов
/ 28 октября 2019

@ old_timer Большое спасибо за подробный ответ. Я обнаружил, что проблема в негабаритных прошивках. У моего чипа всего 64 КБ флэш-памяти, а fw - 68 КБ, поэтому Eclipse не сказала мне, что размер прошивки увеличен, и попытался его прошить. Кроме того, шаблон, в котором основан мой проект, использует newlib, где startup.s был заменен файлами C, и я предполагаю, что есть некоторая проблема. Поэтому я создал новый проект из тамплета openstm32 (он скопировал все необходимые файлы из stdperiph lib, cmsis и т. Д. + Ld), после чего я добавил свои файлы, оптимизировал сборку, удалив неиспользуемые файлы и установив флаг -Os, и он, кажется, работает длямне, но размер прошивки почти негабаритный. Я попробую твое объяснение)

0 голосов
/ 23 октября 2019

Вы пытались использовать STM32CubeProgrammer ?

Это позволяет вам программировать прошивку, используя UART, SWD, JTAG и USB. Пожалуйста, сначала попробуйте SWD, а затем режим UART, чтобы увидеть, является ли это ошибкой ST или вашей UART-проводкой.

...