Estoy intentando hacer que el software GNUK se pueda compilar con Sistema PlatformIO. He convertido Makefile en un archivo de proyecto platformio.ini, todos los archivos fuente se compilan bien, pero obtengo errores de definición múltiple del vinculador para dos de las matrices definidas en uno de mis archivos fuente C. La parte relevante de mi archivo fuente es:

typedef void (*handler)(void);

handler vector[] __attribute__ ((section(".vectors"))) = {
  (handler)&__ram_end__,
  reset,
  (handler)set_led,
  flash_unlock,
  (handler)flash_program_halfword,
  (handler)flash_erase_page,
  (handler)flash_check_blank,
  (handler)flash_write,
  (handler)flash_protect,
  (handler)flash_erase_all_and_exec,
  usb_lld_sys_init,
  usb_lld_sys_shutdown,
  nvic_system_reset,
};

const uint8_t sys_version[8] __attribute__((section(".sys.version"))) = {
  3*2+2,         /* bLength */
  0x03,          /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE*/
  /* sys version: "1.0" */
  '1', 0, '.', 0, '0', 0,
};

Los errores que obtengo son:

.pio\build\OLIMEX_STM32_H103\src\sys.o:(.sys.version+0x0): multiple definition of `sys_version'
.pio\build\OLIMEX_STM32_H103\src\sys.o:(.sys.version+0x0): first defined here
.pio\build\OLIMEX_STM32_H103\src\sys.o:(.vectors+0x0): multiple definition of `vector'
.pio\build\OLIMEX_STM32_H103\src\sys.o:(.vectors+0x0): first defined here

Estoy atascado y ni siquiera sé por dónde empezar. Si agrego nuevas variables a ese archivo de origen, también obtengo errores de vinculador similares para ellos. ¿Parece que el mismo archivo se vincula dos veces?

El contenido del script del vinculador es:

__main_stack_size__     = 0x0400;
__process_stack_size__  = 0x0200;
__stacks_total_size__   = __main_stack_size__ + __process_stack_size__;

MEMORY
{
    flash0 : org = 0x08000000, len = 4k
    flash  : org = 0x08000000+0x1000, len = 128k - 4k
    ram : org = 0x20000000, len = 20k
}

/* __flash_start__: flash ROM start address regardless of DFU_SUPPORT */
__flash_start__         = 0x08001000;
__flash_end__       = ORIGIN(flash) + LENGTH(flash);

__ram_start__           = ORIGIN(ram);
__ram_size__            = LENGTH(ram);
__ram_end__             = __ram_start__ + __ram_size__;

SECTIONS
{
    . = 0;

    .sys : ALIGN(16) SUBALIGN(16)
    {
        _sys = .;
        KEEP(*(.vectors))
    . = ALIGN(16);
    *(.sys.version)
    src\sys.o(.text)
    src\sys.o(.text.*)
    src\sys.o(.rodata)
    src\sys.o(.rodata.*)
    . = ALIGN(1024);
    *(.sys.0)
    *(.sys.1)
    *(.sys.2)
    } > flash0

    .text : ALIGN(16) SUBALIGN(16)
    {
        _text = .;
        KEEP(*(vectors))
        *(.text)
        *(.text.*)
        *(.rodata)
        *(.rodata.*)
        *(.glue_7t)
        *(.glue_7)
        *(.gcc*)
    } > flash

    .ctors :
    {
        PROVIDE(_ctors_start_ = .);
        KEEP(*(SORT(.ctors.*)))
        KEEP(*(.ctors))
        PROVIDE(_ctors_end_ = .);
    } > flash

    .dtors :
    {
        PROVIDE(_dtors_start_ = .);
        KEEP(*(SORT(.dtors.*)))
        KEEP(*(.dtors))
        PROVIDE(_dtors_end_ = .);
    } > flash

    .ARM.extab : {*(.ARM.extab* .gnu.linkonce.armextab.*)}

    __exidx_start = .;
    .ARM.exidx : {*(.ARM.exidx* .gnu.linkonce.armexidx.*)} > flash
    __exidx_end = .;

    .eh_frame_hdr : {*(.eh_frame_hdr)}

    .eh_frame : ONLY_IF_RO {*(.eh_frame)}

    . = ALIGN(4);
    _etext = .;
    _textdata = _etext;

    .data :
    {
        _data = .;
        *(.data)
        . = ALIGN(4);
        *(.data.*)
        . = ALIGN(4);
        *(.ramtext)
        . = ALIGN(4);
        _edata = .;
    } > ram AT > flash

    .bss :
    {
        _bss_start = .;
        *(.bss)
        . = ALIGN(4);
        *(.bss.*)
        . = ALIGN(4);
        *(COMMON)
        . = ALIGN(4);
        _bss_end = .;
    } > ram

    PROVIDE(end = .);
    _end            = .;
    . = ALIGN(512);
    _regnual_start = .;


    .gnuk_flash :
    {
        . = ALIGN (1024);
    _data_pool = .;
    KEEP(*(.gnuk_data))
    . = ALIGN(1024);
    . += 1024;
    _keystore_pool = .;
    . += 512*3;
    . = ALIGN(1024);
    _updatekey_store = .;
    . += 1024;
    . = ALIGN(1024);
    } > flash =0xffffffff
}

__heap_base__   = _end;
__heap_end__    = __ram_end__ - __stacks_total_size__;
0
Alexandr Zarubkin 20 oct. 2020 a las 14:21

1 respuesta

La mejor respuesta

La solución fue reemplazar src\sys.o en la secuencia de comandos del vinculador con *sys.o.

Como se indica en el manual de ld,

En cualquier lugar donde pueda usar un archivo específico o un nombre de sección, también puede usar un patrón comodín. El enlazador maneja comodines de la misma forma que lo hace el shell de Unix. Un carácter '*' coincide con cualquier número de caracteres. A '?' carácter coincide con cualquier carácter individual. La secuencia '[chars]' coincidirá con una sola instancia de cualquiera de los caracteres; el carácter '-' puede usarse para especificar un rango de caracteres, como en '[a-z]' para coincidir con cualquier letra minúscula. Se puede utilizar un carácter "" para citar el siguiente carácter.

Cuando un nombre de archivo coincide con un comodín, los caracteres comodín no coincidirán con un carácter '/' (utilizado para separar nombres de directorio en Unix). Un patrón que consta de un solo carácter '*' es una excepción; siempre coincidirá con cualquier nombre de archivo. En el nombre de una sección, los caracteres comodín coincidirán con un carácter '/'.

Los comodines solo coinciden con los archivos que se especifican explícitamente en la línea de comando. El enlazador no busca directorios para expandir comodines. Sin embargo, si especifica un nombre de archivo simple (un nombre sin caracteres comodín) en una secuencia de comandos del vinculador, y el nombre del archivo tampoco se especifica en la línea de comando, el vinculador intentará abrir el archivo como si apareciera en la línea de comando.

El archivo sys.o se especificó en la línea de comando con otra ruta que en el archivo del vinculador, por lo que el vinculador intentó vincularlo dos veces.

0
Alexandr Zarubkin 26 oct. 2020 a las 09:03