pathterminuspages/blog/aboutcontactabout me

Working with ttyS0 (serial port) Linux Mint vs. Windows 95

16.12.2017 | Computing/Vintage

OK. So I have a sort of a vintage computer. It's a Pentium II from around 1998. It runs Windows 95 and currently games like Diablo 1, Doom II and Command & Conquer : Red Alert. It has a serial port, so has my main computer running Linux Mint 18. I have had them connected before through Virtual Box running Windows 98, but now, I thought, would be a good time to get a more direct connection. So here we go.

Windows 95 comes shipped with HyperTerminal. Through that you can connect via the serial port/null modem. In the Linux terminal you can just pipe a message to the ttyS0 (the serial fd in linux):

HypterTerminal side of things

And then:

Linux Terminal thoughput

OK. But using Kermit you can actually send files. This is done first by starting Kermit. Then type the command set line /dev/ttyS0 and then typing connect. Kermit will not necessarily exit again, so use a terminal you are willing to just shut down. On Windows' site of things there's the button 'send file'. Chose kermit as protocol, and away we go:

HypterTerminal struggling to send a 100kb picture.

The sending rate is less than 1kb/s. So longer than 100 seconds for a picture of poor quality. That takes one back. Kermit of course has a send command, and HyperTerminal has a receive button. How sophisticated.

Kermit struggling to receive.

One last thing that could be fun to do, I thought. Let's create a program and thus automate! This is of course done using C and termios. For some reason we want to print a line 10 times to the receiver and then our self receive an input back. This is done so:

#include <termios.h> #include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> int main(){ struct termios config; int fd1 = open("/dev/ttyS0", O_RDWR); char buffer[100]; int result = 0; int haveRead = 0; int i = 10; if(fd1 == -1){ printf("error : fd1 = -1\n"); } if(!isatty(fd1)){ printf("error fd1\n"); } if(tcgetattr(fd1, &config) < 0){ printf("error : save settings\n"); } // 8bit,no parity,1 stopbit | // output hardware flow control | // local connection | // enable receiving characters config.c_cflag = CS8 | CRTSCTS | CLOCAL | CREAD; // ignore bytes with parity errors | // map CR to NL config.c_iflag = IGNPAR | ICRNL; // raw output config.c_oflag = 0; // enable canonical input config.c_lflag = ICANON; // clean line tcflush(fd1,TCIFLUSH); // activate port tcsetattr(fd1, TCSANOW, &config); // check speed if(cfsetispeed(&config, B9600) < 0 || cfsetospeed(&config, B9600) < 0){ printf("error : baudsomething\n"); } // iterate and write while(i > 0){ sleep(1); write(fd1,"Hello from GCC!\r\n",18); i--; } // wait for returning read while(haveRead < 1 && fd1 > -1 && result > -1){ result = read(fd1,buffer,255); haveRead += result; if(result < 0){ fprintf(stderr, "error in read : %s\n", strerror(errno)); break; } } if(haveRead < 0){ haveRead = 0; } buffer[haveRead] = '\0'; close(fd1); printf("connection closed.\n"); printf("buffer : %s\n",buffer); return 0; }

write must have the exact amount of chars to be written. If more, then parts of the printf (stdout) will be written to HyperTerminal. A bit odd. You have to put the '\0' char at end of the buffer. Else strange things will be written. And all things put the appropriate places we get (this image took me 5:56 to receive):

Hello from GCC!

And the view from Linux:

Hello from Windows!

Very interesting!

CommentsGuest Name:Comment: