Como selecionar um "stream" nesta estrutura...

Programação C em geral

Moderadores: 51, guest2003

Como selecionar um "stream" nesta estrutura...

Mensagempor zielpunkt » 13 Ago 2007 18:29

Seguinte, povo do 'C',

Preciso de uma luz (CCS). Eu recebo tres cadeias de dados distintas e pra isso utilizo tres seriais que alimentam um buffer: streams A, B e C, sendo duas por SW e uma por HW, o que não vem ao caso. Quando preciso receber (ou transmitir), chamo uma rotina específica pra cada stream. Funciona beleza, mas o código fica muito repetitivo. Agora, eu queria implementar uma rotina única (uma pra RX e uma pra TX), onde eu pudesse passar na chamada com qual das streams eu desejo me comunicar. Já fiz algo usando switch/case, mas imagino que exista algo mais prático. Por se tratarem de constantes, eu não sei como referenciá-las. Seria mais ou menos isso para RX, por exemplo:

Código: Selecionar todos

int getdata(pointer* p, stream_desejada)
{
   loop
   .
   if(kbhit(stream_desejada)) c=(fgetc(stream_desejada)); //
   .
   armazena_c_
   trata_timeouts_etc_etc_
}

while(1)
{
   .
   getdata(buffer, A); //
   .
   .
   getdata(buffer, B); //
   .
   .
   getdata(buffer, C); //
   .
   .
}



Se puderem ajudar o pobre colega que não manja muito de 'C' (e nem de 'D', 'E' ou 'F' :cry: )... E se a solução for ridícula de tão óbvia, disfarcem e falem que realmente é muito complicado e tals, ok?

Abços.
"Talento é mais barato que sal. O que separa a pessoa talentosa da bem-sucedida é muito trabalho duro." [ Stephen King ]
zielpunkt
Byte
 
Mensagens: 376
Registrado em: 12 Out 2006 11:36
Localização: Sao Paulo - SP

Mensagempor ivan » 14 Ago 2007 20:34

Uma possivel solução seria:

Código: Selecionar todos
char A[] ="stream desejada A";
char B[] ="stream desejada B";
char C[] ="stream desejada C";

char *ptr[3];
ptr[0] = &A[0];
ptr[1] = &B[0];
ptr[2] = &C[0];

....

while(1) {
 for(int i=0; i<3;i++)
    getdata(buffer, ptr[i]);
}
"A mente que se abre a uma nova idéia jamais volta ao seu tamanho original." (Albert Einstein).
Avatar do usuário
ivan
Word
 
Mensagens: 618
Registrado em: 12 Out 2006 21:27

Mensagempor zielpunkt » 15 Ago 2007 14:45

Então, ivan,

Simplifiquei a tua idéia - lógico que o código não seria esse -, só pra tentar compilar:
Código: Selecionar todos
   while(true)                             
   {   
      char c;
      
      int *_stream[3];
      _stream[0] = &"ETHERNET";
      _stream[1] = &"RS485";
      _stream[2] = &"RFID";
                             
      if(kbhit(_stream[0])) c=(fgetc(_stream[0]));
      if(kbhit(_stream[1])) c=(fgetc(_stream[1]));
      if(kbhit(_stream[2])) c=(fgetc(_stream[2]));
   }


Ai problemas ocorrem. O compilador indica erro e informa que fgetc, fputc, kbhit requerem uma das stream já declaradas (como constantes) quando configurados os parâmetros dos #use rs232. Outro, é que eu acho que eu não estaria, de fato, criando ponteiros que referenciassem as streams declaradas em #use rs232, por se tratarem de constantes geradas automaticamente pelo compilador (e por que só não dá erro quando entre " " ?). E ainda, se não me engano, o CCS não suportaria ponteiros como parâmetros de funções (segundo Fabio Pereira em seu livro), se é que é o caso. Ou eu ainda não estaria fazendo de forma correta. Ou eu continuo sem entender nada de C. Pode ser. Ajudas são bem-vindas.

Abço.
"Talento é mais barato que sal. O que separa a pessoa talentosa da bem-sucedida é muito trabalho duro." [ Stephen King ]
zielpunkt
Byte
 
Mensagens: 376
Registrado em: 12 Out 2006 11:36
Localização: Sao Paulo - SP

Mensagempor ivan » 15 Ago 2007 16:43

Código: Selecionar todos
int *_stream[3];

  _stream[0] = &"ETHERNET";
  _stream[1] = &"RS485";
  _stream[2] = &"RFID";


Se vc quer usar int não pode ser um ponteiro pra um tipo int. Tem que ser apenas:
int _stream[3];

Os endereços são armazenados como valores inteiros e definindo com "int *" vc estaria dizendo que quer um ponteiro para tipos inteiros qdo vc quer um ponteiro pra tipo char. Então guarde apenas o valor inteiro, dado por "&", q vc sabe que na hora do acesso é um char("ETHERNET", por ex).
É um pouco confuso, mas todo ponteiro é armazenado na memória como um valor inteiro. Se vc quer apenas o endereço e sabe o tipo q vai acessar então pode usar uma variavel int para armzená-lo, mas aí vc perde o recurso da aritmética de ponteiros, por ex:

char *ptr;
int *pInt;
...
ptr++
pInt++

Supondo um processador de 16bits, ao fazer ptr++ vc anda um caracter(aponta o prox char), um byte. De outro modo, ao somar pInt++ vc anda 2 bytes(aponta o prox int). Em processadores de 8 bits não teria este prob.
Usando uma variavel int:
int addr = 0xEb;
...
addr++
Supondo q addr seja 0xEC, se vc estiver usando como ponteiro para char, OK! Se estiver usando para apontar um int, em processador de 16bits, dançou!
Normalmente eu não gosto de usar variáveis int para armazenar endereços pq são uma fonte de erros q passa desapercebida depois de algum tempo. Como já programei em plataformas diferentes(PC, UNIX, MAINFRAME e MCU), desaconselho o uso. Mas é um recurso q não deve ser esquecido.
"A mente que se abre a uma nova idéia jamais volta ao seu tamanho original." (Albert Einstein).
Avatar do usuário
ivan
Word
 
Mensagens: 618
Registrado em: 12 Out 2006 21:27

Mensagempor zielpunkt » 16 Ago 2007 19:12

Ivan,

Agradeço a aula. Muito ilustrativa, mesmo. Mas me parece que no caso em questão, funções embutidas do CCS, como fputc ou fgetc, não permitem passar referências como parametro da mesma. Na compilação sempre ocorre o erro "Stream must be a constant in the valid range". Ao contrário do ANSI-C, o CCS impõe algumas limitações, devido à estrutura dos MCU. De qualquer forma, deixei o código mais enxuto me utilizando de outras técnicas. Ficou legal, mais legível e menos repetitivo do que estava antes. Novamente, obrigado pela força.

Abço.
"Talento é mais barato que sal. O que separa a pessoa talentosa da bem-sucedida é muito trabalho duro." [ Stephen King ]
zielpunkt
Byte
 
Mensagens: 376
Registrado em: 12 Out 2006 11:36
Localização: Sao Paulo - SP

Mensagempor Maurício » 17 Ago 2007 15:14

Salve, Ziel.

Experimenta isto:

Código: Selecionar todos
#include <string.h>

char stream1[ ] = "ETHERNET";
char stream2[ ] = "RS485";
char stream3[ ] = "RFID";

char stream_recebido[ 32 ];

void getdata(char *stream_entrada, char *stream_saida)
{
    if ( strlen ( stream_entrada ) )      // se a string for >0
    {
      unsigned char contador = 0;

      for (contador = 0; contador < strlen ( stream_entrada ); contador++ )
         * ( stream_saida + contador ) = * ( stream_entrada + contador );
      * ( stream_saida + contador ) = '\0';
   }
   else
   {
      *stream_saida = '\0';
   }
}

while(1)
{
   .
   getdata(stream1, stream_recebido); //
   .
   .
   getdata(stream2, stream_recebido); //
   .
   .
   getdata(stream3, stream_recebido); //
   .
   .
}


É só uma idéia. Eu não testei o código.
No lugar do loop for na função getdata, vc pode substituir por strcpy, memcpy ou outra função de cópia de strings, isto é, sé é com strings que vc irá trabalhar.

Boa sorte.

[]'s
"Não leve a vida tão à sério, afinal, nenhum de nós sairá vivo, dela!"
Avatar do usuário
Maurício
Word
 
Mensagens: 678
Registrado em: 14 Out 2006 17:23
Localização: São Paulo - SP

Mensagempor ivan » 18 Ago 2007 09:59

Realmente, eu ainda não usei o CCS. Não tive a oportunidade. Mas pela msg de êrro

Stream must be a constant in the valid range"


Me parece q a área de memória que o compilador está alocando para armazenar a stream, não está definida como constante. E portanto, o seu endereço não está no intervalo designado para valores deste tipo(constantes).
É só um palpite. Mas vc resolveu... melhor assim!
"A mente que se abre a uma nova idéia jamais volta ao seu tamanho original." (Albert Einstein).
Avatar do usuário
ivan
Word
 
Mensagens: 618
Registrado em: 12 Out 2006 21:27

Mensagempor zielpunkt » 18 Ago 2007 15:15

Ahe, Mauricio!

Vou testar o seu código, mas não vai ser muito rápido, porque eu tô na correria poe aqui e já dei uma meia-sola nessa questão. Mas assim que eu testar, certamente posto aqui o resultado. Talvez eu tenha que rever alguma coisa, porque recebo/envio além de strings...

Ivan, acho que realmente é a maneira que o compilador trata a função nativa dele, o que inibe certos malabarismos com as estruturas. Qquer forma, obrigado aos dois.

Abço.
"Talento é mais barato que sal. O que separa a pessoa talentosa da bem-sucedida é muito trabalho duro." [ Stephen King ]
zielpunkt
Byte
 
Mensagens: 376
Registrado em: 12 Out 2006 11:36
Localização: Sao Paulo - SP


Voltar para Visual C++/C/C++/C#

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 0 visitantes

x