Talk:Сериен порт

From Ilianko

php

Инсталира се ser2net и се конфигурира ser2net.conf

После се достъпва като стандартен сокет

if(isset($_POST['message']))
{
  $fp =fsockopen("localhost", 2000);
  
  if( !$fp) {
    echo "Error";die();
  }
  fread($fp, 128);
  fwrite($fp, "$_POST[message]");
  $status = fread($fp, 128);
  fclose($fp);


}

?>
<html><head></head>
<body>
<form name="serial" action="" method="post">
Message:  <input name="message" type="text"><input type="submit" value="Send">

<?= (isset($status))? $status:'' ?>
</form>
</body>
</html>

C#

Конфигуриране на системна конзола

http://www.cyberciti.biz/faq/howto-setup-serial-console-on-debian-linux/

В Ubuntu управлението на процесите при стартиране се управляват от Upstart програмата (която заменя и е обратно съвместима с init).

  • init e процес номер 1, PID - 1, т.е. той стартира всички останали процеси.
  • тествайте следната команда ps -A | less - извежда всички процеси.


След инициализиране на хардуера се стартира програмата getty и следват следните стъпки за вход:

  • getty извежда съобщението за вход
  • потребителят въвежда името на акаунта
  • getty стартира програмата login с параметър въведеното име
  • login изисква парола и проверя дали акаунтът е валиден в /etc/shadow
  • при валиден акаунт login извежда текущи съобщения от /etc/motd и стартира шел програма (примерно bash)
  • bash налични стартиращи скриптове (.bashrc)
  • bash извежда промта и чака команди

По подразбиране в Ubuntu getty се стартира на виртуални терминали от tty1 до tty6, на tty7 се стартира графичната система. За да се стартира getty и на серийния порт, то трябва да се добави файл /etc/init/ttyS0.conf със следното съдържание:

# ttyS0 - getty
#
# This service maintains a getty on ttyS0 from the point the system is
# started until it is shut down again.

start on stopped rc or RUNLEVEL=[2345]
stop on runlevel [!2345]

respawn
exec /sbin/getty -L 9600 ttyS0 vt102

След което да се рестартира компютъра или да се стартира процеса с командата

sudo start ttyS0

След така направената конфигурация Linux системата е достъпна през сериен порт

Връзки


Задача Влезте в Ubuntu през системнатa конзола и тествайте командите:

  • reboot,
  • halt,
  • shutdown.

Комуникация през C, POSIX и сериен порт

Задача Тествайте програмата, която изпраща информация по-серийния порт. Свържете два компютъра със сериен кабел, като на единия изпълнявате програмата, а на другия сте включили, някоя от терминалните програми за управление на серийната връзка от предходната задача. Тествайте с различни съобщения.


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>
#include <termios.h>

void handler(int nsig)
{
  int status;
  
  //wait for change in child 
  wait(&status);
  
  if(WIFEXITED(status))
  {  //if child is exited
    printf("Thank You!\n");
    exit(0);
  }
}

int main()
{
  int pid, serial;
  char ch;
  struct termios oIn, nIn, oSerial, nSerial;
    
  //open serial port
  serial = open("/dev/ttyS0", O_RDWR | O_NOCTTY);
  
  // Signal handler
  (void) signal(SIGCHLD, handler);
    
  // Current configuration
  tcgetattr(0,&oIn);
  tcgetattr(0,&nIn);
  tcgetattr(serial,&oSerial);
  tcgetattr(serial,&nSerial);
    
  // Raw mode 
  nIn.c_lflag = 0;
  nSerial.c_lflag = 0;
  
  // Set new configuration
  tcsetattr(0, TCSANOW, &nIn); //stdin
  tcsetattr(serial, TCSANOW, &nSerial);
    
  write(1,"For exit press \'q\' \n", 20);    
    
  fflush(stdout);
  fflush(stdin);
    
  // Create new process
  pid = fork();

  while(1)
  {
     if(pid < 1)
     {  // child process
        read(0,&ch,1); // read stdin
        write(serial,&ch, 1); //write to serial port
        
        if(ch == 'q')
        {
           tcsetattr(0, TCSANOW, &oIn); //restore original configuration
           tcsetattr(serial, TCSANOW, &oSerial);
           exit(0);
        }
      }
     else
     {  // parent process
        read(serial,&ch,1);
        write(1,&ch, 1);
     }
  }
  return(0);
}


/*********************************************************\
 * Title: Write to serial port
 * http://www.easysw.com/~mike/serial/serial.html
 * Edited by ilianko
\*********************************************************/

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */

#define PORTNAME  "/dev/ttyS0"

int main(void)
{
    int fd; // File descriptor for the port 
    struct termios options; // Serial port settings
	
	//Open for reading and writing + special FIFO port settings
    fd = open( PORTNAME, O_RDWR | O_NOCTTY | O_NONBLOCK);
	
    if (fd == -1)//Could not open the port.
	{
		perror("open_port: Unable to open port");
    }
    else 
    {
		//reset of file flags
		fcntl(fd, F_SETFL, 0);
	}
    
    tcgetattr(fd, &options);      //read controller settings
    
    
    cfsetispeed(&options, B2400); // change input speed
    cfsetospeed(&options, B2400); // change output speed
    
    options.c_cflag |= ( CREAD);  // enable reciever 
    options.c_cflag |= ( CLOCAL); // Local line - do not change "owner" of port
    options.c_cflag &= ( ~CSTOPB); // set 1 stop bit
    
    tcsetattr(fd,TCSANOW, &options); // load the controller settings

    write(fd, "a \n", 3); //write to 3 byte to the serial port
           
    return 0;
}

За повече информация Управление на сериен порт с POSIX, POSIX serial port

Осцилограма

Задача Създайте програма с безкраен цикъл, която да изпраща една буква към серийния порт. Използвайте специално пригодения кабел и разгледайте осцилограмата на сериен сигнал.

Четене сериен порт

Raw

/****************************************************************\
 * Edited by Ilianko
 * http://www.easysw.com/~mike/serial/serial.html
 * Description: Raw reading of the serial port
\****************************************************************/
#include <termios.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
      
#define BAUDRATE B2400
#define MODEMDEVICE "/dev/ttyUSB2"
       
int  main()
{
	int fd, c, res, stop = 0;
    struct termios oldtio,newtio;
    char buf[255];
        
    /* open the device to be non-blocking (read will return immediatly) */
    fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fd < 0) {perror(MODEMDEVICE); exit(-1);}
        
    fcntl(fd, F_SETFL, 0);
	fcntl(fd, F_SETFL, FNDELAY);        
        
    tcgetattr(fd,&oldtio); /* save current port settings */
        
    /* set new port settings for canonical input processing */
    newtio.c_cc[VMIN]=1;
    newtio.c_cc[VTIME]=0;
    
    newtio.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
    newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
    newtio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
            
	tcsetattr(fd,TCSANOW,&newtio);
	
	tcflush(fd, TCIFLUSH);
	
	/* loop while waiting for input. normally we would do something */
    while ( stop == 0)
	{
		usleep(100); 
        fflush (stdout);
        res = read(fd,buf,10);
        
        // strcat(buf,buf2);
          
        for( c=0; c<res; c++)
        {
           printf("%c", (char) buf[c]);
        }
	}
    tcsetattr(fd,TCSANOW,&oldtio);/* restore old port settings */
 return 0;
 }

Canonical

/****************************************************************\
 * Edited by Ilianko
 * Description: Raw reading of the serial port
\****************************************************************/

#include <termios.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
      
#define BAUDRATE B2400
#define MODEMDEVICE "/dev/ttyUSB2"
       
int  main()
{
	int fd, c, res, stop = 0;
    struct termios oldtio,newtio;
    char buf[255];
        
    /* open the device to be non-blocking (read will return immediatly) */
    fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fd < 0) {perror(MODEMDEVICE); exit(-1);}
        
    fcntl(fd, F_SETFL, 0);
	fcntl(fd, F_SETFL, FNDELAY);        
        
    tcgetattr(fd,&oldtio); /* save current port settings */
        
    /* set new port settings for canonical input processing */
    newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
    newtio.c_iflag = IGNPAR | ICRNL;
    newtio.c_oflag = 0;
    newtio.c_lflag = ICANON;
           
    newtio.c_cc[VMIN]=1;
    newtio.c_cc[VTIME]=0;
        
	tcsetattr(fd,TCSANOW,&newtio);
	tcflush(fd, TCIFLUSH);
	
	
	/* loop while waiting for input. normally we would do something */
    while ( stop == 0)
	{
		usleep(100); 
        fflush (stdout);
        res = read(fd,buf,10);
         
        for( c=0; c<res; c++)
        {
           printf("%c", (char) buf[c]);
        }
        
	}
    tcsetattr(fd,TCSANOW,&oldtio);/* restore old port settings */
 return 0;
 }

Самостоятелна подготовка

  1. Напишете името си на латиница, преобразувайте буквите с двоичен код и създайте времева диаграма на физическия сигнал.
  2. Да се напише програма, която изпраща символите от клавиатурата към серийния порт.
  3. Която да се логва през системната конзола и да рестартира Linux системата.

Край

Задача 11 Деинсталирайте GTKterm.

Упътване: Използвайте командата.

:~$ sudo apt-get purge gtkterm


Литература

http://en.wikipedia.org/wiki/RS-232 https://learn.sparkfun.com/tutorials/serial-communication/wiring-and-hardware