Entrar    Registrar

Comm Seria Lazarus dando erro segmentação

Programação Delphi e Pascal

Moderadores: guest2003, 51

  • Autor
    Mensagem

Comm Seria Lazarus dando erro segmentação

Mensagempor RobL » 05 Jun 2008 19:37

Não entendí por que recebo um sinal de violação de segmento SIGSEGV quando
não recebo byte algum pela porta serial no winxp. O mesmo não ocorre com
o win98SE. O sinal recebido é o null (ASCII=0h). Sem nada na porta (só PC).
Quando recebo algo diferente de null não dá o erro acima.

Ambiente:
WinXp sp2
LAZARUS v0.9.24
Componente Tcomport (para lazarus).

Código abaixo dá erro:

var
DatEnt: String;
Count: integer;
RelStr: String;

begin
If Form1.ComPort1.Connected = false Then //abre a porta
begin
Form1.ComPort1.Open;
end;
// Transmite string
Form1.ComPort1.ClearBuffer(True,True); // limpa buffer tx e rx
Form1.ComPort1.WriteStr(RelStr); // transmite o pacote com data hora
//Aguarda recepcao dos dados

Sleep(150); //Quanto maior for o pacote esse tempo deve aumentar
Count:=Form1.ComPort1.InputCount;

Form1.ComPort1.ReadStr(DatEnt,Count); // pega dados no buffer
end;
;-------------

Com o código abaixo funciona. Observar que mudei a variável para array
de byte e a função para Write e nao WriteStr. Por que o codigo acima não funciona?

var
DatEnt: array [1..255] of Byte;
Count: integer;
RelStr: String;
begin
If Form1.ComPort1.Connected = false Then //abre a porta
begin
Form1.ComPort1.Open;
end;
// Transmite string
Form1.ComPort1.ClearBuffer(True,True); // limpa buffer tx e rx
Form1.ComPort1.WriteStr(RelStr); // transmite o pacote com data hora
//Aguarda recepcao dos dados

Sleep(150); //Quanto maior for o pacote esse tempo deve aumentar
Count:=Form1.ComPort1.InputCount;

Form1.ComPort1.Read(DatEnt,Count); // pega dados no buffer
end;
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor RobL » 05 Jun 2008 20:03

Mudei a função para Read e antes ReadStr e não Write com acima.
Aliás, cabe observar que transmitindo com a função WriteStr não gera erro. O erro é na ReadStr, ao receber.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor Wagner de Queiroz » 05 Jun 2008 21:15

voce tentou usar a biblioteca Synaser para comunicacao serial?

Qual é seu MSN? eu tambem venho usando o Lazarus com serial. Eu estou usando o Synaser só tenho problemas para saber se tem dado para ler da serial pois estou perdendo dados.
Seja Livre, Use Linux
Avatar do usuário
Wagner de Queiroz
Word
 
Mensagens: 872
Registrado em: 11 Out 2006 13:38
Localização: Barueri-SP

Mensagempor RobL » 05 Jun 2008 23:17

Olá Wagner.
Minha aplicação é muito simples e estou testando em baixa velocidade 9600b/s. Da forma que narrei acima, funciona sem perda de dados.
No entanto, tenho testado com pacote muito pequeno em torno de 20 bytes cada TX/RX.

O único problema que surgiu foi com a função ReadStr() ao receber coisa alguma, silêncio total na linha, sem ruído, da erro externo de violação de segmento!!! Isto só ocorre com o WinXP, com o win98SE não ocorre.
Resolví o problema, sem entender o por que, usando a função Read() cujo parâmetro passa a ser uma array de byte e não string (curiosamente, por definição, string é um array de bytes!!!). Conforme lhe disse, funciona perfeitamente, sem erro de recepção ou mesmo tx.
Mais adiante vou rodar o mesmo no Linux, mas não vou poder usar o mesmo componente.

Não conheço a biblioeca Synaser.

Não sei qual a complexidade de sua aplicação. Se for simples como a minha, perda de dados deveria ser problema de baudrate, no caso de ser assyncrona.
Qual o ambiente no qual está havendo perda de dados (PC <-> microcontrolador )?
Você testou seu aplicativo entre 2 pcs?
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor Wagner de Queiroz » 07 Jun 2008 09:28

Quer conhecer o Synaser?

O link abaixo é da pagina de Download. O que peca nesta biblioteca é a documentacao. Os exemplos sao relativos a modem.


http://www.ararat.cz/synapse/doku.php/download


O link direto da biblioteca é:
http://synapse.ararat.cz/files/synaser.zip


A respeito da aplicacao, eu tenho testado diretamente com hardware ligado ao PC. No hyperterminal funciona perfeitamente.

Uma das aplicacoes é um simples loopback que fiz no MikroPascal eu envio um byte e ele envia o mesmo byte de volta invertido.

A segunda aplicação é mais legal. É o kit MSP430 da Texas que envia a cada segundo uma string com a temperatura. No hyperterminal funciona perfeitamente tambem. tudo a 9600.

Eu estou ediando um material de treinamento de delphi e queria usar o synaser pois o Turbo Delphi explorer nao aceita instalacao de componentes. O meu Delphi tem licença mas o problema sao os alunos que nao podem ou tem que usar o Lazarus que pode nao aceitar alguns componentes do delphi. Particularmente eu gosto do AsyncPro que agora é free no TurboDelphi mas nao tentei instalar ele no Lazarus alem do mais que o AsyncPro nao funcionaria no Linux.

Eu vou testar o synaser entre dois computadores mas acho que esta alternativa tambem vai dar xabú.
Seja Livre, Use Linux
Avatar do usuário
Wagner de Queiroz
Word
 
Mensagens: 872
Registrado em: 11 Out 2006 13:38
Localização: Barueri-SP

Mensagempor RobL » 07 Jun 2008 18:05

Eu lí um outro post seu a repeito do que está acontecendo no seu caso e se entedí é que você recebe os dados mas não consegue extraí-los.
Quanto a perda de alguns caracteres que comprovadamente transitaram, pode ser o uso de null sendo bytes, na qual fazemos uma conversão de tipo inadequada para string (ou derivados). Cada vez que o "byte"null deveria ser lido como 0, acaba sendo interpretado como terminação de string e perdido dando resultado imprevisível.

Como estou com a mão na massa, vou tentar rodar com o Synaser e lhe reportar. O problema é que sou eterno principiante em Delphi, Lazarus e Free Pascal, pois programo eventualmete e tenho sempre que relembrar o óbvio.

Baixei o Synaser e morrí na praia. Rapaz não consigo o trivial no Lazarus.
Já informei onde coloquei o synaser e ele não encontra essa unit.
Coloquei inclusive, diretamente no diretório C:\lazarus\components\Synase\source\ e nada. Alguma sugestão.
Já usei também acrescer path pelo menu Enviroment > code tools option e nada. Qual é a mágica ou a besteira?
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor RobL » 07 Jun 2008 18:16

Só mais um detalhe sobre seu problema:
Se está recebendo os dados, com certeza e não dá para ler é algo realmente estranho.

Veja, o synaser é syncrono. O autor usa o termo syncrono se referindo ao fato de que não é necessário um evento para receber dados. Desta forma, os dados vão chegando e entrando para algum buffer. Quando lidos vai cuspir tudo de uma vez.

Procure então usar um mesmo pacote (mesmo tamanho) com caracteres ou bytes sempre iguais (mesma informação) e, mesmo não tendo muito sentido, no caso do synaser, crie um retardo para a resposta do mesmo pacote. Veja o que acontece. No loopback ele volta instantaneamente. Se for XP e serial há problema aí. No XP a serial não tem tratamento VIP pelo Kernel pois é algo a ser abandonado. Somente nas últimas versões de winxp a serial foi melhorada (quebra galho) , devido a reclamações de usuários. Mas o problema maior estava no tempo assimétrico de início de transmissão. Em outras palavras, as interrupções das antigas seriais são menosprezada pelo Kernel, fizeram algo similar a reduzir sua prioridade.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor RobL » 07 Jun 2008 20:08

Como não conseguí fazer encontrar o synaser pelo path coloquei tudo dentro do projeto.
Compilou mas está dando erro.
Agora é que vou começar.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor Wagner de Queiroz » 08 Jun 2008 00:17

coloque as units da pasta source na pasta do seu projeto e dai ele vai compilar.
Seja Livre, Use Linux
Avatar do usuário
Wagner de Queiroz
Word
 
Mensagens: 872
Registrado em: 11 Out 2006 13:38
Localização: Barueri-SP

Mensagempor RobL » 08 Jun 2008 10:16

Rodou perfeito, tanto no WinXp quanto no Linux.
Como estou com um micro transmitindo bytes e não ASCII, tenho que entender melhor as funções e seus tipos, pois a mesma função que rodou no WinXP não fez o trabalho no Linux, apesar de não dar erro. O problema está somente na conversão de tipo.

O Synaser é fera.
No Linux fiz uma experiência em 9600 bps que mostra bem o que é o synaser, sem eventos, no meu programa.

Fiz ele coletar byte a byte de um pacote com 11 bytes e não houve nenhum erro em dezenas de tentativas. Em outras palavras, para ficar bem claro, o pacote foi enviado pelo micro e o synaser coletou, através de repetidas chamadas à mesma função, cada byte sem perder um na sequência.

Usei a função RecvByte(1000) várias vezes para ver o comportamento do programa.
Essa função ficará tentando receber até 1 segundo quando gera timeout.
Assim que recebe 1 byte termina e então chamei outra vez associado a outro byte.
Incrível que todos foram coletados na ordem que foram enviados.
C, D, E : Byte ;
C:= ser.RecvByte(1000);
D:= ser.RecvByte(1000);
E:= ser.RecvByte(1000);

Isto mostra a que veio o synaser e é o bicho para comunicação pela antiga serial.
Cabe lembrar que apesar da baixa velocidade de transmissão usada acima, outros códigos baseados em componentes, etc, levam bom tempo para abrir, fechar porta, respnder a eventos e dificilmente conseguiriam ler byte a byte de um pacote sem perder
vários bytes.

Nota: O microcontrolador que estou testanto está com baude fixo em 9600bps daí o uso em 9600 neste teste.

Agora sim, cheguei tarde no synaser, pelo menos 2 anos de atrazo, mas Linux e serial em modo gráfico com essa eficiência e simplicidade é show!!!! O mundo vai acabar!!!
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

BREAKING NEWS!

Mensagempor Wagner de Queiroz » 08 Jun 2008 10:40

É!

Viva o Synaser e o Lazarus.

Bem, eu ainda estava pelejando no Synaser e delphi e Lazarus, mas fico muito contente que voce tenha conseguido fazer o trem funcionar e para meu desespero ter conseguido fazer tudo funcionar. No meu caso a minha aplicacao de teste era uma string sem caracteres especiais, somente o retorno do carro e avanco de linha. De toda forma vou testar a forma que voce fez. RobL de onde vc é? podemos trocar MSN?

temos os mesmos objetivos talvez possamos trocar algumas figurinhas. o meu msn esta num botao abaixo da mensagem.

Se voce gostou do synaser, é pq nao conheceu o synapse que é a biblioteca para comunicacao TCP/IP do mesmo autor.


Otima a sua ideia do RecByte! Agora estou contente com o Synaser.

while Serial.CanRead(1) do
begin
Lido:=serial.RecvByte(1000);
Form1.Label1.caption:=TimeToStr(now)+chr(Lido);
Form1.memo1.Text:=Form1.Memo1.Text+chr(Lido);
Application.ProcessMessages;
end;
Seja Livre, Use Linux
Avatar do usuário
Wagner de Queiroz
Word
 
Mensagens: 872
Registrado em: 11 Out 2006 13:38
Localização: Barueri-SP

Voltar para Delphi e Pascal

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

cron