利润|dreamstime.com
艾达促销

在嵌入式系统上编写ADA

2021年5月27日
在ADA中编写低级编程很容易。这是关于如何完成的入门。

本文是嵌入式软件系列:嵌入式C开发人员的ADA

我们已经在以前的文章中看到了如何使用ADA来描述高级语义和体系结构。然而,语言的优点在于,它可以一直使用到开发的最低级别,包括嵌入式装配代码或比特数据管理。

Representation Clauses

该语言的一个非常有趣的功能是,与C不同,除非开发人员指定,否则没有数据表示约束。这意味着编译器可以自由选择代表与性能的最佳权衡。让我们从以下ADA示例开始:

R类是记录V:整数范围0 .. 255;b1:布尔人;b2:布尔人;带包的结束记录;

和C示例:

struct r {unsigned int v:8;Bool B1;Bool B2;};

上面的ADA和C ++代码都代表着创建尽可能小的对象的努力。在Java中无法控制数据大小,但是该语言确实指定了原始类型的值大小。

尽管在此示例中,C ++和ADA代码是等效的,但存在有趣的语义差异。在C ++中,需要指定每个字段所需的位数。在这里,我们指出V仅为8位,有效地表示为0到255的值。

在ADA中,这是另一种方式:开发人员指定所需的值范围,编译器决定如何表示事物,对速度或尺寸进行优化。记录结束时声明的包装方面规定,即使以访问记录组件的速度降低速度,编译器也应优化尺寸。我们将在各节中查看有关包装方面的更多详细信息钻头操作将结构映射到位。在第6章中(来)。

Other representation clauses can be specified as well, along with compile-time consistency checks between requirements in terms of available values and specified sizes. This is particularly useful when a specific layout is necessary; for example, when interfacing with hardware, a driver, or a communication protocol. Here's how to specify a specific data layout based on the previous example:

R类是记录V:整数范围0 .. 255;b1:布尔人;b2:布尔人;结束记录;对于r,使用记录 - 占据第一个字节的第一位。B1在0范围0 .. 0;- 占据第一个字节的最后7位。- 以及第二个字节的第一位。v在0范围1 .. 8;- 占据第二个字节的第二位。 B2 at 1 range 1 .. 1; end record;

我们省略了“用包装”指令,而是在记录声明之后使用记录表示条款。编译器被指示可将R型的对象传播到两个字节上。我们在这里指定的布局效率相当低,无法在任何机器上使用。但是,您可以让编译器构造最有效的访问方法,而不是手动编码自己的机器依赖性比特方法。

嵌入式装配代码

在执行低级开发(例如内核或硬件驱动程序级别)时,有时可能需要使用汇编代码实现功能。

每个ADA编译器都有基于硬件平台和受支持的汇编程序的嵌入组件代码的约定。我们的示例将在X86体系结构上与GNAT和GCC合作。

All x86 processors since the Intel Pentium offer the rdtsc instruction, which tells us the number of cycles since the last processor reset. It takes no inputs and places an unsigned 64-bit value split between the edx and eax registers.

GNAT提供了一个名为System.machine_code.asm的子程序,可用于汇编代码插入。您可以指定一个字符串以传递到汇编程序以及可用于输入和输出的源级变量:

-  get_processor_cycles.adb with ssytem.machine_code;使用system.machine_code;与接口;使用接口;函数get_processor_cycles返回unsigned_64很低,高:unsigned_32;计数器:unsigned_64;开始ASM(“ rdtsc”,outputs =>(unsigned_32’asm_output(“ = a”,high),unsigned_32’asm_output(“ = d”,low)),volatile => true);计数器:= UNSIGNED_64(高) * 2 ** 32 + unsigned_64(low);返回计数器;end get_processor_cycles;

The Unsigned_32'Asm_Output clauses above provide associations between machine registers and source-level variables to be updated. =a and =d refer to the eax and edx machine registers, respectively. The use of the Unsigned_32 and Unsigned_64 types from package Interfaces ensures correct representation of the data. We assemble the two 32-bit values to form a single 64-bit value.

我们将挥发性参数设置为True,以告诉编译器多次使用相同输入调用此指令可能会导致不同的输出。这消除了编译器将多个调用优化到单个呼叫中的可能性。

通过优化,GNAT编译器足够聪明,可以使用EAX和EDX寄存器来实现高和低变量。这导致组装接口的开销为零。

机器代码插入界面提供了此处显示的许多功能。更多信息可以在GNAT用户指南和GNAT参考手册中找到。

中断处理

在编程嵌入设备时,处理中断是一个重要方面。例如,使用中断来表明发生了硬件或软件事件。因此,通过处理中断,应用程序可以对外部事件做出反应。

Ada provides built-in support for handling interrupts. We can process interrupts by attaching a handler, which must be a protected procedure, to it. In the declaration of the protected procedure, we use the Attach_Handler aspect and indicate which interrupt we want to handle.

让我们来看看一个代码示例陷阱Linux上的退出中断(sigquit):

——signal_handlers。与System.OS_Interface广告;package Signal_Handlers is protected type Quit_Handler is function Requested return Boolean; private Quit_Request : Boolean := False; -- -- Declaration of an interrupt handler for the “quit” interrupt -- end Quit_Handler; end Signal_Hander; -- signal_handlers.adb with Ada.Text_IO; use Ada.Text_IO; package body Signal_Handler is protected body Quit_Handler is function Requested return Boolean is (Quit_Request); procedure Handle_Quit_Signal is begin Put_Line (“Quit request detected!”); Quit_Request := True; end Quit_Handler; end Signal_Handler; -- test_quite_handler.adb with Ada.Text_IO; use Ada.Text_IO; with Signal_Handlers; procedure Test_Quit_Handler is Quit : Signal_Handlers.Quit_Handler; begin while True loop delay 1.0; exit when Quit.Requested; end loop; Put_Line (“Exiting application...”); end Test_Quit_Handler;

来自此示例的Signal_Handlers软件包的规范包含Quit_handler的声明,这是一个受保护的类型。在该受保护类型的私有部分中,我们声明handle_quit_signal过程。通过在handle_quit_signal声明中使用附加_handler方面并指示戒烟中断(system.os_interface.sigquit),我们正在指示操作系统以任何退出请求来调用此过程。因此,例如,当用户在键盘上按CTRL+\时,该应用程序的行为将如下:

  • 操作系统调用handle_quit_signal过程,该过程向用户显示一条消息(“检测到退出请求!”),并设置一个布尔值变量-Quit_request,quit_request在quit_handler type中声明:

--The main application checks the status of the quit handler by calling the Requested function as part of the while True loop:

*退出时,此呼叫在退出中。

*在这种情况下,请求的函数返回true,因为quit_request标志是由handle_quit_signal过程设置的。

  • 主要应用程序将退出循环,显示消息并完成。

请注意,上面的代码示例无法移植,因为它利用了Linux操作系统中断。在编程嵌入设备时,我们将使用这些特定设备上可用的中断。

Also note that, in the example above, we're declaring a static handler at compilation time. If you need to make use of dynamic handlers, which can be configured at runtime, you can utilize the subprograms from the Ada.Interrupts package. This package includes not only a version of Attach_Handler as a procedure, but also other procedures such as:

  • Exchange_handler,可以在运行时交换当前处理程序与其他处理程序中断相关联的当前处理程序。
  • distach_handler,我们可以用来删除当前与给定中断关联的处理程序。

有关ADA.Intructs软件包的详细信息不超出本课程的范围。将来,我们将在单独的,更高级的课程中讨论它们。您可以在中断ADA参考手册的附录

嵌入式软件系列:嵌入式C开发人员的ADA

最新的

Murata — IRA IRA-S210ST01 Pyroelectric Infrared Sensor

2022年3月31日
Murata IRA-S210ST01是一种含有铅的Pyroelectric红外传感器,可提供良好的信噪比和可靠的性能。

Nexperia - PMEGXXXTX TRENCH SHOTTKY RECTIFISER

2022年3月31日
Nexperia扩展了其沟槽肖特基整流器的投资组合,其设备额定最高为100 V和20 A.新零件具有出色的Switchi…

工程领域的女性 - 鼓舞我们领域的创造性增长

2022年3月8日
Over the last few years, the number of women in the technology or engineering profession has risen. The number of women enrolled in post-secondary en…

The Future of Automotive Wheel Sensing with GMR

2022年2月23日
下载PDF版本。Allegro微型系统。磁性传感器广泛用于现代车辆,以测量运动部件的位置,…

Voice your opinion!

本网站要求您注册或登录以发表评论。
尚未添加评论。想开始对话吗?
Baidu