这篇文章是嵌入式软件系列:Ada用于嵌入式C开发人员
与C语言一样,Ada也是一种编译语言。这意味着编译器将解析源代码并发出目标硬件的本机机器码。我们将在本课程中讨论的Ada编译器是GNAT编译器。与许多可用的C和c++编译器一样,该编译器基于GCC技术。
当在Ada代码上调用GNAT编译器时,GNAT前端扩展并将Ada代码翻译成传递给GCC的中间语言,在GCC中对代码进行优化并翻译成机器码。基于GCC的C编译器执行相同的步骤,并使用相同的中间GCC表示。这意味着我们在基于gcc的C编译器中看到的优化也可以应用到Ada代码中。
这两个编译器之间的主要区别是Ada编译器将高级构造扩展为中间代码。在展开之后,Ada代码将非常类似于等效的C代码。
可以逐行地将C代码翻译成Ada。对于熟悉C范式的开发人员来说,这似乎是很自然的一步。然而,走这条路可能没什么好处。在本课程中,我们将假设Ada而不是C的选择是基于与可靠性、安全性或安全性相关的考虑。
为了提高应用程序的可靠性、安全性和安全性,Ada范例应该被应用于替换那些通常在c中应用的构造,如指针、预处理宏、位操作和防御代码通常以非常不同的方式在Ada中表示。提高应用程序的整体可靠性和可读性。通常,开发人员一开始需要努力学习这些新的编码方法,但一旦理解了这些范例,就会证明这种方法更有效。
并发和实时
并发和实时编程是Ada语言的标准部分。因此,它们具有相同的语义,无论是在操作系统(如Linux)的本机目标上执行,还是在操作系统(如VxWorks)的实时操作系统(RTOS)上执行,还是在完全没有操作系统或RTOS的裸金属目标上执行。
理解各种选择
对于资源受限的系统,定义了Ada并发设施的两个子集,称为Ravenscar和Jorvik概要文件。尽管受到限制,但这些子集具有非常理想的属性,包括效率、可预测性、可分析性、无死锁、有界阻塞、无优先级反转、实时调度器和较小的内存占用。在裸机系统上,这实际上意味着Ada带有自己的实时内核。
增强的可移植性和表达能力是使用标准并发设施的主要优点,可能会带来可观的成本节约。例如,只需一点努力,就可以从Windows迁移到Linux,再迁移到一台裸机,而不需要对代码进行任何更改。线程管理和同步都是由实现透明地完成的。
然而,在某些情况下,能够直接访问平台提供的服务是至关重要的。在这种情况下,总是可以从Ada代码直接进行系统调用。GNAT编译器的几个目标在默认情况下提供了这种API—例如,用于Windows的win32ada和用于POSIX系统的Florist。
在本地平台和基于rtos的平台上,GNAT通常提供完整的并发设施。相比之下,在裸金属平台上,GNAT通常提供两个标准子集:Ravenscar和Jorvik。
Ravenscar
Ravenscar概要文件是Ada并发性工具的一个子集,它支持确定性、可调度性分析、受限内存使用和最高完整性级别的认证。有四个不同的应用领域:
- 需要可预测性的硬实时应用程序。
- 需要正式、严格认证的安全关键系统。
- 需要正式静态分析和验证的高完整性应用程序。
- 嵌入式应用程序需要小内存占用和低执行开销。
不允许在技术上或经济上排除分析的任务构造。您可以使用pragma Profile (Ravenscar)来指示您的程序中必须遵守Ravenscar限制。
Ravenscar提供了许多额外的限制。讨论这些内容将超出本章的范围。你可以在Ravenscar上找到更多的例子这篇博客.
更多信息请参阅嵌入式软件系列:Ada用于嵌入式C开发人员