função fgets travando no CCS

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

função fgets travando no CCS

Mensagempor Flaviofrc » 20 Mai 2011 11:44

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...
Flavio
Flaviofrc
Byte
 
Mensagens: 111
Registrado em: 16 Out 2006 17:32
Localização: São Paulo

Mensagempor ze » 20 Mai 2011 15:34

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!
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Mensagempor ze » 20 Mai 2011 15:41

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!
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Mensagempor andre_luis » 20 Mai 2011 19:51

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


+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Mensagempor luisf.rossi » 20 Mai 2011 21:00

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
luisf.rossi
Byte
 
Mensagens: 109
Registrado em: 28 Nov 2010 12:48
Localização: São Paulo, SP

Mensagempor Jorge_Francisco » 21 Mai 2011 13:04

o certo seria OU ao invés de AND no while ao comparar o que recebeu com o timeout.
Avatar do usuário
Jorge_Francisco
Dword
 
Mensagens: 1009
Registrado em: 12 Out 2006 09:53
Localização: Rio de Janeiro


Voltar para PIC

Quem está online

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

cron

x