ARM工具链的gcc是常规c还是嵌入式c?

thtygnil  于 2022-11-13  发布在  其他
关注(0)|答案(3)|浏览(133)

我不确定我用的是哪一个,我查了一下,有些答案说是主机决定c是否是嵌入式c,比如,pc -〉c,mcu -〉嵌入式c。
编辑:我使用arm-none-eabi-xxx

ruoxqz4g

ruoxqz4g1#

arm-none-eabi-gcc是一个用于裸机ARM的交叉编译器。ARM是 * 目标 主机 * 是运行编译器的机器-开发主机。
在大多数情况下,您会使用这样的编译器来开发裸机(即没有全功能操作系统)嵌入式系统,但同样,您也可以使用它来开发桌面系统的引导代码,或开发操作系统(尽管可能性较小)。
在任何情况下,并不是编译器决定系统是否是嵌入式的。嵌入式系统只是一个运行软件的系统,而不是一个通用计算机。例如,许多网络路由器运行在嵌入式Linux上,如OpenWRT,在这种情况下,你可以使用arm-linux-eabi-gcc。它的区别在于它仍然是一个交叉编译器;即构建代码的主机,与运行代码的主机不是同一个计算机体系结构或操作系统。
作为一个交叉编译器也不意味着它是“嵌入式”的--完全有可能在Windows上交叉编译Linux可执行文件,反之亦然,而不嵌入任何目标。
关键是,没有“嵌入式C”语言,它都是“常规C”。使它嵌入的是预期的 * 目标 *。所以不要被工具链的分类所困扰。如果你用它来为嵌入式系统生成代码,它就是嵌入式的。就这么简单。很多年前,我在一个使用MicrosoftCV 6的项目上工作(通常用于MS-DOS)在嵌入式系统中使用ROM上的代码并运行VRTX RTOS。Microsoft C没有被定义为嵌入式系统编译器;“魔术”是通过替换Microsoft的链接器来“重定向”它以产生ROM映像而不是. exe来实现的。
当然,也有一些目标总是“嵌入式”的,比如8051,我想,针对这样一个目标的交叉编译器可以说是专门“嵌入式”的,但这是一个没有什么意义的区别。

dphi5xsq

dphi5xsq2#

arm gcc工具链有很多版本,为交叉编译器建立的命名约定是,

  • arm-linux-xxx -这是一个“Regular C”,其中的库受Linux操作系统支持。“xxx”是ABI格式。
  • arm-none-xxx -这是“嵌入式C”。“xxx”再次表示ABI。它通常基于“newlib”。Newlib可以由RTOS托管,然后它将几乎是“常规C”。如果它是“裸机”,并且newlib功能默认为错误,则最有可能称为“嵌入式C”。

嵌入式“C++”是一个很常见的术语,但作为一种技术,它已经被普遍抛弃了。正如前面所说,编译器本身是独立的。然而,库/操作系统通常是定义你所要求的“精神”的东西。
ABI可以是硬浮点的“gnueabhf”等。它是例程之间的调用约定,通常取决于系统上是否有FPU。它也可能取决于ISA、PIC等。

ct2axkht

ct2axkht3#

C语言允许使用两种不同风格的目标:* 托管 * 和 * 独立 *。托管意味着程序运行在Windows或Linux等操作系统之上,独立意味着其他一切。独立系统的示例包括“裸机”微控制器、微控制器上的RTOS、托管操作系统本身。
托管和独立之间只有几个小的区别:

  • 标准库
  • 托管编译器必须支持C标准库的所有必需部分。
  • 独立编译器只需要实现<float.h>, <iso646.h>, <limits.h>, <stdalign.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, <stdint.h><stdnoreturn.h>。所有其他标准头文件都是可选的。
  • main()的有效形式
  • 装载的编译器必须支援int main(void)int main(int argc, char *argv[])。不需要支援其他实作定义形式的main()。
  • 独立编译器总是使用实现定义的形式的main(),因为没有人可以return到。最常见的形式是void main (void)

“嵌入式C”只是指用于嵌入式系统的C语言,而不是一个正式的术语。(例如,不要与嵌入式C混淆,后者实际上是C语言的一个子集方言。)
嵌入式系统通常是独立的系统。gcc-arm-none-eabi编译器是独立ARM系统的编译器端口(使用ARM的Embedded ABI)。它不会附带各种特定于操作系统的库。
当使用gcc编译独立系统时,你应该使用-ffreestanding选项。这启用了main()的常见实现定义形式,并且与-fno-builtin一起,它可能会阻止各种标准库函数调用被“内联”到你的代码中。我们不希望这样,因为那些库可能甚至不存在。

相关问题