¿Escribir código STM32F7 sin archivos externos?

1

Cómo iniciar la codificación para la plataforma STM32F7 sin ningún archivo externo a pesar del archivo de inicio del ensamblador. ¿Hay un archivo de encabezado con registros asignados en memoria que no incluya ningún otro archivo de encabezado (por ejemplo, core_cm7.h)?

    
pregunta VIPPER

1 respuesta

2

Esta es una pregunta de stackoverflow, no una pregunta de ingeniería eléctrica.

El STM32F7 tiene un Cortex-M7, que al igual que el m4 y el m3 se basa en ARMv7-M. extensiones thumb + thumb2 para el conjunto de instrucciones, arranca lo mismo, etc.

La documentación de ST debe mostrarle la lista de registro para el chip. Puede crear un archivo de encabezado de un solo archivo a partir de eso. Si está buscando a alguien para que busque en la red por usted, este no es el lugar, ni se desborda la pila.

toneladas de ejemplos de metales desnudos para trabajar, comience con cualquier ejemplo de cortex-m para ver cómo se hace eso. Un archivo de asm y un archivo de C son todos los mínimos necesarios (probablemente podría hacer un archivo de C, pero más seguro con un puñado de líneas de asm para la tabla de vectores).

por ejemplo

flash.s

.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 main
    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
.end

test.c

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


#define STK_CSR 0xE000E010
#define STK_RVR 0xE000E014
#define STK_CVR 0xE000E018
#define STK_MASK 0x00FFFFFF

static int delay ( unsigned int n )
{
    unsigned int ra;

    while(n--)
    {
        while(1)
        {
            ra=GET32(STK_CSR);
            if(ra&(1<<16)) break;
        }
    }
    return(0);
}

int main ( void )
{
    PUT32(STK_CSR,4);
    PUT32(STK_RVR,1000000-1);
    PUT32(STK_CVR,0x00000000);
    PUT32(STK_CSR,5);

    delay(100);


    return(0);
}

flash.ld

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

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

No necesita el archivo de vinculador, puede hacer algo como -Ttext = 0xaddress en lugar de un script de vinculador.

arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m0 flash.s -o flash.o
arm-none-eabi-gcc -Wall  -O2 -nostdlib -nostartfiles -ffreestanding -mthumb -c test.c -o test.gcc.thumb.o
arm-none-eabi-ld -o test.gcc.thumb.flash.elf -T flash.ld flash.o test.gcc.thumb.o
arm-none-eabi-objdump -D test.gcc.thumb.flash.elf > test.gcc.thumb.flash.list
arm-none-eabi-objcopy test.gcc.thumb.flash.elf test.gcc.thumb.flash.bin -O binary

Sí, sé que dice cortex-m0 en lugar de -m7, tomado de un ejemplo m0 te da solo pulgar no o algunas extensiones de thumb2, debería funcionar en toda la corteza-ms.

desmontaje de arriba.

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 f806   bl  8000050 <main>
 8000044:   e7ff        b.n 8000046 <hang>

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

08000048 <PUT32>:
 8000048:   6001        str r1, [r0, #0]
 800004a:   4770        bx  lr

0800004c <GET32>:
 800004c:   6800        ldr r0, [r0, #0]
 800004e:   4770        bx  lr

08000050 <main>:
 8000050:   b570        push    {r4, r5, r6, lr}
 8000052:   2104        movs    r1, #4
 8000054:   480e        ldr r0, [pc, #56]   ; (8000090 <main+0x40>)
 8000056:   f7ff fff7   bl  8000048 <PUT32>
 800005a:   490e        ldr r1, [pc, #56]   ; (8000094 <main+0x44>)
 800005c:   480e        ldr r0, [pc, #56]   ; (8000098 <main+0x48>)
 800005e:   f7ff fff3   bl  8000048 <PUT32>
 8000062:   2100        movs    r1, #0
 8000064:   480d        ldr r0, [pc, #52]   ; (800009c <main+0x4c>)
 8000066:   f7ff ffef   bl  8000048 <PUT32>
 800006a:   2480        movs    r4, #128    ; 0x80
 800006c:   2105        movs    r1, #5
 800006e:   4808        ldr r0, [pc, #32]   ; (8000090 <main+0x40>)
 8000070:   f7ff ffea   bl  8000048 <PUT32>
 8000074:   2564        movs    r5, #100    ; 0x64
 8000076:   0264        lsls    r4, r4, #9
 8000078:   4805        ldr r0, [pc, #20]   ; (8000090 <main+0x40>)
 800007a:   f7ff ffe7   bl  800004c <GET32>
 800007e:   4220        tst r0, r4
 8000080:   d0fa        beq.n   8000078 <main+0x28>
 8000082:   3d01        subs    r5, #1
 8000084:   2d00        cmp r5, #0
 8000086:   d1f7        bne.n   8000078 <main+0x28>
 8000088:   2000        movs    r0, #0
 800008a:   bc70        pop {r4, r5, r6}
 800008c:   bc02        pop {r1}
 800008e:   4708        bx  r1
 8000090:   e000e010    and lr, r0, r0, lsl r0
 8000094:   000f423f    andeq   r4, pc, pc, lsr r2  ; <UNPREDICTABLE>
 8000098:   e000e014    and lr, r0, r4, lsl r0
 800009c:   e000e018    and lr, r0, r8, lsl r0

Normalmente arrancamos desde la dirección 0, pero las partes de STM32 o al menos la última con la que jugué y al menos una de las STM32F7 (no especificó en cuál estaba interesado) hace que el usuario comience de forma inmediata en 0x08000000, así que -Ttext = 0x08000000 (gnu se pone un poco raro con este enfoque de línea de comandos y puede poner espacios vacíos, prefiero el script del vinculador).

Si está utilizando otra cadena de herramientas (gnu está siempre disponible y es gratis y con un montón de soporte en línea), entonces la sintaxis de ASM es probablemente diferente. Los scripts de vinculador son probablemente muy diferentes.

y sí, mi ejemplo simple utiliza un conjunto de registros periherales de la corteza, no ninguna de las direcciones específicas del proveedor de chips (st en este caso). El stm32f7 que estoy viendo, por ejemplo, RCC comienza en la dirección 0x40023800

así que quizás quieras crear esto

#define RCC_APB1ENR (0x40023800+0x40)
    
respondido por el old_timer

Lea otras preguntas en las etiquetas