Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Serial port communication between virtual machine and host Mini Program (part I)

2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/03 Report--

The host serial port tool is SSCOM32, and the virtual machine serial port tool is VSPD. That is, through the VSPD tool, the serial port of the two can be connected, and you can imagine that there is a serial port cable connecting the host and the virtual machine.

The first step is to determine the port

Open VSPD, as shown below, and click "Port pairs"-"create pair". What we need is COM1 and COM2. At this point, both states are: close.

Then, open the virtual machine, "Virtual Machine"-"Settings"-"Serial Port"-Select the port number, and turn it on, confirm.

As shown in the following figure, this means that the serial port is open.

Open SSCOM again, select "Serial Port 2", and open the serial port.

Similarly, in VSPD, it is observed that the serial port has been opened.

Step 2 Test

The virtual machine serial port sends to the host:

You can see that the host serial port received "hello".

Speaking of which, review "Terminal".

1. Console terminal: tty0~tty6, also known as virtual terminal. (tty0 is an alias for the virtual terminal currently in use)

2. Pseudo terminal: pty (graphics terminal, remote control terminal)

3. Serial port terminal: ttyS0~ttyS4

Control terminal: tty. That is, the terminal currently in use (any of the above may be the control terminal).

This, your own input and output redirection exercises will be clear.

At the same time, the information transmitted by the two can also be seen in the vspd:

Step 3 initialize serial port configuration information

Generally speaking, we can manually modify the serial port configuration information of virtual machines and hosts (baud rate, parity bit, stop bit, etc.), but is it troublesome to modify it every time? Therefore, you can write a file that initializes the serial port configuration information and execute it before communicating.

The code to initialize the serial port is as follows:

Port.h

# ifndef _ PORT_H_#define _ PORT_H_#include # include

< termios.h>

# include

< unistd.h>

# include

< sys/types.h>

# include

< sys/stat.h>

# include

< fcntl.h>

/ * * struct termios {tcflag_t cations; / / input modes tcflag_t cations; / / output modes tcflag_t cations; / / control modes tcflag_t casks; / / local modes cc_t cc [NCCs]; / / control chars} * / / set baud rate void setSpeed (struct termios * ptio,int speed); / / set data bit void setData (struct termios * ptio,int data); / / set parity void setParity (struct termios * ptio,int flag); / / 0-ignore parity 1-set parity 2-set parity 2-set parity / / set stop bit void setStop (struct termios * ptio,int stop) / / return value for initializing serial port: fdint portInit (char devname [], int speed,int data,int flag,int stop); # endif

Port.c

# include "port.h" / / set baud rate void setSpeed (struct termios * ptio,int speed) {switch (speed) {case 9600: cfsetispeed (ptio,B9600); cfsetospeed (ptio,B9600); break; case 14400: break; case 19200: cfsetispeed (ptio,B19200); cfsetospeed (ptio,B19200); break Case 38400: cfsetispeed (ptio,B38400); cfsetospeed (ptio,B38400); break; case 115200: cfsetispeed (ptio,B115200); cfsetospeed (ptio,B115200); break; default: break;}} / / set the data bit void setData (struct termios * ptio,int data) {ptio- > c_cflag & = ~ CSIZE Switch (data) {case 5: ptio- > c_cflag | = CS5; break; case 6: ptio- > c_cflag | = CS6; break; case 7: ptio- > c_cflag | = CS7; break; case 8: ptio- > c_cflag | = CS8; break Default: break;}} / / set parity 0-ignore parity 1-set parity 2-set parity void setParity (struct termios * ptio,int flag) {switch (flag) {case 0: ptio- > c_cflag & = ~ PARENB; break; case 1: ptio- > c_cflag | = PARENB Ptio- > c_cflag | = PARODD; ptio- > c_iflag | = (INPCK | ISTRIP); break; case 2: ptio- > c_iflag | = (INPCK | ISTRIP); ptio- > c_cflag | = PARENB; ptio- > c_cflag & = ~ PARODD; break; default: break }} / / set the stop bit (if the stop bit is 1, clear CSTOPB If the stop bit is 2, activate CSTOPB) void setStop (struct termios * ptio, int stop) {switch (stop) {case 1: ptio- > c_cflag & = ~ CSTOPB; break; case 2: ptio- > c_cflag | = CSTOPB; break; default: break }} / / return value for initializing serial port: fdint portInit (char devname [], int speed,int data,int flag,int stop) {int fd; struct termios tio = {0}; / / Open serial device fd = open (devname,O_RDWR); if (fd = =-1) {printf ("open port:% s failed.\ n", devname); return } / / get the original serial port configuration tcgetattr (fd,&tio); / / Activation options are CLOCAL and CREAD for local connection and receive enable tio.c_cflag | = CLOCAL | CREAD; / / set baud rate setSpeed (& tio,speed); / / set data bits, need to use mask to set setData (& tio,data); / / set parity setParity (& tio,flag) / / set stop bit setStop (& tio, stop); / / set minimum characters and wait time tio.c_ cc [VTIME] = 0; tio.c_ cc [VMIN] = 1; / / minimum characters returned when the number is reached in the buffer / / set without flow control tio.c_cflag & = ~ CRTSCTS; / / clear (input) cache tcflush (fd,TCIFLUSH) / / set the serial port to fcntl (fd,F_SETFL,0) by default; / / activate the configuration tcsetattr (fd,TCSANOW,&tio); return fd;}

How to check whether the serial port configuration is successful? To view information such as the baud rate of a serial port, enter the command in the console: stty-F / dev/ttyS0-a # ttyS0 is the serial port you want to view.

Step 4: read the configuration information

This has been shown in the previous article. In order to practice, you can read the configuration information from the configuration file and initialize it using the above code. Of course, you can also initialize it directly.

The following is the configuration information obtained from the file (based on the content of the previous article)

Configuration Information:

ReadConfig.h

# ifndef _ READCONFIG_H_#define _ READCONFIG_H_#include

< stdio.h>

# include

< string.h>

# include

< sys/types.h>

# include

< sys/stat.h>

# include

< fcntl.h>

/ * Serial port attribute structure * / struct t_port {char devname [20]; int speed; int data; int parity; int stop;}; / / unspace void rm_space (char * pStr); / / uncomment void rm_annotation (char * pStr); / / get configuration item information void getMsg (char filename [], struct t_port * port); # endif

ReadConfig.c

# include "readConfig.h" int icount = 0 pStr; pos / unblank void rm_space (char * pStr) {char * pos = pStr; pos = strchr (pStr,''); while (pos! = NULL) {strcpy (pos,pos+1); pos = strchr (pos,'');}} / uncomment void rm_annotation (char * pStr) {icount++; char * pos = pStr; char * end = NULL If (icount = = 1) / / the first line may top {pos = strchr (pStr,'#');} else {pos = strstr (pStr, "\ n #");} while (pos! = NULL) {end = strchr (pos+1,'\ n'); strcpy (pos,end); pos = strstr (pStr, "\ n #") }} / / get configuration item information void getMsg (char filename [], struct t_port * port) {int fd; int readByte; char buf [512] = ""; char * pos = NULL; char * end = NULL; char key [20] = ""; char value [20] = ""; char keys [10] [20] = {""}; char values [10] [20] = {""}; int flag = 0 Int I = 0; / / Open the configuration file fd = open (filename, O_RDWR); readByte = read (fd,buf,512); / / process data rm_space (buf); rm_annotation (buf); pos = strchr (buf,'\ n'); end = strchr (pos,'='); while (end! = NULL) {memset (key,0,sizeof (key)) Memset (value,0,sizeof (value)); memcpy (key,pos+1,end-(pos+1)); pos = end; end = strchr (pos,'\ r'); if (end = = NULL) / / if the final data {flag = 1; break;} memcpy (value,pos+1,end-(pos+1)) / save key value memcpy (Keys [I], key,strlen (key)); memcpy (values [I], value,strlen (value)); iTunes; pos = end + 1; end = strchr (pos,'=');} if (flag) {end = strchr (pos,'\ 0'); memcpy (value,pos+1,end-(pos+1)) Memcpy (Keys [I], key,strlen (key)); memcpy (values [I], value,strlen (value));} / / match for (I = 0; I

< 10 ;i++) { if(strcmp(keys[i],"dev") == 0) { strcpy(port->

Devname,values [I]);} else if (strcmp (keys [I], "speed") = = 0) {port- > speed = atoi (values [I]);} else if (strcmp (keys [I], "data") = = 0) {port- > data = atoi (values [I]) } else if (strcmp (keys [I], "parity") = = 0) {port- > parity = atoi (values [I]);} else if (strcmp (keys [I], "stop") = = 0) {port- > stop = atoi (values [I]);}

The fifth step is to write a communication program

In that case, the main function only needs to call the above function, and then call the read\ write system function.

# include

< stdio.h>

# include "port.h" # include "readConfig.h" int main () {int fd; char filename [20] = "serial.cfg"; char recbuf [100] = ""; char sendbuf [100] = ""; struct t_port port = {0}; / / get configuration information from file getMsg (filename,&port); / / Serial port initialization fd = portInit (port.devname,port.speed,port.data,port.parity,port.stop) / / Serial communication between host and virtual machine while (1) {memset (recbuf,0100); memset (sendbuf,0100); / / virtual machine waits for host user input and receives message printf ("please wait...\ n"); read (fd,recbuf,100); printf ("receive msg:% s\ n", recbuf) / wait for the virtual machine user to enter and send a message to the host printf ("send msg:"); scanf ("% s", sendbuf); if (strcmp (sendbuf, "over") = = 0) {break;} write (fd,sendbuf,sizeof (sendbuf));} close (fd); return 0;}

Step 6 compile and run

After compiling and running, the host (SSCOM32) virtual machine can communicate with each other. As shown below:

Host: hello

Virtual machine: world

Host: 12345

Virtual machine: over

At run time, if the host sends a message, the virtual machine cannot receive it because the contents of the message are still in the buffer. For example, if you do not type enter when sending data using write, the information will not be sent. This is mainly because we receive carriage return or line feeds according to the standard mode when we output input. In many cases, we do not need carriage return or line feeds. In this case, we should switch to line mode input, tio.c_lflag & = ~ (ICANON | ECHO | ECHOE | ISIG); send directly without processing.

Of course, you can also check "send new lines" directly on the SSCOM interface.

However, it can be found that we can only achieve: the host sends a sentence, the virtual machine receives the content before it can be sent, and then the host receives the content before it can continue to send. If you can't send both the host and the virtual machine at the same time, how to solve it? Multi-process is OK. Write again tomorrow.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report