VirtuOS Operating System ======================== "Documento sobre o tratamento e uso das portas seriais" 1. Introducao ------------- O VirtuOS suporta portas seriais no padrao UART 8250, 16450 e 16550. Todos esteS modelos de UARTs sao muito parecidos com a unica excecao ficando por conta da velocidade maxima suportada. O modelo 8250 (nao mais utilizado) nao contem nenhum FIFO e, portanto, nao e' recomendado para velocidades superiores a 19200 bps. Os modelos 16450 e 16550 possuem FIFO e podem portanto serem usados em velocidades ate' 115200 bps. As portas seriais nos padroes descrito sao normalmente denominadas "Portas COM". O VirtuOS detecta e suporta as portas COM presentes em: . Na propria placa mae; . Em placas multi-seriais instaladas nos conectores PCI; . Dispositivos serias USB que utilizem os chips compativeis com o PL2303 ou o FDTI. 2. Sobre enderecos de Entrada e Saida e Interrupcoes ---------------------------------------------------- Cada porta COM tem associada para si um endereco de entrada e saida (endereco de I/O) unico e uma linha de interrupcao (IRQ) que pode ser compartilhada com outras portas COM ou mesmo com outros dispositivos. As portas COM disponiveis na propria placa mae tem, normalmente, enderecos de I/O e IRQ padronizados: Porta Endereco I/O IRQ COM1 3F8 4 COM2 2F8 3 Muito embora nao se encontre hoje em dia placas mae com portas COM3 e COM4, os enderecos de I/O e IRQ destas tambem sao, por compatibilidade com o passado, padronizados: Porta Endereco I/O IRQ COM3 3E8 4 COM4 2E8 3 As portas COM1 e COM2 sao automaticamente detectadas pelo VirtuOS e nao precisam ser explicitamente declaradas no arquivo VIRTUOS.CFG. Quando se utiliza portas COM em placas PCI multi-seriais, o endereco de I/O associado a cada uma das portas da placa bem como o IRQ sao automaticamente assinalados pelo BIOS pelo mecanismo de PnP. No caso de dispositivos seriais USB, o driver de USB do VirtuOS virtualiza o dispositivo inserido para emular uma porta COM. Ver 2.3 adiante para maiores detalhes. 2.1 Definindo uma porta COM especificando seu endereco de I/O e IRQ ------------------------------------------------------------------- Como dito anteriormente, as portas COM1 e COM2 sao automaticamente detectadas pelo VirtuOS, desde que as mesmas estejam no endereco de I/O e IRQ padronizados para estas. As portas seriais das placas multi-seriais PCI sao automaticamente detectadas e, portanto nao ha' necessidade de se definir o endereco de I/O e IRQ das mesmas. Se houver no sistema uma porta serial que nao seja padrao COM1 ou COM2 e nem esteja no barramento PCI e' necessario defini-la no arquivo VIRTUOS.CFG atraves do comando SERIAL. A sintaxe deste comando e' a seguinte: SERIAL=com_name,ioadd,irq onde com_name e' o nome da porta COM (Ex: COM4, COM8, etc) ioadd e' o endereco de I/O da porta em hexadecimal (ex: A38) irq e' a linha de interrupcao associada `a porta (em decimal) Exemplo: SERIAL= COM3,3e8,4 2.2 Associando uma porta COM a uma porta de uma placa PCI multi-serial ---------------------------------------------------------------------- O VirtuOS detecta automaticamente a presenca de placas multi-seriais no barramento PCI e, atraves do mecanismo de PnP obtem os enderecos de I/O e IRQ associados `as portas. As portas encontradas pelo mecanismo PnP recebem a denominacao PNP1, PNP2, ... PNPn. Cabe ao usuario associar as portas PNP `as portas COM. Exemplo: SERIAL= COM5,PNP1 - Indica que a porta COM5 esta' associada aa primeira porta serial detectada pelo mecanismo PnP. 2.3 Associando um dispositivo serial USB a uma porta COM -------------------------------------------------------- Quando o sistema detecta um dispositivo serial USB, e nao existe nenhum comando no arquivo de configuracao (VIRTUOS.CFG) especificando enderecos de I/O e IRQ especificos para tais dispositivos, o driver USB virtualiza o dispositivo inserido para se apresentar ao sistema como portas COM1 a COM4. Por exemplo, em um sistema onde ja' exista portas COM1 e COM2 na placa mae, o driver USB ira' assinalar o primeiro dispositivo inserido como sendo porta COM3 e o segundo como COM4. Se o usuario desejar especificar qual porta COM e seus respectivos parametros devem ser associados ao(s) dispositivo(s) seriais USB, e' necessario defini-los no arquivo VIRTUOS.CFG usando o seguinte comando: SERIAL=com_name,ioadd,irq,USBn onde com_name e' o nome da porta COM (Ex: COM4, COM8, etc) ioadd e' o endereco de I/O da porta (em hexadecimal) irq e' a linha de interrupcao associada `a porta (em decimal) USBn e' o numero do dispositivo USB ao qual se deseja associar esta definicao. Pode ser USB1 a USB8. Exemplo: SERIAL= COM5,3e8,4,USB1 SERIAL= COM6,2e8,3,USB2 IMPORTANTE: Quando o primeiro dispositivo serial USB e' inserido, este sera identificado como USB1, o segundo como USB2 e assim por diante, independentemente da porta USB onde tal dispositivo foi inserido. Entretanto, se o sistema e' inicializado com os dispositivos ja' inseridos estes serao registrados no sistema em uma ordem especifica, baseada no endereco da porta USB. O sistema varre as portas a partir daquela com o endereco USB mais baixo para o mais alto. Entretanto, os gabinetes nao indicam externamente qual e' o endereco da porta USB. Portanto, se voce vai montar um sistema onde, por exemplo, um dispositivo especifico deve ser associado como COM5 e outro como COM6, o unico metodo de garantir tal associacao e' inserir os dispositivos e fazer boot no sistema e verificar se foram adequadamente associados. Se nao, troque os dispositivos para outras portas USB ate' que a associacao desejada seja atingida. Uma vez feito, todo BOOT ira' assinalar as portas seriais na mesma ordem. 3. Uso das portas seriais pelo sistema operacional -------------------------------------------------- Quando as portas seriais sao usadas como terminais ou impressoras do sistema nenhum tipo de atencao especial deve ser tomado a nao ser definir, no arquivo VIRTUOS.CFG, os terminais e impressoras como associados `as portas COM correspondentes. Adicionalmente, deve-se definir os parametros funcionais (baudrate, etc,) usando os comandos MODE (para terminal) e MODEP (para impressora). 4. Uso das portas serias por device drivers de terceiros ou por programas Existem, basicamente, duas formas de utilizacao das portas seriais: 1. Acesso direto `a porta. Este e' o metodo utilizado pelos drivers normalmente carregados nas maquinas virtuais como, por exemplo, no caso das impressoras fiscais, PIN-Pads, etc. 2. Acesso como arquivo. Este metodo e' mais formal e recomendado. Neste caso a porta serial e' tratata como um arquivo onde o programa abre a porta COM, le e escreve na mesma e ao final fecha-a. 4.1 Acesso direto `a uma porta COM ---------------------------------- Diversos programas e device drivers escritos para MS-DOS utilizam a estrategia de acesso direto `a porta COM. Para que isto funcione sob o VirtuOS, que e' um sistema multi-tarefa - com diversas maquinas virtuais, e' necessario garantir que os pedidos de interrupcoes gerados pela porta COM sejam adequadamente direcionados para maquina virtual correta. Temos 3 cenarios para este caso: 1. O IRQ associado `a porta COM nao e' utilizado por nenhum outro dispositivo do sistema, seja este outra porta COM ou qualquer outro tipo de dispositivo; 2. O IRQ e' compartilhado entre a porta COM e outro(s) dispositivo(s) do sistema. 3. O IRQ e' compartilhado por diversas portas COM; O metodo correto de se alocar uma porta COM a uma maquina virtual e' atraves do comando USRCOM, que atende a todos os 3 cenarios descritos acima. A sintaxe a ser usada e': USRCOM porta+, onde porta e' o numero da porta COM e o simbolo '+' indica que ela devera ser fixada `a maquina virtual corrente. Exemplo: Suponha que antes de se executar um programa de automacao comercial seja necessario carregar o driver imp.sys que acessa diretamente a porta serial COM1. A sequencia de comandos correta e': USRCOM 1+ aloca a porta COM1 para esta maquina virtual ADDRV imp.sys [args] carrega o driver imp.sys passando os eventuais argumentos exigidos por este driver MYAPP Carrega o aplicativo MYAPP USRCOM -1 Libera a porta COM1 (opcional). Quando a maquina virtual for encerrada todas as portas COM alocadas a esta sao automaticamente liberadas. 4.1.1 Usando o comando USRIRQ ----------------------------- E' possivel alocar um IRQ para uma maquina virtual. Entretanto este metodo so' pode ser usado nos cenarios 1 e 2 descritos anteriormente. No caso do cenario 3, onde diversas portas COM compartilham o mesmo IRQ, aloca-lo a uma maquina virtual especifica impede o funcionamento das demais portas COM com o mesmo IRQ. Isto so deve ser feito no caso onde o driver a ser carregado for tratar TODAS as portas seriais associadas ao IRQ sendo alocado. A alocacao do IRQ neste caso o no cenario 1, onde o IRQ nao e' compartilhado com nenhum outro dipositivo, e' feita utilizando-se a sintaxe: USRIRQ n+, onde n e' o numero do irq, em decimal. No caso do IRQ ser compartilhado com outros dispositivos (cenario 2), deve-se utilizar a seguinte sintaxe: USRIRQ n*, onde n e' o numero do irq, em decimal. Reforcamos a recomendacao de sempre alocar uma porta COM a uma maquina virtual utilizando o comando USRCOM ao inves do comando USRIRQ. 4.2 - Compatibilidade com progras/drivers que nao suportem o chip com FIFO Alguns drivers, especialmente os mais antigos, nao esperam que o chip controlador de serial tenha o FIFO habilitado. O VirtuOS so' habilita o FIFO caso a porta COM esteja definida no sistema e o comando MODE especifique baud-rate 19200 ou superior. Neste caso o chip estara' com o FIFO habilitado e isto pode evitar o funcionamento dos drivers que nao o suportam. Para garantir que o FIFO da porta COM seja desabilitado, basta executar o seguinte comando antes de carregar o programa ou driver que ira usar a porta COM: MODE COMn 8250, onde "n" e' o numero da port com. 5. Utilizando a porta COM como arquivo -------------------------------------- O VirtuOS permite que as portas COM sejam tratadas como arquivos, onde o programa abre a porta, le e escreve na mesma e ao final fecha-a. Para isto e' necessario carregar as rotinas de suporte para modo arquivo na maquina virtual. Isto se faz utilizando-se o comando MODE no seguinte formato: MODE com_port baud-rate,paridade,bits_de_dados,bits_de_parada onde: com_port: nome da porta COM (COM1, COM5, etc) baud-rate: velocidade de transmissao (max= 115200 bps) paridade: controle de paridade: n= nenhum, o= impar, e= par bits_de_dados: tamanho da caracter em bits (5, 7 ou 8) bits_de_parada: numero de bits inserido ao final cada caracter (1 ou 2) Exemplo: MODE COM2 9600,n,8,1 Carrega o suporte ao acesso a porta COM2 para ser usada pelo metodo de acesso como arquivo. Quando a porta for aberta, a porta COM2 sera' alocada `a maquina virtual e programada para operar na velocidade de 9600 bps, com 8 bits de dados, sem paridade e com 1 bit de parada. Se no momento da abertura a porta COM2 estiver em uso por outra maquina virtual o OPEN retornara' com erro. >>>>> Exemplo de acesso `a porta COM2 usando a linguagem CLIPPER: ... arquivo = fopen("COM2",2) *Abre aporta COM2 no modo Escrita/Leitura ... fwrite(arquivo,"123",3) *Envia a cadeia "123" para a porta ... fclose(arquivo) *Fecha a porta COM2. >>>>> Exemplo de acesso `a porta COM2 usando a linguagem "C". Neste exemplo temos uma impessoa fiscal DARUMA FS600 conectado `a porta e leremos o Total Geral (GT) que e' o comando [FS]R<200>001 #include void main(void) { int i; FILE *file; unsigned char cmd[]={0x1c, 'R', 200, '0', '0', '1', 0, 0}; unsigned char rcv[100]; /* Abre a porta em modo update */ if ((file=fopen("COM2", "r+b")) == NULL) { printf("Nao achou COM2\n"); return; } /* Marca stream para nao usar buffer */ setvbuf(file, NULL, _IONBF, 0); /* computa BCC */ for (i=0, i < 6; i++) cmd[6] ^= cmd[i]; /* Envia o comando */ if (fwrite(cmd, 1, 8, file) != 8) { printf("Erro no envio\n"); fclose(file); return; } /* Aguarda a resposta */ while ((len=fread(rcv, 1, 100, file)) == 0); /* Exibe no video o que chegou */ fwrite(rcv, 1, len, stdout); fclose(file); } 6. Suporte ao uso de das portas COM atraves dos servicos oferecidos pelo BIOS ----------------------------------------------------------------------------- Os BIOS dos equipamentos oferecem um conjunto de funcoes atraves de uma API via INT 14H que permite programar, ler e escreve na porta. Estes servicos sao basicos e improprios para velocidades de transmissao superiores a 9600 pois a recepcao nao se da' via interrupcao. O comando MODE descrito acima [5], alem de adicionar o suporte ao uso das portas com arquivo, implementa uma outra versao dos servicos equivalentes ao do BIOS INT 14H, com tratamento de recepcao por interrupcoes. Para ativa-lo basta carregar o comando MODE da mesma forma como descrito em [5]. *** FIM DO DOCUMENTO ***