попробуйте эту
.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 и перезагрузки, будь то кнопки или перемычки или пэды или какая-то комбинация.