screen
동일한 컴퓨터에서 읽을 직렬 포트에 일부 데이터를 쓰려고 합니다 . 이 답변을 보려고했는데직렬 포트로 데이터를 전송하고 답변을 확인하는 방법
내 사용자를 그룹에 추가 dialout
하고 chmod o+rw /dev/ttyS1
Python으로 실행했습니다. 이 작업을 수행하고 다음 오류가 발생합니다.
>>> import serial
>>> ser = serial.Serial("/dev/ttyS1",4800)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/el3/Envs/serial/lib/python2.7/site-packages/serial/serialutil.py", line 236, in __init__
self.open()
File "/home/el3/Envs/serial/lib/python2.7/site-packages/serial/serialposix.py", line 272, in open
self._reconfigure_port(force_update=True)
File "/home/el3/Envs/serial/lib/python2.7/site-packages/serial/serialposix.py", line 315, in _reconfigure_port
raise SerialException("Could not configure port: {}".format(msg))
serial.serialutil.SerialException: Could not configure port: (5, 'Input/output error')
그래서 질문은, 내가 여기서 뭘 잘못하고 있는 걸까요?
아니면 다른 접근법을 찾아야 할까요?
문제는 Python으로 수신할 수 있는 일부 UDP 메시지를 받았는데 이를 직렬 포트만 볼 수 있는 소프트웨어로 보내야 한다는 것입니다.
어쩌면 다른 접근법이 있을까요?
이 경우 좋은 접근 방식은 무엇입니까?
답변1
두 개의 프로그램을 연결해야 하는데 그 중 하나가 tty 장치(직렬 포트가 예) 사용을 요구하는 경우 다음을 사용할 수 있습니다.의사 터미널한 쌍.
표준 Python을 사용하여 이 작업을 수행할 수 있습니다.pty 모듈, 또는 작은 C 프로그램을 사용하여 쌍을 만든 다음 셸, Python 프로그램 또는 일반 파일과 같은 것에서 액세스합니다.
당신의제안이 댓글은 과도하고 이식성이 떨어지는 커널 모듈을 사용합니다.
다음은 비슷한 상황에서 제가 사용한 C 프로그램의 예입니다. 그다지 우아하지도 않았고 사용된 이름을 전달하는 방법이 필요했습니다.
/* ptycat (ptypipe? ptypair?)
*
* create a pair of pseudo-terminal slaves connected to each other
*
* Link with -lutil
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include <pty.h>
#undef max
#define max(x,y) ((x) > (y) ? (x) : (y))
/*
(void)ioctl(STDIN_FILENO, TIOCGWINSZ, &win);
*/
/* TODO: make symlinks, unlink on atexit */
static uint8_t buf[BUFSIZ]; /* BUFSIZ from stdio.h, at least 256 */
static char *log_dir = NULL;
void logdata (char *dir, uint8_t *data, int n) {
if (dir != log_dir) fprintf (stdout, "\n%s", dir);
log_dir = dir;
for (; n > 0; n--, data++) fprintf (stdout, " %02x", *data);
fflush (stdout);
}
int main (int argc, char* argv[])
{
char name[256]; /* max namelen = 255 for most fs. */
fd_set rfd;
struct termios tt;
struct winsize ws;
int master[2], slave[2];
int n, nfds, cc;
if (tcgetattr (STDIN_FILENO, &tt) < 0)
{
perror("Cannot get terminal attributes of stdin");
exit(1);
}
cfmakeraw (&tt);
for (int i = 0; i < 2; i++)
{
if (openpty (&master[i], &slave[i], name, &tt, NULL /*ws*/) < 0)
{
perror("Cannot open pty");
exit(1);
}
puts(name);
}
for (;;) {
FD_ZERO(&rfd);
FD_SET(master[0], &rfd);
FD_SET(master[1], &rfd);
nfds = max(master[0], master[1]) + 1;
n = select(nfds, &rfd, 0, 0, NULL);
if (n > 0 || errno == EINTR)
{
if (FD_ISSET(master[0], &rfd))
{
if ((cc = read(master[0], buf, sizeof(buf))) > 0)
{
(void) write(master[1], buf, cc);
logdata (">>>", buf, cc);
}
}
if (FD_ISSET(master[1], &rfd))
{
if ((cc = read(master[1], buf, sizeof(buf))) > 0)
{
(void) write(master[0], buf, cc);
logdata ("<<<", buf, cc);
}
}
}
}
/* This never reached */
return 0;
}