Фон
Я пытаюсь записать / напечатать на последовательный порт на 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, и выдает желаемый вывод на принтер.
Вопросы
Что-то не так с моим кодом?Я пропустил несколько шагов по пути?Как я могу решить эту проблему?