Error when linking .o files using ld on WIndows

1

Two C files are compiled as shown:

gcc -g -c -Wall -I../include blink.c -o blink.o

gcc -g -c -Wall -I../include led/led.c -o led/led.o

These operations appear to be successful (the correct files are produced).

When attempting to link the two .o files with the command:

ld -Map blink.map -T make.ld -N -o blink.exe blink.o led/led.o

This error is returned:

undefined reference to `__main'

As suggested on another post, I tried adding -r, but that instead results in this error shown below:

C:\mingw\bin\ld.exe: address 0x0 of blink.exe section `data' is not within region `ram'
C:\mingw\bin\ld.exe: address 0x0 of blink.exe section `bss' is not within region `ram'
C:\mingw\bin\ld.exe: address 0xd0 of blink.exe section `text' is not within region `ram'
C:\mingw\bin\ld.exe: address 0x28 of blink.exe section `.xdata' is not within region `ram'
C:\mingw\bin\ld.exe: address 0x30 of blink.exe section `.pdata' is not within region `ram'
C:\mingw\bin\ld.exe: address 0x40 of blink.exe section `.rdata$zzz' is not within region `ram'

I am using Windows 10, and have tried this using both Cygwin64 Terminal and MinGW, but get the exact same result with both.

I am fairly sure that it is not a RAM issue, as there is '320K' (which I believe should be more than enough for a simple program like this) assigned in the make.ld file, shown below:

ENTRY (main)

MEMORY
{
    ram : ORIGIN = 0x20000000, LENGTH = 320K /* 0x2000 0000 - 0x2004 FFFF */
    rom : ORIGIN = 0x08000000, LENGTH = 1024K /* 0x0800 0000 - 0x080F FFFF */
}

SECTIONS
{
    data :
    {
        _DataStart = . ;
        *(.data)
        _DataEnd   = . ;
    } >ram 

    bss :
    {
        _BssStart = . ;
        *(.bss)
        _BssEnd   = . ;
    } >ram 

    text :
    {
        *(.text)
    } >ram 
}

For reference here are the three other files:

blink.c

int main(void)
{
    ledInit();
    while (1)
    {
        ledToggle();
        delay_ms(500);
    }
    return 0;
}

led/led.c

#include "../stm32f7/onChipPeripherals.h"            

void ledInit(void)
{
    (*((uint32_t volatile *)(GPIO_A + GPIO_BSRR_OFFSET))) = 0xFFFF0000;
    (*((uint32_t volatile *)(GPIO_A + GPIO_MODER_OFFSET))) = 0x00000010;
}

void ledToggle(void)
{
    if ((*((uint32_t volatile *)(GPIO_A + GPIO_BSRR_OFFSET))) & 0x0000FFFF)
        (*((uint32_t volatile *)(GPIO_A + GPIO_BSRR_OFFSET))) = 0xFFFF0000;
    else
        (*((uint32_t volatile *)(GPIO_A + GPIO_BSRR_OFFSET))) = 0x0000FFFF;
}

void delay_ms(int milliseconds)
{
    long volatile cycles = (milliseconds * CYCLES_PER_MS);
    while (cycles != 0)
        cycles--;
}

stm32f7/onChipPeripherals.h

#include <stdint.h>

/* GPIO Registers */
#define GPIO_A                                     (*((uint32_t volatile *)0x40020000))

#define GPIO_MODER_OFFSET                          (0x00) // GPIO port mode register
#define GPIO_OTYPER_OFFSET                         (0x04) // GPIO port output type register
#define GPIO_OSPEEDR_OFFSET                        (0x08) // GPIO port output speed register
#define GPIO_PUPDR_OFFSET                          (0x0C) // GPIO port pull-up/pull-down register
#define GPIO_IDR_OFFSET                            (0x10) // GPIO port input data register
#define GPIO_ODR_OFFSET                            (0x14) // GPIO port output data register
#define GPIO_BSRR_OFFSET                           (0x18) // GPIO port bit set/reset register
#define GPIO_LCKR_OFFSET                           (0x1C) // GPIO port configuration lock register
#define GPIO_AFRL_OFFSET                           (0x20) // GPIO alternate function low register
#define GPIO_AFRH_OFFSET                           (0x24) // GPIO alternate function high register

I would hugely appreciate any suggestions or guidance on what to do or try next, as I am a little stuck and unsure from here.

c
windows
gcc
gnu
ld
asked on Stack Overflow Feb 25, 2021 by Starman

1 Answer

1

Use the correct toolchain for the target architecture. An unqualified gcc on cygwin64 is going to try to build the program to run on x64 Windows under cygwin.

The error is complaining about section ram; but the real issue is using the wrong toolchain. The correct gcc is gcc-arm-embedded -m cortex-m7. Note that you will need to do the same adjustment with the ld command; I don't have a good source but the pattern is usually followed so the ld command is most likely ld-arm-embedded.

My source for the correct gcc: https://github.com/libopencm3/libopencm3/issues/965

answered on Stack Overflow Feb 25, 2021 by Joshua

User contributions licensed under CC BY-SA 3.0