OberonCore https://forum.oberoncore.ru/ |
|
CommV24 https://forum.oberoncore.ru/viewtopic.php?f=34&t=4150 |
Страница 1 из 1 |
Автор: | Alexander Shiryaev [ Понедельник, 12 Ноябрь, 2012 22:44 ] |
Заголовок сообщения: | CommV24 |
CommV24: Код: MODULE CommV24; (* A. V. Shiryaev, 2012.11 Linux, OpenBSD 32-bit Interface corresponds to original BlackBox 1.6-rc6 CommV24 *) IMPORT SYSTEM, Libc := LinLibc, Termios := LinTermios, Ioctl := LinIoctl; CONST nonblocking = FALSE; CONST bits4* = 0; bits5* = 1; bits6* = 2; bits7* = 3; stop15* = 4; stop2* = 5; even* = 6; odd* = 7; inXonXoff* = 8; outXonXoff* = 9; inRTS* = 10; inDTR* = 11; outCTS* = 12; outDSR* = 13; TYPE Connection* = POINTER TO LIMITED RECORD hnd: INTEGER; (* # -1: open *) opts: SET END; PROCEDURE DecodeBaud (baud: INTEGER; OUT speed: Termios.speed_t); BEGIN IF baud = 50 THEN speed := Termios.B50 ELSIF baud = 75 THEN speed := Termios.B75 ELSIF baud = 110 THEN speed := Termios.B110 ELSIF baud = 134 THEN speed := Termios.B134 ELSIF baud = 150 THEN speed := Termios.B150 ELSIF baud = 200 THEN speed := Termios.B200 ELSIF baud = 300 THEN speed := Termios.B300 ELSIF baud = 600 THEN speed := Termios.B600 ELSIF baud = 1200 THEN speed := Termios.B1200 ELSIF baud = 1800 THEN speed := Termios.B1800 ELSIF baud = 2400 THEN speed := Termios.B2400 ELSIF baud = 4800 THEN speed := Termios.B4800 (* ELSIF baud = 7200 THEN speed := Termios.B7200 *) (* not present in Linux *) ELSIF baud = 9600 THEN speed := Termios.B9600 (* ELSIF baud = 14400 THEN speed := Termios.B14400 *) (* not present in Linux *) ELSIF baud = 19200 THEN speed := Termios.B19200 (* ELSIF baud = 28800 THEN speed := Termios.B28800 *) (* not present in Linux *) ELSIF baud = 38400 THEN speed := Termios.B38400 ELSIF baud = 57600 THEN speed := Termios.B57600 (* ELSIF baud = 76800 THEN speed := Termios.B76800 *) (* not present in Linux *) ELSIF baud = 115200 THEN speed := Termios.B115200 ELSIF baud = 230400 THEN speed := Termios.B230400 ELSE HALT(100) END END DecodeBaud; PROCEDURE Open* (device: ARRAY OF CHAR; baud: INTEGER; opts: SET; OUT conn: Connection); VAR c: Connection; fd: INTEGER; ss: ARRAY Libc.NAME_MAX + 1 OF SHORTCHAR; res: INTEGER; t: Termios.termios; speed: Termios.speed_t; flags: SET; BEGIN conn := NIL; ASSERT(opts * {even,odd} # {even,odd}, 20); IF bits4 IN opts THEN ASSERT(opts * {bits5,bits6,bits7} = {}, 21) END; IF bits5 IN opts THEN ASSERT(opts * {bits4,bits6,bits7} = {}, 22) END; IF bits6 IN opts THEN ASSERT(opts * {bits4,bits5,bits7} = {}, 23) END; IF bits7 IN opts THEN ASSERT(opts * {bits4,bits5,bits6} = {}, 24) END; ASSERT(opts * {stop15,stop2} # {stop15,stop2}, 25); IF stop15 IN opts THEN ASSERT(opts * {bits4,bits5} # {}, 26) END; IF stop2 IN opts THEN ASSERT(opts * {bits4,bits5} = {}, 27) END; DecodeBaud(baud, speed); ss := SHORT(device$); flags := Libc.O_RDWR; IF nonblocking THEN flags := flags + Libc.O_NONBLOCK END; fd := Libc.open(ss, flags, {1,4} (* 022 *)); IF fd # -1 THEN res := Termios.tcgetattr(fd, t); IF res = 0 THEN t.c_iflag := Termios.IGNBRK (* ignore BREAK condition *) + Termios.IGNPAR (* ignore (discard) parity errors *); IF opts * {even,odd} # {} THEN t.c_iflag := t.c_iflag + Termios.INPCK (* enable input parity checking *) END; t.c_oflag := 0; t.c_cflag := Termios.CREAD (* enable receiver *) + Termios.CLOCAL (* ignore modem status lines *); IF bits4 IN opts THEN HALT(126) (* not implemented *) ELSIF bits5 IN opts THEN t.c_cflag := t.c_cflag + Termios.CS5 ELSIF bits6 IN opts THEN t.c_cflag := t.c_cflag + Termios.CS6 ELSIF bits7 IN opts THEN t.c_cflag := t.c_cflag + Termios.CS6 ELSE t.c_cflag := t.c_cflag + Termios.CS8 END; IF opts * {stop15,stop2} # {} THEN t.c_cflag := t.c_cflag + Termios.CSTOPB END; IF even IN opts THEN t.c_cflag := t.c_cflag + Termios.PARENB ELSIF odd IN opts THEN t.c_cflag := t.c_cflag + Termios.PARENB + Termios.PARODD (* ELSE parity none *) END; IF outCTS IN opts THEN HALT(126) END; (* CTS out flow control *) IF outDSR IN opts THEN HALT(126) END; (* DSR out flow control *) IF inDTR IN opts THEN HALT(126) END; (* DTR flow control handshake *) IF outXonXoff IN opts THEN HALT(126) END; (* Xon/Xoff out flow control *) IF inXonXoff IN opts THEN HALT(126) END; (* Xon/Xoff in flow control *) IF inRTS IN opts THEN HALT(126) END; (* RTS flow control handshake *) t.c_lflag := 0; res := Termios.cfsetispeed(t, speed); IF res = 0 THEN res := Termios.cfsetospeed(t, speed); IF res = 0 THEN res := Termios.tcsetattr(fd, Termios.TCSANOW, t); IF res = 0 THEN res := Termios.tcflush(fd, Termios.TCIOFLUSH); IF res = 0 THEN NEW(c); c.hnd := fd; c.opts := opts; conn := c ELSE res := Libc.close(fd) END ELSE res := Libc.close(fd) END ELSE res := Libc.close(fd) END ELSE res := Libc.close(fd) END ELSE res := Libc.close(fd) END END END Open; PROCEDURE Close* (c: Connection); VAR res: INTEGER; BEGIN ASSERT(c # NIL, 20); ASSERT(c.hnd # -1, 21); res := Libc.close(c.hnd); c.hnd := -1 END Close; PROCEDURE (c: Connection) FINALIZE-; BEGIN IF c.hnd # -1 THEN Close(c) END END FINALIZE; PROCEDURE SendByte* (c: Connection; x: BYTE); VAR res: Libc.ssize_t; BEGIN ASSERT(c # NIL, 20); ASSERT(c.hnd # -1, 21); res := Libc.write(c.hnd, SYSTEM.ADR(x), 1); IF ~nonblocking THEN ASSERT(res = 1, 100) END END SendByte; PROCEDURE SendBytes* (c: Connection; IN x: ARRAY OF BYTE; beg, len: INTEGER); VAR res: Libc.ssize_t; BEGIN ASSERT(c # NIL, 20); ASSERT(c.hnd # -1, 21); ASSERT(LEN(x) >= beg + len, 22); ASSERT(len > 0, 23); res := Libc.write(c.hnd, SYSTEM.ADR(x) + beg, len); IF ~nonblocking THEN ASSERT(res = len, 100) END END SendBytes; PROCEDURE Available* (c: Connection): INTEGER; VAR res: INTEGER; read: INTEGER; BEGIN ASSERT(c # NIL, 20); ASSERT(c.hnd # -1, 21); read := -1; res := Ioctl.ioctl1(c.hnd, Ioctl.FIONREAD, read); ASSERT(res # -1, 100); ASSERT(read >= 0, 101); RETURN read END Available; PROCEDURE ReceiveByte* (c: Connection; OUT x: BYTE); VAR res: Libc.ssize_t; BEGIN ASSERT(c # NIL, 20); ASSERT(c.hnd # -1, 21); res := Libc.read(c.hnd, SYSTEM.ADR(x), 1); ASSERT(res = 1, 100) END ReceiveByte; PROCEDURE ReceiveBytes* (c: Connection; OUT x: ARRAY OF BYTE; beg, len: INTEGER); VAR res: Libc.ssize_t; BEGIN ASSERT(c # NIL, 20); ASSERT(c.hnd # -1, 21); ASSERT(LEN(x) >= beg + len, 22); ASSERT(len > 0, 23); res := Libc.read(c.hnd, SYSTEM.ADR(x) + beg, len); ASSERT(res = len, 100) END ReceiveBytes; PROCEDURE SetBuffers* (c: Connection; inpBufSize, outBufSize: INTEGER); BEGIN ASSERT(c # NIL, 20); ASSERT(c.hnd # -1, 21); (* HALT(126) *) END SetBuffers; PROCEDURE SetDTR* (c: Connection; on: BOOLEAN); VAR res: INTEGER; modembits: INTEGER; BEGIN ASSERT(c # NIL, 20); ASSERT(c.hnd # -1, 21); ASSERT(~(inDTR IN c.opts), 22); res := Ioctl.ioctl1(c.hnd, Ioctl.TIOCMGET, modembits); ASSERT(res # -1, 100); IF on THEN modembits := ORD(BITS(modembits) + Ioctl.TIOCM_DTR) ELSE modembits := ORD(BITS(modembits) - Ioctl.TIOCM_DTR) END; res := Ioctl.ioctl1(c.hnd, Ioctl.TIOCMSET, modembits); ASSERT(res # -1, 101) END SetDTR; PROCEDURE SetRTS* (c: Connection; on: BOOLEAN); VAR res: INTEGER; modembits: INTEGER; BEGIN ASSERT(c # NIL, 20); ASSERT(c.hnd # -1, 21); ASSERT(~(inRTS IN c.opts), 22); res := Ioctl.ioctl1(c.hnd, Ioctl.TIOCMGET, modembits); ASSERT(res # -1, 100); IF on THEN modembits := ORD(BITS(modembits) + Ioctl.TIOCM_RTS) ELSE modembits := ORD(BITS(modembits) - Ioctl.TIOCM_RTS) END; res := Ioctl.ioctl1(c.hnd, Ioctl.TIOCMSET, modembits); ASSERT(res # -1, 101) END SetRTS; PROCEDURE SetBreak* (c: Connection; on: BOOLEAN); VAR res: INTEGER; BEGIN ASSERT(c # NIL, 20); ASSERT(c.hnd # -1, 21); IF on THEN res := Ioctl.ioctl0(c.hnd, Ioctl.TIOCSBRK) ELSE res := Ioctl.ioctl0(c.hnd, Ioctl.TIOCCBRK) END; ASSERT(res # -1, 100) END SetBreak; PROCEDURE CTSState* (c: Connection): BOOLEAN; VAR res: INTEGER; modembits: INTEGER; BEGIN ASSERT(c # NIL, 20); ASSERT(c.hnd # -1, 21); res := Ioctl.ioctl1(c.hnd, Ioctl.TIOCMGET, modembits); ASSERT(res # -1, 100); RETURN BITS(modembits) * Ioctl.TIOCM_CTS = Ioctl.TIOCM_CTS END CTSState; PROCEDURE DSRState* (c: Connection): BOOLEAN; VAR res: INTEGER; modembits: INTEGER; BEGIN ASSERT(c # NIL, 20); ASSERT(c.hnd # -1, 21); res := Ioctl.ioctl1(c.hnd, Ioctl.TIOCMGET, modembits); ASSERT(res # -1, 100); RETURN BITS(modembits) * Ioctl.TIOCM_DSR = Ioctl.TIOCM_DSR END DSRState; PROCEDURE CDState* (c: Connection): BOOLEAN; VAR res, errno: INTEGER; modembits: INTEGER; BEGIN ASSERT(c # NIL, 20); ASSERT(c.hnd # -1, 21); res := Ioctl.ioctl1(c.hnd, Ioctl.TIOCMGET, modembits); ASSERT(res # -1, 100); RETURN BITS(modembits) * Ioctl.TIOCM_CAR = Ioctl.TIOCM_CAR END CDState; END CommV24. Ioctl: Код: MODULE LinIoctl ["libc.so.6"]; (* A. V. Shiryaev, 2012.11 GNU/Linux i386 *) CONST (* /usr/include/i386-linux-gnu/bits/ioctl-types.h *) TIOCM_LE* = {0}; TIOCM_DTR* = {1}; TIOCM_RTS* = {2}; TIOCM_ST* = {3}; TIOCM_SR* = {4}; TIOCM_CTS* = {5}; TIOCM_CAR* = {6}; TIOCM_RNG* = {7}; TIOCM_DSR* = {8}; FIOCLEX* = 21585; FIONCLEX* = 21584; FIONREAD* = 21531; FIONBIO* = 21537; FIOASYNC* = 21586; TIOCMGET* = 21525; TIOCMSET* = 21528; TIOCEXCL* = 21516; TIOCNXCL* = 21517; TIOCOUTQ* = 21521; TIOCSBRK* = 21543; TIOCCBRK* = 21544; TIOCMBIS* = 21526; TIOCMBIC* = 21527; PROCEDURE [ccall] ioctl0* ["ioctl"] (d: INTEGER; req: INTEGER): INTEGER; PROCEDURE [ccall] ioctl1* ["ioctl"] (d: INTEGER; req: INTEGER; VAR arg: INTEGER): INTEGER; END LinIoctl. Termios: Код: MODULE LinTermios ["libc.so.6"]; (* A. V. Shiryaev, 2012.11 GNU/Linux i386 *) CONST NCCS* = 32; VINTR* = 0; VQUIT* = 1; VERASE* = 2; VKILL* = 3; VEOF* = 4; VTIME* = 5; VMIN* = 6; VSWTC* = 7; VSTART* = 8; VSTOP* = 9; VSUSP* = 10; VEOL* = 11; VREPRINT* = 12; VDISCARD* = 13; VWERASE* = 14; VLNEXT* = 15; VEOL2* = 16; IGNBRK* = 1; (* {0} *) BRKINT* = 2; (* {1} *) IGNPAR* = 4; (* {2} *) PARMRK* = 8; (* {3} *) INPCK* = 16; (* {4} *) ISTRIP* = 32; (* {5} *) INLCR* = 64; (* {6} *) IGNCR* = 128; (* {7} *) ICRNL* = 256; (* {8} *) IUCLC* = 512; (* {9} *) IXON* = 1024; (* {10} *) IXANY* = 2048; (* {11} *) IXOFF* = 4096; (* {12} *) IMAXBEL* = 8192; (* {13} *) IUTF8* = 16384; (* {14} *) OPOST* = 1; (* {0} *) OLCUC* = 2; (* {1} *) ONLCR* = 4; (* {2} *) OCRNL* = 8; (* {3} *) ONOCR* = 16; (* {4} *) ONLRET* = 32; (* {5} *) OFILL* = 64; (* {6} *) OFDEL* = 128; (* {7} *) VTDLY* = 16384; (* {14} *) VT0* = 0; (* {} *) VT1* = 16384; (* {14} *) B0* = 0; (* {} *) (* hang up *) B50* = 1; (* {0} *) B75* = 2; (* {1} *) B110* = 3; (* {0,1} *) B134* = 4; (* {2} *) B150* = 5; (* {0,2} *) B200* = 6; (* {1,2} *) B300* = 7; (* {0..2} *) B600* = 8; (* {3} *) B1200* = 9; (* {0,3} *) B1800* = 10; (* {1,3} *) B2400* = 11; (* {0,1,3} *) B4800* = 12; (* {2,3} *) B9600* = 13; (* {0,2,3} *) B19200* = 14; (* {1..3} *) B38400* = 15; (* {0..3} *) CSIZE* = 48; (* {4,5} *) CS5* = 0; (* {} *) CS6* = 16; (* {4} *) CS7* = 32; (* {5} *) CS8* = 48; (* {4,5} *) CSTOPB* = 64; (* {6} *) CREAD* = 128; (* {7} *) PARENB* = 256; (* {8} *) PARODD* = 512; (* {9} *) HUPCL* = 1024; (* {10} *) CLOCAL* = 2048; (* {11} *) B57600* = 4097; (* {0,12} *) B115200* = 4098; (* {1,12} *) B230400* = 4099; (* {0,1,12} *) B460800* = 4100; (* {2,12} *) B500000* = 4101; (* {0,2,12} *) B576000* = 4102; (* {1,2,12} *) B921600* = 4103; (* {0..2,12} *) B1000000* = 4104; (* {3,12} *) B1152000* = 4105; (* {0,3,12} *) B1500000* = 4106; (* {1,3,12} *) B2000000* = 4107; (* {0,1,3,12} *) B2500000* = 4108; (* {2,3,12} *) B3000000* = 4109; (* {0,2,3,12} *) B3500000* = 4110; (* {1..3,12} *) B4000000* = 4111; (* {0..3,12} *) __MAX_BAUD* = B4000000; ISIG* = 1; (* {0} *) ICANON* = 2; (* {1} *) ECHO* = 8; (* {3} *) ECHOE* = 16; (* {4} *) ECHOK* = 32; (* {5} *) ECHONL* = 64; (* {6} *) NOFLSH* = 128; (* {7} *) TOSTOP* = 256; (* {8} *) IEXTEN* = 32768; (* {15} *) TCOOFF* = 0; TCOON* = 1; TCIOFF* = 2; TCION* = 3; TCIFLUSH* = 0; TCOFLUSH* = 1; TCIOFLUSH* = 2; TCSANOW* = 0; TCSADRAIN* = 1; TCSAFLUSH* = 2; TYPE tcflag_t* = INTEGER; (* unsigned int *) cc_t* = SHORTCHAR; (* unsigned char *) speed_t* = INTEGER; (* unsigned int *) termios* = RECORD [untagged] c_iflag*: tcflag_t; (* input mode flags *) c_oflag*: tcflag_t; (* output mode flags *) c_cflag*: tcflag_t; (* control mode flags *) c_lflag*: tcflag_t; (* local mode flags *) c_line*: cc_t; (* line discipline *) cc_c*: ARRAY [untagged] NCCS OF cc_t; (* control chars *) c_ispeed*: INTEGER; (* input speed *) c_ospeed*: INTEGER; (* output speed *) END; (* POSIX.1 *) PROCEDURE [ccall] cfgetispeed* (VAR tp: termios): speed_t; PROCEDURE [ccall] cfsetispeed* (VAR tp: termios; ispeed: speed_t): INTEGER; PROCEDURE [ccall] cfgetospeed* (VAR tp: termios): speed_t; PROCEDURE [ccall] cfsetospeed* (VAR tp: termios; ospeed: speed_t): INTEGER; PROCEDURE [ccall] tcgetattr* (fd: INTEGER; VAR tp: termios): INTEGER; PROCEDURE [ccall] tcsetattr* (fd: INTEGER; action: INTEGER; VAR tp: termios): INTEGER; PROCEDURE [ccall] tcdrain* (fd: INTEGER): INTEGER; PROCEDURE [ccall] tcflow* (fd: INTEGER; action: INTEGER): INTEGER; PROCEDURE [ccall] tcflush* (fd: INTEGER; action: INTEGER): INTEGER; PROCEDURE [ccall] tcsendbreak* (fd: INTEGER; len: INTEGER): INTEGER; END LinTermios. В OpenBSD работает, в Linux не проверял. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |