Function: make-serial-process

make-serial-process is a function defined in process.c.

Signature

(make-serial-process &rest ARGS)

Documentation

Create and return a serial port process.

In Emacs, serial port connections are represented by process objects, so input and output work as for subprocesses, and delete-process closes a serial port connection. However, a serial process has no process id, it cannot be signaled, and the status codes are different from normal processes.

make-serial-process creates a process and a buffer, on which you probably want to use process-send-string. Try M-x serial-term (serial-term) for an interactive terminal. See below for examples.

Arguments are specified as keyword/argument pairs. The following arguments are defined:

:port PORT -- (mandatory) PORT is the path or name of the serial port.
For example, this could be "/dev/ttyS0" on Unix. On Windows, this could be "COM1", or "\\\\.\\COM10" for ports higher than COM9 (double the backslashes in strings).

:speed SPEED -- (mandatory) is handled by serial-process-configure,
which this function calls.

:name NAME -- NAME is the name of the process. If NAME is not given,
the value of PORT is used.

:buffer BUFFER -- BUFFER is the buffer (or buffer-name) to associate
with the process. Process output goes at the end of that buffer, unless you specify a filter function to handle the output. If BUFFER is not given, the value of NAME is used.

:coding CODING -- If CODING is a symbol, it specifies the coding
system used for both reading and writing for this process. If CODING is a cons (DECODING . ENCODING), DECODING is used for reading, and ENCODING is used for writing.

:noquery BOOL -- When exiting Emacs, query the user if BOOL is nil and
the process is running. If BOOL is not given, query before exiting.

:stop BOOL -- Start process in the stopped state if BOOL is non-nil.
In the stopped state, a serial process does not accept incoming data, but you can send outgoing data. The stopped state is cleared by continue-process and set by stop-process.

:filter FILTER -- Install FILTER as the process filter.

:sentinel SENTINEL -- Install SENTINEL as the process sentinel.

:plist PLIST -- Install PLIST as the initial plist of the process.

:bytesize
:parity
:stopbits
:flowcontrol
-- This function calls serial-process-configure to handle these
arguments.

The original argument list, possibly modified by later configuration, is available via the function process-contact.

Examples:

(make-serial-process :port "/dev/ttyS0" :speed 9600)

(make-serial-process :port "COM1" :speed 115200 :stopbits 2)

(make-serial-process :port "\\\\.\\COM13" :speed 1200 :bytesize 7 :parity 'odd)

(make-serial-process :port "/dev/tty.BlueConsole-SPP-1" :speed nil)

View in manual

Probably introduced at or before Emacs version 23.1.

Source Code

// Defined in /usr/src/emacs/src/process.c
{
  int fd = -1;
  Lisp_Object proc, contact, port;
  struct Lisp_Process *p;
  Lisp_Object name, buffer;
  Lisp_Object tem, val;

  if (nargs == 0)
    return Qnil;

  contact = Flist (nargs, args);

  port = plist_get (contact, QCport);
  if (NILP (port))
    error ("No port specified");
  CHECK_STRING (port);

  if (NILP (plist_member (contact, QCspeed)))
    error (":speed not specified");
  if (!NILP (plist_get (contact, QCspeed)))
    CHECK_FIXNUM (plist_get (contact, QCspeed));

  name = plist_get (contact, QCname);
  if (NILP (name))
    name = port;
  CHECK_STRING (name);
  proc = make_process (name);
  specpdl_ref specpdl_count = SPECPDL_INDEX ();
  record_unwind_protect (remove_process, proc);
  p = XPROCESS (proc);

  fd = serial_open (port);
  p->open_fd[SUBPROCESS_STDIN] = fd;
  if (FD_SETSIZE <= fd)
    report_file_errno ("Opening serial port", port, EMFILE);
  p->infd = fd;
  p->outfd = fd;
  if (fd > max_desc)
    max_desc = fd;
  eassert (0 <= fd && fd < FD_SETSIZE);
  chan_process[fd] = proc;

  buffer = plist_get (contact, QCbuffer);
  if (NILP (buffer))
    buffer = name;
  buffer = Fget_buffer_create (buffer, Qnil);
  pset_buffer (p, buffer);

  pset_childp (p, contact);
  pset_plist (p, Fcopy_sequence (plist_get (contact, QCplist)));
  pset_type (p, Qserial);
  pset_sentinel (p, plist_get (contact, QCsentinel));
  pset_filter (p, plist_get (contact, QCfilter));
  eassert (NILP (p->log));
  if (tem = plist_get (contact, QCnoquery), !NILP (tem))
    p->kill_without_query = 1;
  if (tem = plist_get (contact, QCstop), !NILP (tem))
    pset_command (p, Qt);
  eassert (! p->pty_in && ! p->pty_out);

  if (!EQ (p->command, Qt)
      && !EQ (p->filter, Qt))
    add_process_read_fd (fd);

  update_process_mark (p);

  tem = plist_get (contact, QCcoding);

  val = Qnil;
  if (!NILP (tem))
    {
      val = tem;
      if (CONSP (val))
	val = XCAR (val);
    }
  else if (!NILP (Vcoding_system_for_read))
    val = Vcoding_system_for_read;
  else if ((!NILP (buffer) && NILP (BVAR (XBUFFER (buffer), enable_multibyte_characters)))
	   || (NILP (buffer) && NILP (BVAR (&buffer_defaults, enable_multibyte_characters))))
    val = Qnil;
  pset_decode_coding_system (p, val);

  val = Qnil;
  if (!NILP (tem))
    {
      val = tem;
      if (CONSP (val))
	val = XCDR (val);
    }
  else if (!NILP (Vcoding_system_for_write))
    val = Vcoding_system_for_write;
  else if ((!NILP (buffer) && NILP (BVAR (XBUFFER (buffer), enable_multibyte_characters)))
	   || (NILP (buffer) && NILP (BVAR (&buffer_defaults, enable_multibyte_characters))))
    val = Qnil;
  pset_encode_coding_system (p, val);

  setup_process_coding_systems (proc);
  pset_decoding_buf (p, empty_unibyte_string);
  eassert (p->decoding_carryover == 0);
  pset_encoding_buf (p, empty_unibyte_string);
  p->inherit_coding_system_flag
    = !(!NILP (tem) || NILP (buffer) || !inherit_process_coding_system);

  Fserial_process_configure (nargs, args);

  specpdl_ptr = specpdl_ref_to_ptr (specpdl_count);

  return proc;
}