Profitimage | Dreamstime.com
艾达促销

Writing Ada on Embedded Systems

May 27, 2021
Writing low-level programming in Ada is easy. Here’s a primer on how it’s done.

本文是嵌入Softwareseries:嵌入式C开发人员的ADA

We've seen in the previous articles how Ada can be used to describe high-level semantics and architecture. The beauty of the language, however, is that it can be used all the way down to the lowest levels of the development, including embedded assembly code or bit-level data management.

Representation Clauses

One very interesting feature of the language is that, unlike C, for example, there are no data representation constraints unless specified by the developer. This means that the compiler is free to choose the best tradeoff in terms of representation vs. performance. Let's start with the following Ada example:

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

and C example:

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

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

Although the C++ and Ada code are equivalent in this example, there's an interesting semantic difference. In C++, the number of bits required by each field needs to be specified. Here, we're stating that V is only 8 bits, effectively representing values from 0 to 255.

In Ada, it's the other way around: The developer specifies the range of values required and the compiler decides how to represent things, optimizing for speed or size. The Pack aspect declared at the end of the record specifies that the compiler should optimize for size even at the expense of decreased speed in accessing record components. We'll see more details about the Pack aspect in the sections about钻头操作and将结构映射到位。在第6章中(来)。

其他条款可以指定代表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型的对象传播到两个字节上。我们在这里指定的布局效率相当低,无法在任何机器上使用。但是,您可以让编译器构造最有效的访问方法,而不是手动编码自己的机器依赖性比特方法。

嵌入Assembly Code

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

每个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.

We set the Volatile parameter to True to tell the compiler that invoking this instruction multiple times with the same inputs can result in different outputs. This eliminates the possibility that the compiler will optimize multiple invocations into a single call.

With optimization turned on, the GNAT compiler is smart enough to use the eax and edx registers to implement the High and Low variables. This results in zero overhead for the assembly interface.

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

中断处理

Handling interrupts is an important aspect when programming embedded devices. Interrupts are used, for example, to indicate that a hardware or software event has happened. Therefore, by handling interrupts, an application can react to external events.

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.

Let's look into a code example that陷阱Linux上的退出中断(sigquit):

-- signal_handlers.ads with 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_Signalprocedure, which displays a message to the user ("Quit request detected!") and sets a Boolean variable—Quit_Request, which is declared in the 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过程设置的。

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

Note that the code example above isn't portable because it makes use of interrupts from the Linux operating system. When programming embedded devices, we would use instead the interrupts available on those specific devices.

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,我们可以用来删除当前与给定中断关联的处理程序。

Details about the Ada.Interrupts package are out of scope for this course. We'll discuss them in a separate, more advanced course in the future. You can find some information about it in the中断ADA参考手册的附录

嵌入Softwareseries:嵌入式C开发人员的ADA

来自我们的合作伙伴

实时操作系统(RTO)及其应用程序

2021年2月25日
什么是RTO。实时操作系统(RTOS)是一种轻巧的操作系统,用于简化资源和时间限制的多任务集成和任务集成…

GAN-和硅FET的比较,基于硅FET的主动夹具反式转换器

Reproduced from 2018 Texas Instruments Power Supply Design Seminar. SEM2300, Topic 3. TI Literature Number: SLUP380. © 2018 Texas Instruments Incorporat…

外壳材料可用于粗糙环境

Problem Solution Enclosure Materials Available for Rough Environments. Metal enclosures are often not the right product for highly tough environmental…

电源密度开关

电源开关提供了从电压源或接地到负载的电气连接。我们多样化的投资组合包括来自SI…的几种拓扑结构。

ULTRA-HIGH RELIABILITY & LOW LATENCY

As you read this, 5G is rolling out across the United States.. Some people have a 5G compatible phone that can connect to an AT&T network, T-Mobile, o…

The Co-Processor Architecture: An Embedded System Architecture for Rapid Prototyping

July 6, 2021
Editor’s Note — Although well known for its digital processing performance and throughput, the co-processor architecture provides the embedded system…

Voice your opinion!

本网站要求您注册或登录以发表评论。
No comments have been added yet. Want to start the conversation?

来自我们的合作伙伴

实时操作系统(RTO)及其应用程序

什么是RTO。实时操作系统(RTOS)是一种轻巧的操作系统,用于简化资源和时间限制的多任务集成和任务集成…

GAN-和硅FET的比较,基于硅FET的主动夹具反式转换器

Reproduced from 2018 Texas Instruments Power Supply Design Seminar. SEM2300, Topic 3. TI Literature Number: SLUP380. © 2018 Texas Instruments Incorporat…

外壳材料可用于粗糙环境

Problem Solution Enclosure Materials Available for Rough Environments. Metal enclosures are often not the right product for highly tough environmental…

电源密度开关

电源开关提供了从电压源或接地到负载的电气连接。我们多样化的投资组合包括来自SI…的几种拓扑结构。

ULTRA-HIGH RELIABILITY & LOW LATENCY

As you read this, 5G is rolling out across the United States.. Some people have a 5G compatible phone that can connect to an AT&T network, T-Mobile, o…
Baidu