1
\$\begingroup\$

How to start coding for STM32F7 platform without any external files despite of assembler startup file. Is there a header file with memory mapped registers which does not include any other header files (for example core_cm7.h)?

\$\endgroup\$
  • \$\begingroup\$ Try download MxCube. \$\endgroup\$ – Marko Buršič Dec 31 '15 at 21:49
  • \$\begingroup\$ I have downloaded mxcube. But it generates source codes with additional files such as core_cm7.h, so ST software does not help \$\endgroup\$ – VIPPER Jan 1 '16 at 10:53
  • 1
    \$\begingroup\$ Why the restriction of "without any external files"? It seems like an arbitrary and an unnecessary constraint. An explanation for that might help more people answer. \$\endgroup\$ – gbulmer Jan 1 '16 at 13:02
  • \$\begingroup\$ I have taken course on edX. It was based on Stellaris/Tiva C from TI MCU with Cortex-M4 on board. They created example projects where the only included file was .s assembler as startup code. All registers was defined as a constant pointer to place in memory. I just want to repeat this on STM32... and learn new stuff, that's all. \$\endgroup\$ – VIPPER Jan 3 '16 at 9:51
  • \$\begingroup\$ You'll learn way more stuff by using the appropriate tools - MXCube or the StdPeriphLib. There is very little need to recreate the libraries ST already provide (plus nothing forces you to use any of the libs but the startup files if you wish to perform direct register accesses). At least you'll get a minimal running program. \$\endgroup\$ – Tibo Jan 4 '16 at 8:41
2
\$\begingroup\$

This is a stackoverflow question not an electrical engineering question.

The STM32F7 has a Cortex-M7, which like the m4 and m3 is ARMv7-M based. thumb+thumb2 extensions for the instruction set, boots the same, etc.

The ST documentation should show you the register list for the chip. You can create a single file header file from that. If you are looking for someone to search the net for you, this is not the place, nor is stack overflow.

tons of bare metal examples out there to work from, start with any cortex-m example to see how that is done. One asm file and one C file are all yeed bare minimum (probably could do one C file, but safer with a handful of lines of asm for the vector table).

for example

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
}

You dont need the linker file you can do something like -Ttext=0xaddress instead of a linker script.

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

Yes I know that says cortex-m0 instead of -m7, borrowed from an example m0 gives you just thumb no or few thumb2 extensions, should work on all cortex-ms.

disassembly of above.

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

Normally we boot from address 0 but the STM32 parts or at least the latest one I played with and at least one of the STM32F7's (you didnt specify which one you were interested in) has the user flash start at 0x08000000 so -Ttext=0x08000000 (gnu gets a little funny with this command line approach and can put gaps of dead space, I prefer the linker script).

If you are using another toolchain (gnu is always available and free and tons of online support) then the asm syntax is likely different. Linker scripts are likely a lot different.

and yes my simple example uses a cortex periheral set of registers not any of the chip vendor (st in this case) specific addresses. the stm32f7 I am looking at for example RCC starts at address 0x40023800

so perhaps you might want to create this

#define RCC_APB1ENR (0x40023800+0x40)
\$\endgroup\$
  • \$\begingroup\$ I am not looking for someone to work for me... I've just asked a question... Nevermind. Can you recommend a website or other online stuff to learn more memory structure, linker scripts, startup codes etc. ? \$\endgroup\$ – VIPPER Jan 3 '16 at 9:58
  • \$\begingroup\$ I have numerous examples at github (dwelch67). google is your friend. gnu.org, stackoverflow, infocenter.arm.com, there is so much information out there it is hard to consume even a small fraction of it. But you should just start doing that. Pick a place, arm docs connected to the booting of a cortex-m, or gnu linker scripts, read the chip vendors docs, etc. \$\endgroup\$ – old_timer Jan 3 '16 at 15:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.