在 WIndows 上使用 ld 链接 .o 文件时出错

Error when linking .o files using ld on WIndows

编译出两个C文件如图:

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

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

这些操作似乎是成功的(生成了正确的文件)。

尝试使用以下命令 link 两个 .o 文件时:

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

返回此错误:

undefined reference to `__main'

根据另一个 post 的建议,我尝试添加 -r,但这反而导致了如下所示的错误:

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'

我正在使用 Windows 10,并尝试使用 Cygwin64 Terminal 和 MinGW,但两者得到的结果完全相同。

我相当确定这不是 RAM 问题,因为在 make.ld 文件中分配了“320K”(我认为对于像这样的简单程序来说应该足够了),如图所示下面:

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 
}

其他三个文件供参考:

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

对于接下来要做什么或尝试什么的任何建议或指导,我将不胜感激,因为我在这里有点卡住和不确定。

为目标架构使用正确的工具链。 cygwin64 上的不合格 gcc 将尝试在 cygwin.

下的 x64 Windows 上将程序构建为 运行

错误是关于 ram 部分的抱怨;但真正的问题是使用了错误的工具链。正确的 gccgcc-arm-embedded -m cortex-m7。请注意,您需要使用 ld 命令进行相同的调整;我没有很好的来源,但通常会遵循该模式,因此 ld 命令很可能是 ld-arm-embedded.

我的正确 gcc 来源:https://github.com/libopencm3/libopencm3/issues/965