⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial.c

📁 MANTIS是由科罗拉多大学开发的传感器网络嵌入式操作系统。 这是mantis的0.9.5版本的源码。
💻 C
字号:
//  This file is part of MANTIS OS, Operating System//  See http://mantis.cs.colorado.edu/////  Copyright (C) 2003,2004,2005 University of Colorado, Boulder////  This program is free software; you can redistribute it and/or//  modify it under the terms of the mos license (see file LICENSE)/*  Project Mantis  File:   serial.c  Authors: Jeff Rose  Date:   02-01-04    Mac layer built on top of serial uart devices.*/#include "mos.h"#ifdef PLATFORM_LINUX#include <stdlib.h>#include <strings.h>#include <sys/time.h>#include "serial.h"#include "com.h"#include "msched.h"#include "mutex.h"#include "arg.h"#include <pthread.h>#include <signal.h>#if defined(SERIAL) || !defined(SCONS)/** @brief Terminal settings. */struct termios oldtio, newtio; static comBuf *packetBuf;static pthread_t serial_tid = 0;int serialfd = -1;uint8_t current_mode;void serial_listen ();void serial_init_fd (){   uint8_t *serial_dev;   uint8_t *new_baud;   int baud;   // Check to see if someone specified a different serial port   if (!mos_arg_check ("--sdev", &serial_dev))      serial_dev = DEFAULT_SERIAL_DEV;         if (!mos_arg_check ("--sbaud", &new_baud))   {      baud = DEFAULT_BAUDRATE;   } else {      if(strcmp(new_baud, "B2400") == 0) {	 baud = B2400;      } else if(strcmp(new_baud, "B4800") == 0) {	 baud = B4800;      } else if(strcmp(new_baud, "B9600") == 0) {	 baud = B9600;      } else if(strcmp(new_baud, "B19200") == 0) {	 baud = B19200;      } else if(strcmp(new_baud, "B38400") == 0) {	 baud = B38400;      } else if(strcmp(new_baud, "B57600") == 0) {	 baud = B57600;      } else if(strcmp(new_baud, "B115200") == 0) {	 baud = B115200;      } else if(strcmp(new_baud, "B230400") == 0) {	 baud = B230400;      } else {	 printf("Error in baud setting, try '--sbaud B57600'\n");	 baud = DEFAULT_BAUDRATE;      }      printf("specified baud: %s\n", new_baud);         }   printf("opening serial\n");   // Init the actual serial device.  The NOCTTY means this   // terminal won't have any process control.  (That way if a   // control-C happens to come down the line we don't get dropped.)   if (serialfd == -1) {      serialfd = open (serial_dev, O_RDWR | O_NOCTTY);      if (serialfd < 0) {	 printf("ERROR OPENING SERIAL\n");	 perror (serial_dev);	 exit (-1);      }   } else {      printf ("Serial port is already open\n");      return;   }   tcgetattr (serialfd, &oldtio); // save current port settings      // Setup new serial port settings   bzero (&newtio, sizeof (newtio));   // manually do what cfmakeraw () does since cygwin doesn't support it   newtio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP |		       INLCR | IGNCR | ICRNL | IXON);   newtio.c_oflag &= ~OPOST;   newtio.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);   newtio.c_cflag &= ~(CSIZE | PARENB);   newtio.c_cflag |= CS8;   newtio.c_iflag &= ~(INPCK | IXOFF | IXON);   newtio.c_cflag &= ~(HUPCL | CSTOPB | CRTSCTS);   newtio.c_cflag |= (CLOCAL | CREAD);      // set input mode (non-canonical, no echo,...)   newtio.c_lflag = 0;     newtio.c_cc[VTIME] = 0;   // min time between chars (*.1sec)   newtio.c_cc[VMIN] = 1;   // min number of chars for read    cfsetispeed (&newtio, baud);   cfsetospeed (&newtio, baud);   tcflush (serialfd, TCIFLUSH);   tcsetattr (serialfd,TCSANOW,&newtio);}uint8_t serial_init (){   serial_init_fd();   //initialize the serial mutex   //mos_mutex_init(&serial_mutex);      current_mode = IF_OFF;      // get initial buffer   com_swap_bufs (IFACE_SERIAL, NULL, &packetBuf);   packetBuf->size = 0;   // Create a thread to constantly listen on the serial port and   // save packets if we are in listen mode   if(serial_tid == 0)      mos_thread_new (serial_listen, 128, PRIORITY_NORMAL);      return 0;}void serial_close (){   if (serialfd != -1) { //if the file descriptor has been set...      close (serialfd); //close the file descriptor      serialfd = -1;    //set the value to initial known value   }}void serial_block(){   //mos_mutex_lock(&serial_mutex);}void serial_unblock(){   //mos_mutex_unlock(&serial_mutex);}void serial_flush (){   tcflush (serialfd, TCIFLUSH);}uint8_t com_send_IFACE_SERIAL (comBuf *buf){   uint8_t byte = PREAMBLE;   uint8_t i;   int retval;   mos_mutex_lock (&if_send_mutexes[IFACE_SERIAL]);      // Send the preamble then the size and packet   for(i = 0; i < PREAMBLE_SIZE; i++) {      retval = write (serialfd, &byte, 1);      if (retval == -1)	 goto serial_send_error;   }   retval = write (serialfd, &buf->size, 1);   if (retval == -1)      goto serial_send_error;   retval = write (serialfd, &buf->data, buf->size);   if (retval == -1)      goto serial_send_error;   retval = tcdrain (serialfd);serial_send_error:   if (retval == -1)      perror("com_send_IFACE_SERIAL");			   mos_mutex_unlock (&if_send_mutexes[IFACE_SERIAL]);      return 0;}uint8_t serial_get_mode (){   return current_mode;}void com_mode_IFACE_SERIAL (uint8_t mode){   if (mode != current_mode) {      switch (mode) {      case IF_OFF:	 break;      case IF_STANDBY:      case IF_IDLE:      case IF_LISTEN:	 break;      default:	 break;      }      current_mode = mode;   }}void com_ioctl_IFACE_SERIAL (uint8_t request, ...){   int baud_rate;   va_list ap;   va_start(ap, request);   switch (request) {   case BAUD_RATE:      baud_rate = va_arg (ap, int);      printf ("Setting new baud rate: %d\n", baud_rate);      newtio.c_cflag = baud_rate | CS8 | CLOCAL | CREAD;      tcflush (serialfd, TCIFLUSH);      tcsetattr (serialfd, TCSANOW, &newtio);      break;   }   va_end(ap);}/** @brief See full description. *  * This function is meant to be run as a separate thread that is * constantly reading bytes off the serial port.  In order to make * the behavior the same in xmos and amos I am dropping packets * unless the user has explicitly turned on the serial device.  */void serial_listen (){   uint8_t byte, preamble_count, bytesRead;   uint8_t *dataPtr;   int retval;      preamble_count = 0;      serial_tid = pthread_self ();      while (1) {      retval = read (serialfd, &byte, 1);      if (retval > 0) {	 // Check for the preamble	 if (byte == PREAMBLE) {	    preamble_count++;	    	    // After the preamble we can get the size and read the packet	    if (preamble_count == PREAMBLE_SIZE) {	       retval = 0;	       while (retval == 0) {		  retval = read (serialfd, &packetBuf->size, 1);	       }	       if (retval == -1) {		  perror("serial_listen: read");		  continue;	       }	       dataPtr = packetBuf->data;	       bytesRead = 0;	       while (bytesRead < packetBuf->size) {		  retval = read (serialfd, dataPtr, packetBuf->size - bytesRead);		  if (retval == -1) {		     perror("serial_listen: read");		     break;		  }		  bytesRead += retval;		  dataPtr = packetBuf->data + bytesRead;	       }	       // Only send the packet up to the com layer if we are actually	       //  in listen mode	       if (current_mode == IF_LISTEN) {		  com_swap_bufs (IFACE_SERIAL, packetBuf, &packetBuf);		  while (packetBuf == NULL) {		     fprintf (stderr, "Ran out of packets...\n");		     usleep (250);		     com_swap_bufs (IFACE_SERIAL, packetBuf, &packetBuf);		  }	       }	       preamble_count = 0;	    }	 } else // Only a valid preamble if all the bytes show up in a row	    preamble_count = 0;      }      else if (retval == -1) {	 perror("serial_listen: read");      }   }}#endif#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -