es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedo vincular Newlib memcpy en un proyecto sin sistema operativo?

Estoy tratando de compilar un proyecto simple para un microcontrolador TM4C123GXL utilizando arm-none-eabi-gcc. Dentro de main, llamo a memcpy solo para probar que funciona como se espera, pero esto causa un error. Lo que causa el error está en el desensamblado de memcpy, una de las primeras instrucciones es b.n 0xc7a, que lleva a la CPU a un segmento no utilizado de la memoria flash. Es como si memcpy esperara que otra función esté en esa ubicación, pero no puedo entender por qué sucedería eso cuando todas las dependencias deberían estar enlazadas también. Y de hecho, lo están. Un vistazo a los símbolos en el archivo ELF muestra que otras funciones también están incluidas. Se compila sin advertencias ni errores.

Aquí está el Makefile que estoy utilizando:

PROJECT = main
SRCS = $(wildcard src/*.c)
OBJ = obj/
OBJS = $(addprefix $(OBJ), $(notdir $(SRCS:.c=.o)))
INC = inc/
LD_SCRIPT = TM4C123GH6PM.ld

CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld 
OBJCOPY = arm-none-eabi-objcopy
RM = rm -rf
MKDIR = @mkdir -p $(@D)

<h1>EDIT: incluir la bandera -O0</h1>

OPT += -O0

CFLAGS = -ggdb3 -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 
CFLAGS += -mfloat-abi=softfp -MD -std=c99 -c -Wextra -Wall -Wno-missing-braces
CFLAGS += $(OPT)

all: bin/$(PROJECT).elf

$(OBJ)%.o: src/%.c
    $(MKDIR)
    $(CC) -o $@ $^ -I$(INC) $(CFLAGS)

bin/$(PROJECT).elf: $(OBJS) 
    $(MKDIR)
    $(CC) -o $@ $^ -Wl,-T $(LD_SCRIPT) -Wl,-e Reset_Handler
    $(OBJCOPY) -O binary $@ bin/$(PROJECT).bin

clean:
    -$(RM) obj
    -$(RM) bin

Y aquí está mi main:

#include <stdint.h>
#include <string.h>

int main(void){
    uint8_t x[] = {1,2,3};
    uint8_t y[] = {0,0,0};

    uint8_t *xptr = x;
    uint8_t *yptr = y;
    memcpy(yptr, xptr, 3);

    while (1)
        ;
}

Y mi Reset_Handler, solo por si acaso:

void Reset_Handler(void) {

    int *src, *dest;

    /* copiar los valores de .data a la RAM */
    src = &_etext;
    for (dest = &_data; dest < &_edata;) {
        *dest++ = *src++;
    }

    /* inicializar los valores de .bss a cero */
    for (dest = &__bss_start__; dest < &__bss_end__;) {
        *dest++ = 0;
    }

    main();
}

¿Hay algo más que deba hacer para poder usar la biblioteca estándar C de Newlib?</string.h></stdint.h>

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Parece que puede haber un problema con la función memcpy en tu código. Específicamente, parece que la función espera que alguna otra función esté en una ubicación determinada de la memoria flash, pero no la encuentra allí. Esto podría deberse a un problema con la forma en que se está compilando o enlazando el código.

    Una posible solución es agregar el indicador -nostdlib a tus CFLAGS al compilar el proyecto. Este indicador le indica al compilador que no use la biblioteca estándar de C, lo cual podría estar causando conflictos con la función memcpy. Además, sería conveniente verificar que todos los archivos necesarios se estén enlazando correctamente y que no haya dependencias circulares o versiones de bibliotecas incompatibles.

    Otra cosa que puedes intentar es agregar el indicador -O0 a tus CFLAGS. Esto desactivará la optimización del compilador y puede ayudar a identificar la causa raíz del problema.

    En resumen, es posible que el problema radique en la forma en que se está compilando o enlazando el código, y agregar los indicadores -nostdlib y -O0 podría ayudar a resolver el problema. Además, es importante asegurarse de que todos los archivos necesarios se estén enlazando correctamente y que no haya dependencias circulares o conflictos de versiones.

Comments are closed.