Страница 1 из 1

Получить в программе список com портов в linux

СообщениеДобавлено: 06.02.2012 13:46:51
zig
Доброго дня!

Есть работающая под Win программа которая управляет двумя USB устройствами через виртуальные com порты. Используется Synaser. Все работает, всем доволен.
Вот появилась необходимость портировать ее под linux. Запустил компиляцию в Ubuntu и о чудо, все сразу скомпилячилось без косяков!
Но один момент завязан именно на win: я получал через реестр список активных в системе com портов и выводил их в список для выбора пользователем. Теперь стоит та же задача сделать это под linux.
В интернете без труда нашлись команды для этого дела:
Код: Выделить всё
# dmesg | grep tty
serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
serial8250: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
00:09: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
00:0a: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A


Но так как я новичок в linux то мне совершенно непонятно как вызвать эту команду из программы и получить выдаваемые ею данные?

Помогите примером!

Re: Получить в программе список com портов в linux

СообщениеДобавлено: 06.02.2012 14:31:45
Mr.Smart
Проще пробежаться по файлам /dev/ttyS*

Добавлено спустя 4 минуты 59 секунд:
Вот кусок кода из моего "поделия" для *nix систем:
Код: Выделить всё
procedure TMySerialPorts.MakeList(aFilter: String);
var
p: TMySerialPort;
sr: TSearchRec;
begin
  if FindFirst(aFilter,faAnyFile,sr)=0 then
  repeat
   if (sr.Attr and faDirectory)=0 then
    begin
     if Pos('.',sr.Name)<>0 then
      Continue;
     p:=TMySerialPort.Create;
     p.fDev:='/dev/'+sr.Name;
     p.fName:=sr.Name;
     fList.Add(p);
    end;
  until FindNext(sr)<>0;
  FindClose(sr);
end;

procedure TMySerialPorts.BuildList;
begin
  try
   Clear;
   {$ifdef linux}
   MakeList('/dev/modem*');   // Find Modem link
   MakeList('/dev/ttyS*');    // Find Comm Ports
   MakeList('/dev/ttyUSB*');  // Find USB to Serial
   MakeList('/dev/ircomm*');  // Find IRDA to Serial
   MakeList('/dev/rfcomm*');  // Find Bluetooth to Serial
   {$endif ~linux}
   {$ifdef freebsd}
   MakeList('/dev/ttyd*');    // Find Comm Ports with DCD Dial-in
   MakeList('/dev/cuad*');    // Find Comm Ports wiout DCD Call-out for FreeBSD 6
   MakeList('/dev/cuaa*');    // Find Comm Ports wiout DCD Call-out for FreeBSD 5.X
   MakeList('/dev/ttyU*');    // Find USB to Serial with DCD Dial-in
   MakeList('/dev/cuaU*');    // Find USB to Serial wiout DCD Call-out
   {$endif ~freebsd}
   Sort;
  except
  end;
end;

Re: Получить в программе список com портов в linux

СообщениеДобавлено: 06.02.2012 14:54:40
zig
Mr.Smart писал(а):Проще пробежаться по файлам /dev/ttyS*

Такой вариант меня к сожалению не устроит: у меня например там два десятка ttyS* файлов! Если дать их юзеру все перебирать он думаю обидится. :)

Добавлено спустя 10 часов 16 минут 58 секунд:
А вообще есть механизм запуска линуксовых команд и получения их результатов в программе?

Re: Получить в программе список com портов в linux

СообщениеДобавлено: 07.02.2012 08:02:46
Brainenjii

Re: Получить в программе список com портов в linux

СообщениеДобавлено: 07.02.2012 11:40:18
zig
Brainenjii писал(а):http://wiki.lazarus.freepascal.org/Executing_External_Programs/ru

Спасибо!

Re: Получить в программе список com портов в linux

СообщениеДобавлено: 12.02.2012 16:02:52
zig
Подытожу то что получилось:
Работал с USB устройствами на базе FTDI под Ubuntu 11.10. Их драйвера давно встраиваются в ядро и работают без проблем на лету подключая устройство.
Автоматом создавать список активных портов не стал - долго и муторно. Простых решений (как под винды, где можно спокойно пройтись по веткам реестра) не нашлось.
Просто решил выдавать юзеру выборку из логов ядра относящуюся к подключению USB следующим кодом (а дальше пусть он вручную выбирает нужные):
Код: Выделить всё
AProcess := TProcess.Create(nil);
AStringList := TStringList.Create;
AProcess.CommandLine := 'bash -c "/bin/dmesg | grep to.ttyUSB"';
AProcess.Options := AProcess.Options + [poUsePipes, poNoConsole];
AProcess.Execute;
AStringList.LoadFromStream(AProcess.Output);
if AStringList.Count > 0 then
    for i:=0 to AStringList.Count-1 do Memo1.Lines.Insert(0,AStringList[i]);
if AStringList.Count = 0 then Memo1.Lines.Insert(0,FormatDateTime('hh:nn:ss',now)+': Не найдено активных портов USB.');
AStringList.Free;
AProcess.Terminate(i);
AProcess.Free;

Правда процессы bush по моему не терминируются и висят в списке процессов.

Недостаток - если постоянно перетыкать USB устройства то логи будут сильно замусорены и их надо дополнительно фильтровать.

Вообще оказалось что с ttyUSB* все проще чем с ttyS*, так как первых в моей системе изначально нет (пока не подключишь USB устройство), а вторых (ttyS*) уже по умолчанию пару десятков. Поэтому можно как советовал выше Mr.Smart пробежаться по /dev/ttyUSB* файлам. Но я не знаю что творится на машине заказчика и поэтому пока оставил так.