문제

나는 전송/수신 데이터의 시리얼 라인에서 리눅스고 싶을 찾기 위해 사이에 지연이다.

Modbus 사용 3.5 문자는 지연을 감지하는 메시지를니다.이 있는 경우보다 더 많은 1.5 문자를 지연시 프레임을 선언 완전하지 않습니다.

쓰고 있어요 빠른 프로그램에서는 기본적으로 C

fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
// setup newtio
....
tcsetattr(fd, TCSANOW, &newtio);
for(;;) {
    res = read(fs, buf, 1);
    if (res > 0) {
        // store time in milliseconds?
        //do stuff
    }
}

는 몇 가지 방법이 있을 측정하는 시간까요?또는 나에서 볼 필요가 검색하기에서 데이터의 시리얼 라인에서 다른 방법이 있을까?

나도 연결 SIGIO 신호가 있을 때마다 하지만 데이터가 보이 데이터를 얻을 수 있 8 바이트다.

(그렇다,나는 거기에 몇 가지를 존재 modbus 라이브러리가 그러나 내가 이것을 사용하고 싶은 다른 응용 프로그램)

도움이 되었습니까?

해결책

Modbus는 많은 오래된 프로토콜과 같으며 실제로 현대적인 하드웨어를 싫어합니다.

한 번에 8 바이트를 얻는 이유는 다음과 같습니다. PC는 하드웨어에 수신 및 전송시 적어도 16 바이트 직렬 FIFO가 있습니다. 대부분은 64 바이트 이상입니다.

그것 ~이다 UART 장치에 시간을 초과하고 수신 된 인터럽트를 발행 할 수 있습니다.

트리거 레벨은 조정 가능하지만 낮은 레벨 드라이버는 "스마트하게"설정합니다. SetSerial을 사용하여 저탄소 모드를 시도해보십시오) 직렬 드라이버의 코드를 사용하여 필수를 할 수 있습니다. Google It (성숙한 컨텐츠 경고) 예쁘지 않습니다.

따라서 루틴은 의사 코드입니다

int actual=read (packet, timeout of 1.5 chars)

look at actual # of received bytes

if less than a packet, has issues, discard.

별로.

다른 팁

간단한 대답은 ... 당신은 할 수 없습니다 (글을 쓰지 않고 자신의 연쇄 운전자가 아닙니다)!

당신이 modbus를 쓰고 있다면 주인 희망이 있습니다 : 당신은 기다려서 노예 응답의 끝을 감지 할 수 있습니다. 어느 아무 것도받지 않고 (선택 (2)을 수신하지 않고 시간 (3.5 숯을 초과 할 수있는 시간) 또는 읽을 때 반응을 파싱하여 (두 번째 방법은 훨씬 적은 시간을 낭비 함) 시간을받지 않습니다. 당신은 또한 기다려야합니다 적어도 3.5 문자 시간은 이전 요청에 대한 응답을받은 후 새 요청을 전송하기 전에. "적어도"는 여기서 작동합니다! 더 기다리는 것은 중요하지 않습니다. 덜 기다리고 있습니다.

당신이 modbus를 쓰고 있다면 노예 그럼 당신은 're 운없는. 당신은 간단합니다 할 수 없습니다확실하게 사용자 공간 Linux에서. 당신은 당신의 직렬 드라이버를 작성해야합니다.

BTW, 이것은 Linux의 잘못이 아닙니다. 이것은 Modbus의 프레임 방법의 믿을 수없는 어리 석음 때문입니다.

나는 당신이 이것에 대해 잘못된 방식으로 가고 있다고 생각합니다. 캐릭터가 모두 함께 오도록하는 메커니즘이 있습니다.

기본적으로 사용하고 싶을 것입니다 ioctl() 그리고 설정 VMIN 그리고 VTIME 적절하게 매개 변수. 이 경우 원하는 것 같습니다 VMIN (패킷의 최소 문자 수) 0 그리고 VTIME (문자 사이에 허용되는 최소 시간 15 (그들은 10 분의 1 초입니다).

약간 진짜 기본 예제 코드 :

struct termio t;
t.c_cc[ VMIN ] = 0;
t.c_cc[ VTIME ] = 15;
if (ioctl( fd, TCSETAW, &t ) == -1)
{
    printf( msg, "ioctl(set) failed on port %s. Exiting...", yourPort);
    exit( 1 );
}

당신 앞에 이것을하십시오 open() 그러나 당신 앞에 read(). 다음은 제가 매우 도움이 된 몇 가지 링크입니다.

직렬 프로그래밍 안내서

Vmin 및 Vmax 이해

나는 당신의 질문에 대한 완벽한 답이 아니더라도 적어도 당신을 올바른 방향으로 도울 수 있기를 바랍니다.

사용할 수 없습니다 시간이 초과되었습니다.에서 더 높은 전송 속도가 3.5 문자를 제한 시간이 몇 밀리초 단위의 수백 마이크로초 단위로.이러한 시간 제한을 처리할 수 없습에서 리눅스 사용자 공간입니다.

클라이언트 측에서,그것은 어렵지 않기 때문 Modbus 보내지 않는 비동기 메시지입니다.그래서 그것을 당신이 보내지 않는 2 년 연속 메시지에는 3.5 성격 제한 시간.

서버 측에서는,문제는 경우 클라이언트는 매우 짧은 반응 시간 제한과 리눅스는 너무 바빠서 당신은 쓸 수 없습니다 총알 증거 프레이밍 솔루션입니다.는 기회가있 read()함수보다 더 많은 반환 하나의 패킷을 전송합니다.여기에(조금 고안)예입니다.

  1. 클라이언트를 쓰는 패킷을 서버입니다.시간 제한은 말하자 20ms.

  2. 말하자는 리눅스에서는 순간 매우 바쁘다,그래서 커널이 없어 실내에 50ms.

  3. 후 20ms 클라이언트를 감지하지 않았다는 것을 받은 어떤 반응 그래서 그것을 보내는 다른 패킷을 서버에(어쩌면 원망 이전).

  4. 면 리눅스 깨어 읽기 쓰레드 후 50ms,read()함수를 얻을 수 있습 2 패킷 또는 1 절반을 따라하는 방법은 바이트가 수신되었으로 직렬 포트 드라이버입니다.

에서 나의 구현을 사용한 간단한 방법을 시도하는 바이트로 구문 분석 on-the-fly-먼저를 검출하는 함수 코드 그리고 나서를 읽으려고 나머지 모든 바이트를 위한 특정 기능이다.면 하나의 반 패킷을 나는 분석 첫 번째 하고 나머지 바이트에 남아 있습니다.한 경우 더 바이트 내 짧은 시간 제한 추가들고 시도하는 구문 분석,그렇지 않으면 내가 그들을 버린다.그것은 완벽한 솔루션을(예를 들어 일부 서브 코드를 위해 기능을 8 지 않는 고정된 크기)하지만 이후 MODBUS RTU 없 STX ETX 문자,그것은 최고의 한 나는 할 수 있었습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top