Página 1 de 1

função fgets travando no CCS

MensagemEnviado: 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...

MensagemEnviado: 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!

MensagemEnviado: 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!

MensagemEnviado: 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                                            ;
      }
   }
}


+++

MensagemEnviado: 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

MensagemEnviado: 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.