Página 1 de 1
função fgets travando no CCS

Enviado:
20 Mai 2011 11:44
por Flaviofrc
Olá amigos,
Estou implementando um data logger com PIC 16F628 e um receptor de GPS, mas estou enfrentando alguns travamentos ocasionais.
O que sei sobre o fgets é que este faz chamadas sucessivas "getc" numa stream determinada até que essa encontre um caractere 0x0D se não estou enganado.
Porém o que acontece é que se o bendito caracatere não chega a função parace ficar travada, não estou usando o WDT pois o PIC precisa ficar em Sleep por um longo tempo até ser acionado.
Gostaria de saber se há alguma solução para esse travamento que não seja a utilização de timers ou WDT.
Já tentei utilizar o seguinte:
timeout=0;
while(fgets(string,stream) && timeout<30000)
Mas parece que não esta surtindo nenhum efeito.
Desde já agradeço...

Enviado:
20 Mai 2011 15:34
por ze
voce já deve estar utilizado timer para incrementar timeout né que por sinal deve ser bem rápido pois 30000 (!?) senão não vai funcionar mesmo (caso o fgets trave). ou senão tente
timeout=0;
while((fgets(string,stream)) && (timeout++<30000))
ou senão (quanto senão) crie seu proprio getc com mini timeout. vai ter que entender (eis a chance!) um mínimo de hw do pic e usar um compilador de verdade que dê acesso a ele.
char getccto()
{
int tmo=0x1000;//p.ex.
while((!RCIF)&&(tmo--));
if (tmo) return RCREG;
else return 0;
}
e crie seu proprio fgets e monte sua string com ele. este dou-me o direito de silenciar.
sucessos!

Enviado:
20 Mai 2011 15:41
por ze
voce já deve estar utilizado timer para incrementar timeout né que por sinal deve ser bem rápido pois 30000 (!?) senão não vai funcionar mesmo (caso o fgets trave). ou senão tente
timeout=0;
while((fgets(string,stream)) && (timeout++<30000))
ou senão (quanto senão) crie seu proprio getc com mini timeout. vai ter que entender (eis a chance!) um mínimo de hw do pic e usar um compilador de verdade que dê acesso a ele.
char getccto()
{
int tmo=0x1000;//p.ex.
while((!RCIF)&&(tmo--));
if (tmo) return RCREG;
else return 0;
}
e crie seu proprio fgets e monte sua string com ele. este dou-me o direito de silenciar.
sucessos!

Enviado:
20 Mai 2011 19:51
por andre_luis
lellis escreveu:...crie seu proprio getc com mini timeout...
Também sou partidário dessa opinião. Prefiro uma abordagem apenas monitorando o byte recebido quando tiver.
Nunca usei essas funções de entrada ou saída de stream da biblioteca do C. Sempre montei meu manipulador de protocolo manualmente (switch-case).
Assim não trava o processamento num loop de espera.
Aí vai um exemplo :
- Código: Selecionar todos
#int_RDA
RDA_isr()
{
DadoRecebido = getc() ;
TemDado = SIM ;
if ( TemDado )
{
TemDado = NAO ;
switch ( ContBytesRec )
{
case 0 :
PodeAvaliar = 0 ;
BufferRx[ContBytesRec] = DadoRecebido ;
if( DadoRecebido == 'C') ContBytesRec = 1 ;
else ContBytesRec = 0 ;
break ;
case 1 :
BufferRx[ContBytesRec] = DadoRecebido ;
if( DadoRecebido == 'O') ContBytesRec = 2 ;
else ContBytesRec = 0 ;
break ;
case 2 :
BufferRx[ContBytesRec] = DadoRecebido ;
if( DadoRecebido == 'M') ContBytesRec = 3 ;
else ContBytesRec = 0 ;
break ;
case 3 :
case 4 :
BufferRx[ContBytesRec] = DadoRecebido ;
ContBytesRec++ ;
break ;
case 5 :
BufferRx[ContBytesRec] = DadoRecebido ;
if( DadoRecebido == 'F') ContBytesRec = 6 ;
else ContBytesRec = 0 ;
break ;
case 6 :
BufferRx[ContBytesRec] = DadoRecebido ;
if( DadoRecebido == 'I') ContBytesRec = 7 ;
else ContBytesRec = 0 ;
break ;
case 7 :
BufferRx[ContBytesRec] = DadoRecebido ;
if( DadoRecebido == 'N') ContBytesRec = 8 ;
else ContBytesRec = 0 ;
break ;
case 8 :
BufferRx[ContBytesRec] = DadoRecebido ;
ContBytesRec = 9 ;
break ;
case 9 :
BufferRx[ContBytesRec] = DadoRecebido ;
ContBytesRec = 0 ;
PodeAvaliar = 1 ;
break ;
}
}
}
+++

Enviado:
20 Mai 2011 21:00
por luisf.rossi
Se você não quiser interpretar nada com a chegada dos dados, você pode simplesmente ir guardando tudo no buffer até chegar o 0x0D. Quando ele chegar você seta uma FLAG para a sua aplicação usar os dados. Se os dados forem meio criticos e a velocidade de comunicação for alta, sugiro usar um ping-pong buffer. Se passar uma quantidade absurda de dados, você seta um flag de time-out e faz o que precisar (e.g resetar o modulo).
Abs

Enviado:
21 Mai 2011 13:04
por Jorge_Francisco
o certo seria OU ao invés de AND no while ao comparar o que recebeu com o timeout.