Обмен данными между "Virtualbox guest OS COM port" and "Wind
От: grizlyk1  
Дата: 01.11.22 10:59
Оценка:
Я тут быстро репост сделаю методом "copy&paste" (не буду переводить много буков), а то люди в месте исходного размещения беспокоятся (так некрасиво улыбаются в мой адрес, что это приводит к юридическим последствиям (ограничения доступа и предоставления информации)) и как бы отвергают оплату за потребленные услуги. Они решили платить за все сами. Что же, так тому и быть (приятно больше не чувствовать себя должным)!

В кратце проблема в том, что есть VirtualBox отображающий гостевые UART 8250 порты на Windows хосте как "//./pipe" и VirtualBox работает как сервер для "//./pipe". На клиентской стороне такие порты могут быть открыты через такой простой интерфейс как <stdio> (что очень привлекательно).

Однако реально пользователи не могут обмениваться данными с такими гостевыми портами, потому что <stdio> у них не работает как надо, например потому что сервер VirtualBox устанавливает ограничения на количество подключений к "//./pipe". Как это исправить?

Оказывается <stdio> обладает рядом особенностей, которые пользователь в 99% случаев обычно никогда не встречает, но вот pipe требует особенной работы с <stdio>, и эти отличия не описаны ни в референсе для <stdio>, ни в книжках по posix. Я не видел. (подсказка: для программиста это интересная информация).

************
Часть первая
************
Assume you map Virtualbox guest OS COM port to Windows host pipe (\\.\pipe\*) and Virtualbox is server side of pipe.

It is possible to read/write Windows host pipe from client side (from Windows program) by <stdio>, i.e. access the pipe (and the guest COM port) as regular stream (via FILE, fopen, fgetc, fputc, etc).

1. The client side pipe behaviour details can depend on conventions offered by Virtualbox server side pipe implementation.

If you are not sure about the server side pipe considerations, you can find unexpected troubles while transfer data, among them:
— client side pipe terminates to receive rx data (windows program begin to read 0x00);
//the following code will not help to 'read after write'
int
    //begin to read 0x00 here
    rx_ch= fgetc(fc); 
if(rx_ch == EOF)break;

— guest machine engine can hang guest OS window during COM port exchange via pipe (probably by pipe queue overflow);
— etc.

2.
By tests it was found, that there is the way to read/write client side pipe in half-duplex mode via single FILE handler opened for read/write by:
— for mingw pipe win directory is visible as "//./pipe"
— fopen pipe in "rb+" mode;
— mandatory calls fseek (with correct offset) between any read and write pipe operation.

Though the "fseek before append" is always mandatory for "r+" mode FILE, the fseek does nothing visible in pipe, but sets internal pipe data into correct state to carry out read and write pipe operation.

3.
example
enum{ PR_SYN= 0x16U };

fc= fopen("//./pipe/dos1","rb+"); assert(fc);
fi= fopen("./isw","rb"); assert(fi);
fo= fopen("./osw","ab"); assert(fo);

//
long
    fc_fpos_rx= 0;

for(;;){

    //rx
    assert( !fseek(fc,fc_fpos_rx,SEEK_SET) );

    int
        rx_ch= fgetc(fc); 
    if(rx_ch == EOF)break;

    fc_fpos_rx= ftell(fc); assert( fc_fpos_rx != -1L );

    if(rx_ch != PR_SYN)fputc(rx_ch,fo);

    //tx
    assert( !fseek(fc,0,SEEK_END) );
            
    int
        tx_ch= fi? fgetc(fi): PR_SYN; 
    if(tx_ch == EOF)tx_ch= PR_SYN;

    fputc(tx_ch,fc);
}

на фото: вот так работает такая программа
Отредактировано 01.11.2022 11:35 grizlyk1 . Предыдущая версия . Еще …
Отредактировано 01.11.2022 11:28 grizlyk1 . Предыдущая версия .
virtualbox pipe serialport
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.