| Версия, подходяща за принтиране
Кликни тук, за да видиш темата в оригиналният и вид |
| BG Development Форуми > .NET програмиране > Достъп до серийните портове под linux |
| Публикувано от: thrawn 28-10-2025, 16:13 | ||
| Цял ден се мъча да получа списък със серийните портове на Linux машина. Проблемът е, че SerialPort.GetPortNames() не ги вижда. Ако се опитам да отворя порт който знам, че е там (например /dev/ttyS0) се отваря успешно. Това е инсталирано на машината:
|
| Публикувано от: ici 28-10-2025, 16:39 |
| Ами мен лично .NET ме отвращава, но на Питон PySerial си ги вижда, а за C++ boost::asio проверявам /dev/ttyS* и /dev/ttyUSB* и няма проблем. |
| Публикувано от: thrawn 28-10-2025, 16:50 | ||||
| И мен ме отвращава, ама няма особен избор сега. Всичко е ОК с портовете. Работят си, имам права и се менаджират коректно от udev (добавям постоянни линкове за usb устройствата). Виждам си ги под java, но .net не ги вижда. Конкретно функцията GetPortNames() връща празен масив. Но въпреки, че не се вижда портът, ако се опитам да го отворя като изрично посоча името му се отваря без проблеми (под .net). Сега свалих платформата директно от MS и пак е същата работа
Между другото с chatgtp циклим в кръг - той твърди че трябва да имам libSystem.IO.Ports.Native.so която да ползва libudev. На една от платформите с които се мъча я има билиотеката но не ползва libudev
Но и с нея не става. След това твърди, че от версия 6 в платформата тая библиотека не била отделна и ми казва да сваля официалната исталация защото моята била орязана ... |
| Публикувано от: ici 28-10-2025, 17:13 |
| С libc.so.6 аз имах големи болки които не можах да реша. Исках да направя портабъл приложение за Linux със PyInstaller, но работеше само на моята машина заради libc.so.6. В крайна сметка го направих като *.pyz, прави venv, качва с pip каквото му трябва и така работи. |
| Публикувано от: thrawn 28-10-2025, 18:50 | ||
Вече го докарахме до тук
|
| Публикувано от: akrachev 28-10-2025, 20:15 |
| ОК - тогава правиш проба да инициализираш порт - ако има грешка - значи няма! |
| Публикувано от: thrawn 29-10-2025, 06:48 |
| Тествал съм. Знам, че имам /dev/ttyS0 на машината. GetPortNames() връща празен масив. Въпреки това пробвам да отворя порт с това име и да пратя нещо по него. Портът се отваря и данните се пращат. Днес смятам да свалям версията на платформата под 6 - 5, 4, 3 и 2 за да проверя теорията на бота за библиотеката и да видя дали в някоя версия на платформата тя няма да използва наистина libudev за да ги изброява. |
| Публикувано от: relax4o 29-10-2025, 15:26 |
| Предполагам си reference-нал правилната версия на System.IO.Ports в проекта. Аз мога да потвърдя под Mac (въпреки, че е Unix, е отделен метод, който чете, така че не е доказателство), с .NET 9 GetPortNames() ми връща устройства. По-късно ще тествам и на линукс машината, отново с 9 (а може и с 8) да видим какво ще стане и дали ще върне нещо. |
| Публикувано от: ici 29-10-2025, 15:53 |
| Едва ли имаш истински сериен порт, по-скоро имаш някакво USB CDC устройство с което няма проблеми. |
| Публикувано от: relax4o 29-10-2025, 16:36 | ||||
Това вижда dmesg, но SerialPort.GetPortNames() нищо не вижда и при мен под Линукс. Предполагам, че трябваше да ми върне поне ttyS0 в случая. Иначе има една архивирана библиотека NetCoreSerial, но при нея SerialDevice.GetPortNames() просто връща списък с всички /dev/ttyS0-N. Не съм сигурен дали това би ти помогнало за твоя случай. |
| Публикувано от: thrawn 29-10-2025, 16:59 |
| Да, ще помогне (ако проблемът е в библиотеката). Ако това което имаш работи коректно и има натив библиотеката я погледни с ldd дали ползва libudev, както твърди бота че трябва да е. |
| Публикувано от: relax4o 29-10-2025, 20:20 | ||
| Изглежда .NET-аджиите никога не са ползвали libudev. Всичко е четене на файлове и директории. Ето това е, което прави https://github.com/dotnet/runtime/blob/v9.0.10/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialPort.Unix.cs#L32-L91 Като цяло този метод не е мърдал въобще. Аз също нямам натив библиотеката, даже се учудвам, че на някоя от системите, които си тествал я има. Иначе с помощта на чатгпт ми сътвори това, което използва libudev API-а. Нямам никакъв опит с такъв тип програмиране на C#, така че адекватно мнение не мога да дам, но изглежда да работи. Само го накарах да филтрира само сериал портове.
Очевидно API-а може да се разшири и да използва мониторинг за плъг/ънплъг, но предполагам от тук натам, ако решиш този вариант гугъл и чатгпт биха ти помогнали повече от мен. Ако този метод и на теб не ти допада, то тогава NetCoreSerial изглежда ще е това, което да ти свърши работа. Надявам се да съм помогнал. |
| Публикувано от: thrawn 30-10-2025, 06:46 |
| Гитхъбът ще свърши перфектна работа. Ще го ползвам за да видя точно какво не му харесва в системата и ще го коригирам с udev. 10x |
| Публикувано от: dvader 30-10-2025, 08:11 |
| Абе тоя .нет не е ли опен сорс? Какво пречи да се види какво що и как прави? А и да не е опен-сорс за .нет има декомпилатори, включително май в самия .нет. |
| Публикувано от: relax4o 30-10-2025, 10:13 | ||
Е да де https://github.com/dotnet/runtime/blob/v9.0.10/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialPort.Unix.cs#L32-L91 |
| Публикувано от: ici 30-10-2025, 12:15 | ||
| Виж и на Питон как става: https://github.com/pyserial/pyserial/blob/master/serial/tools/list_ports_linux.py ПП. Казах на Gemini да ми направи cpp код за това от питонският файл, и го компилирах в WSL/Debian, след което закачих на Дебиана една платка с УСБ ЦДЦ със https://learn.microsoft.com/en-us/windows/wsl/connect-usb. С УСБ-тата няма проблем, но вади списък с ttyS0-7 който няма нищо общо с истината.
|
| Публикувано от: thrawn 30-10-2025, 16:39 | ||||
Проблемът е в атрибутите на устройството които драйверът му задава
За isTtyS се търси id или of_node които липсват. Ако мина в not isTtyS или isTtyGS проверките ще минат (но и двете са на база име в /sys но там пипа само ядрото). Друг вариант за да мине проверката е да се провали проверката за това дали sysTtyDir е налична. Трети вариант е репорт на бъг или да си билдна сам платформата... Давайте идеи. |
| Публикувано от: relax4o 30-10-2025, 18:09 |
| Дори и да репортнеш бъг ще паднат едни обяснения с тях, ще искат код, някакъв начин да се репликейтне, от там да решат заслужава ли си фикс и какъв да е той и накрая ще стане едно нищо. Не ти пречи да го направиш паралелно с друго решение, което вземеш, но иначе ще си чакаш. Ако ти се занимава, можеш да пробваш тази библиотека, която имплементира libudev https://www.nuget.org/packages/Dandy.Linux.Udev/1.0.0-b2. Стара е и неподдържана, но ме съмнява нещо да се е променило значително, за да не работи. Какъв е проблема да модифицираш метода за твоите нужди? |
| Публикувано от: thrawn 30-10-2025, 18:32 |
| Казусът е, че имам приложение на трета страна което трябва да тръгне. За да видя какво не му е на ред, правя отделно приложение само за тестове. Затова търся решение или на база платформа или на база ОС. Вариант с редакция на самото приложение няма. |
| Публикувано от: relax4o 31-10-2025, 11:34 |
| Ако си сигурен, че лежи на System.IO.Ports, то можеш да пробваш да модифицираш dll на това асембли и презапишеш модифицирана версия на метода. Можеш да пробваш с https://github.com/dnSpyEx/dnSpy, но нещата стават леко hacky. |
| Публикувано от: thrawn 31-10-2025, 13:43 |
| Бота предлага да направя собствен модул за ядрото който да създаде липсващите елементи. Тия дни обаче имам други задачи и тоя проект ще го оставя за другата седмица. Така ми се струва, че ще е най-чисто а и ще се поучи универсален фикс. |