Проблема при записи в последовательный порт на MacOS - PullRequest
0 голосов
/ 03 октября 2018

Фон

Я пытаюсь записать / напечатать на последовательный порт на MacOS Mojave.Последовательный порт подключен к термопринтеру с эмуляцией ESC / POS.Я использовал boost::asio::serial_port из boost 1.67.0 для этой задачи.См. Следующий код:

#define SUCCESS 0
#define FAIL -1

#include <string>
#include <cstdio>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/serial_port.hpp>

int main(int argc, char *argv[]){

    boost::system::error_code ec;
    boost::asio::io_service io;
    boost::asio::serial_port port( io );

    std::string portname="/dev/tty.usbserial-12";

    try{
        port.open(portname.c_str(), ec);

        if (ec) {
            std::cout << "error : port.open() failed... portname=" << portname << ", e=" << ec.message().c_str() << std::endl; 
            return FAIL;
        }
        port.set_option( boost::asio::serial_port_base::baud_rate( 19200 ) );

        unsigned char init[2] = { 27, 64 };
        unsigned char hello[6] = { 'h', 'e', 'l', 'l', 'o', '\0'};
        unsigned char cut[2] = { 29, 86 };

        boost::asio::write(port, boost::asio::buffer(init, sizeof(init)));
        boost::asio::write(port, boost::asio::buffer(hello, sizeof(hello)));
        boost::asio::write(port, boost::asio::buffer(cut, sizeof(cut)));

        port.close();
        return SUCCESS;
    }catch(...){
        return FAIL;
    }
}

РЕДАКТИРОВАТЬ 1

Я пытался использовать FileDescriptor, как показано в следующем фрагменте:

int fd; //Descriptor for the port
fd = open("/dev/tty.usbserial-12", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
    std::cout << "Unable to open port. \n";
    return FAIL;
}

struct termios options;

tcgetattr(fd, &options);
cfsetispeed(&options, B19200);
cfsetospeed(&options, B19200);

options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_oflag &= ~OPOST;
options.c_cflag |= CS8;
options.c_cflag |= (CLOCAL | CREAD);
tcsetattr(fd, TCSANOW, &options);

std::cout << "Port configured.\n";

unsigned char init[2] = { 27, 64 };
unsigned char hello[6] = { 'h', 'e', 'l', 'l', 'o', '\0'};
unsigned char cut[2] = { 29, 86};

int rv = FAIL;

rv = write(fd, init, 2);
if(rv<SUCCESS){
    std::cout << "could not write" << std::endl;
    return FAIL;
}

rv = write(fd, "hello\n", 6);
if(rv<SUCCESS){
    std::cout << "could not write" << std::endl;
    return FAIL;
}

rv = write(fd, cut, 2);
if(rv<SUCCESS){
    std::cout << "could not write" << std::endl;
    return FAIL;
}

std::cout << "closing FD" << std::endl;
close(fd);
return SUCCESS;

Вывод на консольпредыдущего фрагмента:

Port configured.
closing FD

К сожалению, нет ошибок и нет вывода на стороне устройства .

РЕДАКТИРОВАТЬ 1 КОНЕЦ

Я могу подтвердить, что MacOS обнаруживает подключенный последовательный порт, проверив вывод ls /dev/tty.usbserial* и ls /dev/cu.usbserial* до и после подключения его к моему Mac.

Кроме того, если я запускаю screen /dev/tty.usbserial-12 19200, а затем запускаю свое приложение, я получаю сообщение об ошибке, сообщающее, что resource busy.

Во время поиска в Интернете я обнаружил SimpleSerialреализация со следующим комментарием, написанным в верхней части файла:

ВАЖНО: В Mac OS X boost у последовательных портов asio есть ошибки, и обычная реализация этого класса не работает.Таким образом, класс временного решения был написан временно, пока asio (надеюсь) не исправит совместимость Mac с последовательными портами.Обратите внимание, что в отличие от сказанного в документации по OS X, пока asio не будет исправлен последовательный порт записи являются не асинхронными, но по крайней мере асинхронными read работает.Кроме того, при открытии последовательного порта игнорируются следующие параметры: четность, размер символа, поток, стоповые биты и по умолчанию формат 8N1.Я знаю, что это плохо, но, по крайней мере, лучше, чем ничего.

Я попытался выполнить поиск в Интернете, чтобы подтвердить наличие известной ошибки, но не смог найти соответствующую.

Issue

Приведенный выше код выполняется без ошибок, но по неизвестным мне причинам на принтере нет вывода.Я могу «печатать», используя screen /dev/tty.usbserial-12 19200.

Тот же код работает на Raspberry PI, работающем с raspbian, и выдает желаемый вывод на принтер.

Вопросы

Что-то не так с моим кодом?Я пропустил несколько шагов по пути?Как я могу решить эту проблему?

...