У меня странная проблема с простой программой Ada, которая использует пакет "GNAT.Serial_Communications".
Программа отправляет семь байтов (126, 1, 0, 0, 0, 0, 254) через устройство последовательного порта (8, N, 1 @ 115200 бод), и я проверил, что это выполняется правильно, используя анализатор logi c, подключенный напрямую к контактам последовательного порта.
Странно то, что есть два больших промежутка (колеблется между 0,6 миллисекундами и 2,4 мс) между первыми тремя отправленными байтами. Остальные байты отправляются с максимальной скоростью, как и следовало ожидать. Каждый отдельный байт идеально сформирован и отправлен с правильной скоростью. Простой между байтами - это часть, которая меняется. Другими словами, время выглядит следующим образом ...
[126]..........(big gap)..........[1]..........(big gap)..........[0][0][0][0][254]
У меня есть C версия этой программы, которая не демонстрирует такое поведение, все байты отправляются в одном пакете без пробелов.
Точно так же, cat
, отправляющий те же данные напрямую в последовательный порт из Bash, также не имеет этих больших промежутков между первыми тремя байтами.
Таким образом, кажется, что есть некоторый аспект из библиотек / сред выполнения Ada, которые вводят эту переменную задержку в середине моего потока байтов.
Для моего проекта это допустимая проблема, но я хотел бы попытаться выяснить, почему это происходит.
По-видимому, нет проблем с чтением байтов с последовательного порта, он получает все правильно.
with Interfaces; use Interfaces;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Streams; use Ada.Streams;
with GNAT.Serial_Communications;
procedure Main is
SP : GNAT.Serial_Communications.Serial_Port;
In_Data : String (1 .. 6) := "~ddddS"; -- this string literal is illustrative only
In_Buffer : Stream_Element_Array (1 .. 6);
Length : Stream_Element_Offset;
type PropIO_Octet is mod (2 ** 8);
type PropIO_Packet_Data is array (1 .. 4) of PropIO_Octet;
Packet_Start : constant PropIO_Octet := 16#7E#;
Packet_Escape_Marker : constant PropIO_Octet := 16#7D#;
Packet_Escape_XOR : constant PropIO_Octet := 16#20#;
Command_Hard_Reset : constant PropIO_Octet := 16#00#;
Command_Watchdog : constant PropIO_Octet := 16#01#;
procedure TX_Octet (Octet : in PropIO_Octet; Allow_Escape : in Boolean) is
Out_Buffer : Stream_Element_Array (1 .. 1);
Temp_Oct : PropIO_Octet := Octet;
begin
if Allow_Escape then
if (Temp_Oct = Packet_Start) or (Temp_Oct = Packet_Escape_Marker) then
Out_Buffer (Stream_Element_Offset (1)) := Character'Pos (Character'Val (Packet_Escape_Marker));
GNAT.Serial_Communications.Write (SP, Out_Buffer);
Temp_Oct := Temp_Oct xor Packet_Escape_XOR;
end if;
end if;
Out_Buffer (Stream_Element_Offset (1))
:= Character'Pos (Character'Val (Temp_Oct));
GNAT.Serial_Communications.Write (SP, Out_Buffer);
end TX_Octet;
procedure TX_Packet (
Command : in PropIO_Octet;
Data : in PropIO_Packet_Data
) is
CS : PropIO_Octet := 16#00#;
begin
TX_Octet (Packet_Start, False);
TX_Octet (Command, True);
CS := CS xor Command;
for D of Data loop
TX_Octet (D, True);
CS := CS xor D;
end loop;
CS := 16#FF# - CS;
TX_Octet (CS, True);
end TX_Packet;
begin
GNAT.Serial_Communications.Open(SP, "/dev/ttyUSB0");
GNAT.Serial_Communications.Set (
Port => SP,
Rate => GNAT.Serial_Communications.B115200,
Bits => GNAT.Serial_Communications.CS8,
Stop_Bits => GNAT.Serial_Communications.One,
Parity => GNAT.Serial_Communications.None
);
for i in 1 .. 10 loop
TX_Packet (Command_Watchdog, (0,0,0,0));
delay 1.0;
GNAT.Serial_Communications.Read (SP, In_Buffer, Length);
for i in 1 .. Length loop
In_Data (Integer (i)) := Character'Val (In_Buffer (i));
end loop;
Put_Line ("Response: " & In_Data (1 .. (Integer (Length))));
end loop;
GNAT.Serial_Communications.Close (SP);
end Main;
Я использую этот код в Ubuntu 19.10 (последние обновления) и Gnat 8.3.0. Последовательное устройство, подключенное через USB, является законным устройством FTDI.
Есть идеи, что может вызвать это?