【发布时间】:2022-01-02 08:57:05
【问题描述】:
正如标题所暗示的那样,我收到一个与未定义 memcpy 和 memset 相关的错误,即使我没有直接使用它(尽管鉴于此错误的性质,我猜它用于链接器和编译过程)
长话短说:我正在将最初存储在 FLASH 中的 .data 和 .bss 部分写入 SRAM 内存,我正在使用指针进行此类操作,如下所示:
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <string.h>
int main(void);
void Reset_Handler(void);
void Default_Handler(void);
#ifdef __cplusplus
}
#endif
extern uint32_t _etext;
extern uint32_t _sdata;
extern uint32_t _edata;
extern uint32_t _sbss;
extern uint32_t _ebss;
void Reset_Handler(void)
{
//copy .data section to SRAM
uint32_t size = (uint32_t)&_edata - (uint32_t)&_sdata;
uint8_t *pDst = (uint8_t*)&_sdata; //sram
uint8_t *pSrc = (uint8_t*)&_etext; //source point comes from flash memory that is end of flash
for(uint32_t i =0 ; i < size ; i++)
{
*pDst++ = *pSrc++; //"MEMCPY NOT DEFINED" ERROR TRIGGERS HERE
}
//copy .bss section to SRAM
size = (uint32_t)&_ebss - (uint32_t)&_sbss;
pDst = (uint8_t*)&_sbss; //sram
for(uint32_t i =0 ; i < size ; i++)
{
*pDst++ = 0; //"MEMSET NOT DEFINED" ERROR TRIGGERS HERE
}
main();
}
我正在使用 arm 嵌入式 g++ 编译器来构建 .o 文件,然后使用 -nostdlib 选项链接到 .elf ,因为这是嵌入式应用程序,因此不需要/负担得起的标准库。
该过程失败,因为似乎存在对“memcpy”和“memset”函数的隐式调用。我试图包含
这是 make 文件调用和终端输出:
arm-none-eabi-g++ -c -mcpu=cortex-m4 -mthumb -std=c++11 -O2 -g -fno-exceptions stm32_startup.cpp -o stm32_startup.o
arm-none-eabi-g++ -nostdlib -T stm32_ls.ld -Wl,-Map=final.map main.o GPIO_PORT.o stm32_startup.o config.o -o final.elf
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: stm32_startup.o: in function `Reset_Handler':
/home/inumaki/Development/stm32/Workspace/stm32_startup.cpp:155: undefined reference to `memcpy'
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: /home/inumaki/Development/stm32/Workspace/stm32_startup.cpp:165: undefined reference to `memset'
collect2: error: ld returned 1 exit status
make: *** [Makefile:35: final.elf] Error 1
inumaki@dev-Inumaki:~/Development/stm32/Workspace$ make
arm-none-eabi-g++ -c -mcpu=cortex-m4 -mthumb -std=c++11 -O2 -g -fno-exceptions stm32_startup.cpp -o stm32_startup.o
arm-none-eabi-g++ -nostdlib -T stm32_ls.ld -Wl,-Map=final.map main.o GPIO_PORT.o stm32_startup.o config.o -o final.elf
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: stm32_startup.o: in function `Reset_Handler':
/home/inumaki/Development/stm32/Workspace/stm32_startup.cpp:155: undefined reference to `memcpy'
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: /home/inumaki/Development/stm32/Workspace/stm32_startup.cpp:165: undefined reference to `memset'
collect2: error: ld returned 1 exit status
make: *** [Makefile:35: final.elf] Error 1
如我所见,唯一的出路是在删除#include
提前致谢。
编辑:
通过删除 -nostdlib,即允许链接器链接标准库,我得到这个错误也与未定义的函数有关。在我看来,它与汇编程序启动文件有关,即使我有一个 .cpp 启动文件。
inumaki@dev-Inumaki:~/Development/stm32/Workspace$ make
arm-none-eabi-g++ -c -mcpu=cortex-m4 -mthumb -std=c++11 -O2 -g -fno-exceptions main.cpp -o main.o
arm-none-eabi-g++ -c -mcpu=cortex-m4 -mthumb -std=c++11 -O2 -g -fno-exceptions GPIO_PORT.cpp -o GPIO_PORT.o
arm-none-eabi-g++ -c -mcpu=cortex-m4 -mthumb -std=c++11 -O2 -g -fno-exceptions stm32_startup.cpp -o stm32_startup.o
arm-none-eabi-g++ -c -mcpu=cortex-m4 -mthumb -std=c++11 -O2 -g -fno-exceptions config.cpp -o config.o
arm-none-eabi-g++ -T stm32_ls.ld -Wl,-Map=final.map main.o GPIO_PORT.o stm32_startup.o config.o -o final.elf
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/crt0.o: in function `_mainCRTStartup':
(.text+0x128): undefined reference to `__bss_start__'
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: (.text+0x12c): undefined reference to `__bss_end__'
/usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: /usr/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o): in function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'
collect2: error: ld returned 1 exit status
make: *** [Makefile:35: final.elf] Error 1
【问题讨论】:
-
虽然我不知道 memcpy 和 memset 是做什么的。你look them up了吗?
-
我想知道编译器是不是太聪明了,识别出代码描述的行为,并试图用对
memcpy和memset的调用替换你的循环,但不知道它们在你的实现中不存在. -
@PaulSanders 是的,我有点看过他们。我知道他们做什么,但不知道他们是怎么做的。我真正的意思是,如果需要,我不知道如何进行优化。
-
请注意,-nostdlib 指的是 glibc,而不是 c++ std 库。 gllibc 包括 memcpy、strcpy 等,对于嵌入式应用程序/小型 MCU 来说绝对不会太“昂贵”。
标签: c++ stm32 memcpy memset arm-none-eabi-gcc