전이중 직렬 회선을 통해 I/O를 수행하려는 응용 프로그램이 있습니다. 그건:
char buf[4];
write(fd, "ping", 4);
read(fd, buf, 4);
...원격 장치가 "ping" 문자열에 대한 응답으로 전송하는 4바이트로 끝날 것으로 예상됩니다.
하지만 저는 반이중 RS485 회선을 사용하고 있으므로 직렬 회선에서 전송된 모든 바이트는 직렬 회선에서도 수신됩니다.예같은 줄). 따라서 위의 코드 조각은 원격 장치가 무엇이든 전송하기 전에 항상 "ping"을 버퍼로 읽습니다.
분명히 호스트 코드는 이것을 예상하지 않았습니다.
내가 생각해낸 최선의 해결책은 항상 쓴 후에 읽고 받은 문자가 보낸 문자와 일치하는지 확인한 다음 무시하는 것입니다.
하지만 더 좋은 방법이 있나요? 전송 중에 문자 수신을 억제하는 신뢰할 수 있는 Unix 관용구가 있습니까?
(제 질문에는 많은 미묘함과 작은 우여곡절이 있다는 점에 감사드립니다. 예를 들어 UART에 FIFO가 있습니까? 수신 프로세스가 동일한 스레드에서 실행됩니까? 등등. 쉬웠다면 유닉스에 대해서는 묻지 마세요!
고쳐 쓰다
write()
나는 각 바이트 뒤에 동일한 read()
수의 바이트를 호출한 다음 이를 사용하여 strncmp()
일치하는지 확인하는 간단한 루틴을 구현했습니다 . 강력해 보이지만 드라이버 수준에서 더 나은 방법이나 적어도 다른 방법이 있는지 알고 싶습니다.
답변1
실용적으로 말하면, 현재 가지고 있는 것이 작동하는 것 같고 설정을 변경하고 싶지 않거나 이것이 일회성 해킹인 경우 계속해서 솔루션을 사용하십시오.
그러나 Linux에는 API가 있습니다RS485올바른 하드웨어를 찾으려면 시도해 볼 수 있습니다. 일부 하드웨어에는 직렬 포트가 적절한 상태에 있을 때 작동하는 반이중 모드가 내장되어 있습니다. 예를 들어 ioctl은 RS485 모드를 활성화하는 데 사용됩니다.
#include <linux/serial.h>
struct serial_rs485 rs485conf = {0};
rs485conf.flags |= SER_RS485_ENABLED;
if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) ...
또는 전송할 때 RTS 핀의 로직 레벨을 1로 설정하십시오.
rs485conf.flags |= SER_RS485_RTS_ON_SEND;