ETL 可以与 Atmel Studio 一起使用吗?

Can ETL be used with Atmel Studio?

Embedded Template Library提供了不使用动态分配的STL数据结构,用于嵌入式开发。

我正在 Atmel Studio 中试验 ATSAMD21,无法使用动态分配。因此我尝试了 ETL,但它给我的错误与我在尝试使用 STL 时遇到的错误相同:

Error       ld returned 1 exit status
Error       undefined reference to `_exit'
Error       undefined reference to `_close'
Error       undefined reference to `_fstat'
Error       undefined reference to `_isatty'
Error       undefined reference to `_lseek'
Error       undefined reference to `_read'
Error       undefined reference to `_sbrk'
Error       undefined reference to `_kill'
Error       undefined reference to `_getpid'
Error       undefined reference to `_write'

据我所知,这些错误意味着为编译器选择了错误的目标体系结构。然而,事实并非如此,因为在我定义单个 ETL 结构之前我的程序运行良好。此外,ETL 仅由一堆头文件组成。

我的猜测是 ETL 使用了来自 STL 的代码,而 Atmel Studio 中包含的 gnu 编译器无法处理它。 (但如果完全无法使用,他们为什么还要包括 STL?)

不过,据说可以使用 ETL even without STL

所以我在我的项目中定义了#define ETL_NO_STL,但我仍然得到同样的错误。

它似乎在“发布”模式下工作正常,这些错误只出现在“调试”中。

调试和发布之间的差异并不表明我在其中一个与另一个之间使用了 STL:

调试:

"C:\Program Files (x86)\Atmel\Studio.0\toolchain\arm\arm-gnu-toolchain\bin\arm-none-eabi-g++.exe" -mthumb -D__SAMD21J18A__ -DDEBUG -I"C:\Program Files (x86)\Atmel\Studio.0\Packs\atmel\SAMD21_DFP.2.276\samd21a\include" -I"C:\Program Files (x86)\Atmel\Studio.0\Packs\arm\CMSIS.2.0\CMSIS\Include" -O1 -ffunction-sections -fno-rtti -fno-exceptions -mlong-calls -g3 -Wall -mcpu=cortex-m0plus -c -MD -MP -MF "main.d" -MT"main.d" -MT"main.o" -o "main.o" ".././main.cpp"

发布:

"C:\Program Files (x86)\Atmel\Studio.0\toolchain\arm\arm-gnu-toolchain\bin\arm-none-eabi-g++.exe" -mthumb -D__SAMD21J18A__ -DNDEBUG -I"C:\Program Files (x86)\Atmel\Studio.0\Packs\atmel\SAMD21_DFP.2.276\samd21a\include" -I"C:\Program Files (x86)\Atmel\Studio.0\Packs\arm\CMSIS.2.0\CMSIS\Include" -O1 -ffunction-sections -fno-rtti -fno-exceptions -mlong-calls -Wall -mcpu=cortex-m0plus -c -MD -MP -MF "main.d" -MT"main.d" -MT"main.o" -o "main.o" ".././main.cpp"

唯一的区别是调试版本多了一行: 使用程序集“C:\Program Files (x86)\Atmel\Studio.0\Extensions\Application\AvrGCC.dll”中的“RunCompilerTask”任务。

调试级别不是原因。将其设置为 g3、g2、g1 或将其关闭不会改变任何内容。区别在于命令中是否有 NDEBUG。也许没有它会有一些不必要的 POSIX 执行一致性检查?

ETL是在STL之后设计的,没错。但是 STL 作为一个库早已不复存在,随着它的内容被合并到 C++ 标准库中,它已经过时了。

不过,引用的符号来自 C 标准库,这是另一个已成为 C++ 标准库一部分的库。

一个折衷的解决方案是在调试模式下添加 NDEBUG 参数,同时仍然指定调试级别(如 -g2 或 -g3)

这允许在调试会话中使用断点和观察变量的值,唯一的缺点似乎是断言语句不起作用,与其他平台相比,嵌入式开发中很少使用该功能。

我遇到了同样的问题。 我的解决方案是禁用 ETL 的 DEBUG 模式。

您需要修补 etl/platforms.h 文件:

#if (defined(_DEBUG) || defined(DEBUG)) && !defined(ETL_DEBUG) 
  #define ETL_DEBUG  // <---- comment out this line
#endif