Comunicação UART beaglebone [RESOLVIDO]

1. Comunicação UART beaglebone [RESOLVIDO]

Isac Marques da Silva
isacmarques

(usa Debian)

Enviado em 26/02/2015 - 17:10h

Olá galera.

Mais uma vez eu com duvida aqui no forum.

Tenho a seguinte situação:

3 placas slave
1 placa master

As três placas Slave possue um DIP(chave) de oito digitos onde corresponde ao endereço de cada placa.
Fiz o comando que envia a informação para cada uma delas separadamente e recebe tudo certinho. No entanto
nem tudo é maravilha pode ocorrer de uma dessas placas se queimar nesse caso o meu software para de enviar
as informações. veja o exemplo:

solicitando informações a placa 1
informações recebidas

solicitando informações a placa 2 (queimada)
informações não recebidas

O software para e não envia a informação para a placa 3 pois ele fica esperando resposta da placa 2

Eu já tentei de todas as formas verificar se a informação chegou ao destino e se o destino existe.

Tentei de varias formas resolver isso mas não consegui se alguem tiver uma ideia de como fazer me ajudaria
bastante.

O legal seria ele tentar por x tempo se não tiver resposta voltar novamente e tentar por x tempo e voltar de novo
e nessa ultima tentativa ele pularia para a proxima placa assim mesmo que a segunda esteja queimada ou com erro na rede
não prejudicaria o resto do processo.

Estou usando C++ no Debian para beaglebone revision C, para me comunicar utilizo as saidas uart do PC e
para escrever na uart estou utilizando as funções

write() e Read()


Desde já grato pela ajuda de vocês e do Viva o linux.


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 27/02/2015 - 13:12h

Uma maneira simples de implementar um timer é mais ou menos o seguinte.

#include <signal.h>
#include <unistd.h>


void alarm_handler(int sig_num){
/* Faz alguma coisa -- até mesmo nada, como neste caso. */
}


int main(void){
struct sigaction sa, old_sa;

/* O campo sa_handler aponta para a função tratadora. */
sa.sa_handler=alarm_handler;
/*
O campo sa_mask indica quais sinais serão bloqueados durante
tratamento. No nosso caso, não bloqueamos sinal algum.
*/
sigemptyset(&sa.sa_mask);
/*
O campo sa_flags modifica comportamento do tratador, inclusive
se a chamada a read() deve ser reiniciada ou não (SA_RESTART).
No nosso caso, não queremos que isso aconteça.
*/
sa.sa_flags=0;

/* Instala novo tratamento e salva tratamento antigo. */
sigaction(SIGALRM, &sa, &old_sa);

/* ... */

/* Instala timeout sobre a leitura. */
alarm(2); /* Tempo em segundos. */
n_read=read(fd, buffer, buf_size);
read_err=errno;
alarm(0); /* Desliga o temporizador. */
/* Testa se houve erro de leitura. */
if(n_read==-1){
if(read_err==EINTR){
/* read() foi interrompido (timeout) */
}
else{
/* Outro tipo de erro de leitura. */
}
}

/* ... */

}


Claro que o programa acima está supersimplificado, e supõe timeouts de um número inteiro de segundos. Para timeouts de duração fracionária de segundos, você pode usar setitimer() (uma vez que ualarm() está marcada como obsoleta). Leia sobre read(), sigaction() e setitimer().

3. Re: Comunicação UART beaglebone [RESOLVIDO]

Isac Marques da Silva
isacmarques

(usa Debian)

Enviado em 27/02/2015 - 13:49h

Paulo, Mais uma vez sou muito grato pela sua ajuda, fiz do jeito que me passou e deu certinho era o que eu precisava .

Abraços, Bom final de semana.



4. Re: Comunicação UART beaglebone [RESOLVIDO]

Isac Marques da Silva
isacmarques

(usa Debian)

Enviado em 24/03/2015 - 08:05h

Bom dia,

Paulo Estou com uma duvida neste tópico, fiz todo o processo dei uma lida em alguns materiais sobre sinais em C e me ficou uma duvida.

No exemplo que me passou eu o implementei para caso o mesmo não consiga ler uma determinada informação do READ ele pule fora do mesmo e não fique com o processo parado, no entanto agora eu tenho a necessidade de refazer o read ou seja tentar ler novamente.

Na parte abaixo:


if(n_read==-1){
if(read_err==EINTR){
/* read() foi interrompido (timeout) */
}
else{
/* Outro tipo de erro de leitura. */
}


Eu posso estar colocando a 2 tentativa de leitura dentro do if (read_err==EINTR) ? no sa.saflags =0 posso solicitar que ele reinicie o read novamente ? Ou é melhor que caso eu não receba nada pela função READ eu envie os dados novamente e aguardo novamente o read tentar receber essas informações. O que você melhor me indica para uma aplicação que terá uma rede grande.

Desde já muito obrigado pela sua ajuda e de todos que colaboram no viva o linux.


5. Re: Comunicação UART beaglebone [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 25/03/2015 - 23:37h

isacmarques escreveu:

Bom dia,

Paulo Estou com uma duvida neste tópico, fiz todo o processo dei uma lida em alguns materiais sobre sinais em C e me ficou uma duvida.

No exemplo que me passou eu o implementei para caso o mesmo não consiga ler uma determinada informação do READ ele pule fora do mesmo e não fique com o processo parado, no entanto agora eu tenho a necessidade de refazer o read ou seja tentar ler novamente.


Nada impede de fazer, mas você tem de tomar cuidado de proteger também o segundo read() contra timeout, ou a proteção do primeiro terá sido inútil.

Na parte abaixo:


if(n_read==-1){
if(read_err==EINTR){
/* read() foi interrompido (timeout) */
}
else{
/* Outro tipo de erro de leitura. */
}


Eu posso estar colocando a 2 tentativa de leitura dentro do if (read_err==EINTR) ? no sa.saflags =0 posso solicitar que ele reinicie o read novamente ? Ou é melhor que caso eu não receba nada pela função READ eu envie os dados novamente e aguardo novamente o read tentar receber essas informações. O que você melhor me indica para uma aplicação que terá uma rede grande.

Desde já muito obrigado pela sua ajuda e de todos que colaboram no viva o linux.


Não acho que seja uma boa ideia colocar dentro do tratamento de timeout uma segunda leitura que também pode dar timeout. Acredito que uma saída melhor seja ter um loop de I/O, e implementar uma máquina de estados para controlar as ações a tomar em cada repetição desse loop.

Não acredito que usar o flag SA_RESTART tenha serventia também. Muito provavelmente atrapalharia a detecção do timeout.

Uma coisa que você poderia fazer seria usar select() ou pool() para esperar por dados na entrada, em lugar de usar um timer.

Mas tudo isso é meio acessório. Uma coisa muito importante que, se você ainda não tiver feito, eu recomendo fortemente que pare o desenvolvimento para realizar antes de prosseguir é planejar bastante como será o funcionamento da rede. Das conversas que tivemos até agora, parece que você ainda está com problemas de comunicação básica, em nível de hardware e enlace de dados, mas já falou em comunicação multiponto, e eu temo que você possa estar tentando fazer tudo ao mesmo tempo. Acho que separar a coisa em níveis, como num modelo OSI (http://en.wikipedia.org/wiki/OSI_model) ou da Internet (http://en.wikipedia.org/wiki/Internet_protocol_suite), e desenvolver aos poucos, do nível mais baixo para os mais altos, pode facilitar sua vida.


6. Re: Comunicação UART beaglebone [RESOLVIDO]

Isac Marques da Silva
isacmarques

(usa Debian)

Enviado em 15/05/2015 - 09:59h

Paulo Boa tarde,
Você poderia me ajudar com um exemplo de setitimer() ?

Montei aqui o esquema abaixo:

  struct itimerval timer ;
struct sigaction action ;

// define a ação para o sinal SIGALRM
action.sa_handler = disparo_timer ;
sigemptyset (&action.sa_mask);
action.sa_flags = 0;
sigaction (SIGALRM, &action, 0);

// ajusta valores do temporizador
timer.it_interval.tv_usec = 0; // disparos sucessivos, micro-segundos
timer.it_interval.tv_sec = 1; // disparos sucessivos, segundos
timer.it_value.tv_usec = 0; // primeiro disparo, micro-segundos
timer.it_value.tv_sec = 3 ; // primeiro disparo, segundos

// arma o temporizador
setitimer (ITIMER_REAL, &timer, NULL) ;


Eu entendi o esquema só não entendi como eu usaria ele para substituir o Alarm e controla-lo por micro-segundo, ou seja se o read não receber nada em 3 microsengundos ele sai do Read não deixando o mesmo travar.

Se você puder me ajudar mais uma vez eu seria muito grato.

Desde já muito obrigado.






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts