Siedze juz od kilku dni nad jednym problem, przeszukalem wszystko co bylo mozliwe do znalezienia ale rozwiazania brak.
Jestem zielony jesli idzie o Linuksa.
Mam do napisania program czytajacy port szeregowy (rs232), ktory bedzie dzialal tak, ze w momencie pojawienia sie czegos na RSie wystawiane jest przerwanie/sygnal, ktory spowoduje czytanie danych z RS232
Napisalem dzialajacy program ale niestety sytuacja wyglada tak:
jezeli czytam bezposrednio (bez syganlow) z RSa to wszystko ladnie odbiera, natomiast gdy wlaczam obsluge sygnalu polowa danych zostaje zgubiona np.: zamiast 20bajtow obieram 9.
Z gory dziekuje za pomoc. Moze ktos ma inny pomysl na napisanie tego programu np. z obsluga przerwan, albo doradzi co robie zle lub jak powinienem to napisac.
Pozdrawiam.
muzic
Ponizszy kod prezentuje program w ktorym wyraznie widac gubienie sygnalow w przypadku obslugi sygnalow:
Kod: Zaznacz cały
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <iostream>
#include <sys/signal.h>
//----------------------------------------------------
#define BAUDRATE B57600 //[RS232] ustawienie predkosci transmisji
#define MODEMDEVICE "/dev/ttyS0" //[RS232] sciezka odstepu do RS232
#define _POSIX_SOURCE 1 //ustawienie kodu zgodnego z POSIX
#define O_BINARY 0x8000
#define FALSE 0
#define TRUE 1
//----------------------------------------------------
volatile int STOP=FALSE;
void signal_handler_IO (int status); //definicja procedury obsługi przerwania/sygnalu
int wait_flag=TRUE; //flaga przerwania/sygnalu: TRUE - brak przerwania FALSE - przyszlo przerwanie
int fd, res;
unsigned char buf[255]; //zmienna trzymajaca wartosc odczytana z RS232
int przer=0; // [TMP-DEL]
struct sigaction saio; //Struktura do obslugi konkretnego przerwania: SAIO
struct termios oldtio,newtio; //Struktury do przechowywania informacji związanych z urządzeniami terminalowymi.
//----------------------------------------------------
int main()
{
std::cout<<"START PROGRAMU"<<std::endl;
//----------------------------------------------------
// Otwórz urządzenie:
// O_RDWR - do odczytu i zapisu,
// O_NOCTTY - brak kontroli polaczenia [zabezpieczenie przed CTRL-C],
// O_BINARY - tryb binarny,
// O_NONBLOCK - tryb nie blokujacy, zadne operacje (pisania, czekanie na dane) nie zablokuja procesu
//----------------------------------------------------
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd <0) {perror(MODEMDEVICE); exit(-1); } //nie powiodlo sie otwarcie urzadzenia to ERROR
//----------------------------------------------------
// ZAINICJUJ OBSLUGE PRZERWAN / SYGNALOW
//----------------------------------------------------
saio.sa_handler = signal_handler_IO; //inicjuje przerwanie dla RS232
sigemptyset(&saio.sa_mask); //wyczysc ustawienia //PRZEDTEM: saio.sa_mask = 0;
saio.sa_flags = 0; //wyzeruj flage przerwania
saio.sa_flags = SA_NODEFER;
saio.sa_restorer = NULL; //
sigaction(SIGIO,&saio,NULL); //zaladuj nowe ustawienia
//----------------------------------------------------
fcntl(fd, F_SETOWN, getpid()); //pozwól procesowi otrzymać sygnał SIGIO
fcntl(fd, F_SETFL, FASYNC); //przelacz gniazdo fd w tryb asynchronicznego powiadamiania o gotowości do zapisu/odczytu. Domyślnie wysylany sygnał SIGIO
// fcntl(fd,F_SETFL,FNDELAY);
tcgetattr(fd,&oldtio); //zapisz dotychczasowe ustawienia portu [oldtio]
bzero(&newtio, sizeof(newtio)); //wyczyść strukturę na ustawienia portu [newtio]
//----------------------------------------------------
//USTAWIENIA RS232
// BAUDRATE - Ustaw prędkośc,
// CRTSCTS - ustaw sprzętową kontrolę transmisji,
// CS8 - 8n1 (8bitów ,bez kontroli parzystości,1 bit stopu),
// CLOCAL - połączenie lokalne - nie kontroluje modemu,
// CREAD - włącz odbieranie znaków
//----------------------------------------------------
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR ; //IGNPAR - ignoruj bajty z błędami parzystości, ICRNL : przetłumacz CR na LN [ENTER]
newtio.c_oflag = 0; //port zorientowany bajtowo (RAW)
newtio.c_lflag = 0; //nie ukladaj odebranych danych w wiersze [brak obslugi nowej linii, konca wiersza itp] ICANON - wlacza ukladanie
newtio.c_cc[VINTR] = 0; //Ctrl-c -przerwij : 0 - wylacz, 1 - wlacz [jesli wlaczone ISIG]
newtio.c_cc[VQUIT] = 0; //konczenie pracy : 0 - wylacz, 1 - wlacz [jesli wlaczone ISIG]
newtio.c_cc[VERASE] = 0; //kasowanie : 0 - wylacz, 1 - wlacz [jesli wlaczone ICANON]
newtio.c_cc[VKILL] = 0; //kasowanie wiersza : 0 - wylacz, 1 - wlacz [jesli wlaczone ICANON]
newtio.c_cc[VEOF] = 1; //koniec pliku : 0 - wylacz, 1 - wlacz [jesli wlaczone ICANON]
newtio.c_cc[VTIME] = 0; //odczytane dane beda dostępne, po upływie [VTIME] (VTIME x 0,1s) [jesli wylaczone ICANON]
newtio.c_cc[VMIN] = 1; //odczytane dane beda dostępne, gdy długość kolejki = [VMIN] [jesli wylaczone ICANON]
newtio.c_cc[VSWTC] = 0; //
newtio.c_cc[VSTART] = 0; //rozpoczecie pisania : 0 - wylacz, 1 - wlacz
newtio.c_cc[VSTOP] = 0; //zatrzymanie pisania : 0 - wylacz, 1 - wlacz
newtio.c_cc[VSUSP] = 0; //zawieszenie : 0 - wylacz, 1 - wlacz
newtio.c_cc[VEOL] = 0; //koniec wiersza : 0 - wylacz, 1 - wlacz
newtio.c_cc[VREPRINT] = 0; //powtorz wiersz : 0 - wylacz, 1 - wlacz
newtio.c_cc[VDISCARD] = 0; //
newtio.c_cc[VWERASE] = 0; //kasowania słowa : 0 - wylacz, 1 - wlacz
newtio.c_cc[VLNEXT] = 0; //
newtio.c_cc[VEOL2] = 0; //koniec wiersza 2 : 0 - wylacz, 1 - wlacz
tcflush(fd, TCIFLUSH); //porzuć dane otrzymane do bufora ale nie odczytane (przez read() itd)
tcsetattr(fd,TCSANOW,&newtio); //uaktywnij nowe ustawienia
while (STOP==FALSE) {
res = read(fd,buf,1);
buf[res]=0; // set end of string, so we can printf
std::cout << " Odczyt normal: " << (int)buf[0]<< std::endl;
//std::cout << " Przer: " << przer<< std::endl;
if (buf[0]=='z') STOP=TRUE;
}
// fcntl(0, F_SETFL, tem);
tcsetattr(fd,TCSANOW,&oldtio);
std::cout<<"KONIEC PROGRAMU"<<std::endl;
return 0;
}
void signal_handler_IO (int status)
{
wait_flag = FALSE;
printf("SIGIO signal.\n");
przer++;
}