непонятки с COM портом

Модератор: Модераторы разделов

Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

непонятки с COM портом

Сообщение RasenHerz »

решил написать программу для своего UPS, соединенного с компьютером через COM-порт. вот черновой вариант прораммы:

Код: Выделить всё

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termio.h>
#include <termios.h>

#define LEN 128

typedef int COMPORT;

char COM_dev[] = "/dev/ttyS0\0";
struct termios term;
struct termios oldterm;
COMPORT comport = -1;

enum UPS_Command {
    STATUS,
    TEST,
    BEEP,
    SDRC,
    CANCEL,
    INFO,
    RATING
};

int init_com(const char*);
void deinit_com();
int ups_send_msg(COMPORT, enum UPS_Command, void*);
void cp_termios(struct termios*, struct termios*);

/*
 *
 */
int main(int argc, char** argv) {
    char i = '0';
    COM_dev[cindex] = i;
    init_com(COM_dev);
    deinit_com();
    return 0;
}

int init_com(const char *com){
    if (!com)
        return -1;
    int fd = open(com, O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd < 0){
        perror("open_com");
        return -1;
    }
    if (tcgetattr(fd, &term) < 0){
        close(fd);
        return -1;
    }
    cp_termios(&term, &oldterm);
    if (cfsetispeed(&term, B2400) != 0 || cfsetospeed(&term, B2400) != 0){
        close(fd);
        return -1;
    }
    term.c_cflag &= ~CSIZE;
    term.c_cflag |= CS8;
    term.c_cflag |= CREAD;
    term.c_cflag &= ~CSTOPB;
    term.c_cflag |= CLOCAL;
    term.c_cflag |= CRTSCTS;
    if (tcsetattr(fd, TCSANOW, &term) < 0){
        close(fd);
        return -1;
    }
    char *buffer = (char*)malloc(LEN*3);
    memset(buffer, 0x0, LEN*3);
    if (ups_send_msg(fd, INFO, buffer)){
        printf("%s\n", buffer);
        free(buffer);
        comport = fd;
        return 1;
    }
    free(buffer);
    return -1;
}

void deinit_com(){
    if (comport < 0)
        return;
    tcsetattr(comport, TCSANOW, &oldterm);
    close(comport);
}

int ups_send_msg(COMPORT port,enum UPS_Command cmd, void *arg){
    if (port < 0)
        return -1;
    char buff[2];
    switch (cmd){
        case (INFO):
            buff[0] = 'I';
            buff[1] = '\r';
            write(port, buff, 2);
            if (arg){
                int b_read = 0;
                while ((b_read += read(port, arg+b_read, LEN)) > 0);
                if (b_read < 0){
                    perror("ups_send_msg");
                    break;
                }
                return b_read;
            }
            else {
                return 1;
            }
            break;
    }
    return -1;
}

void cp_termios(struct termios *from, struct termios *to){
    if (!from || !to)
        return;
    to->c_iflag = from->c_iflag;
    to->c_cflag = from->c_cflag;
    to->c_oflag = from->c_oflag;
    to->c_lflag = from->c_lflag;
    to->c_ispeed = from->c_ispeed;
    to->c_line = from->c_line;
    to->c_ospeed = from->c_ospeed;
    int i = 0;
    for (; i<NCCS;i++)
        to->c_cc[i] = from->c_cc[i];
}

при попытке прочесть из него выдает следующее: ups_send_msg: Resource temporarily unavailable
права на чтение и запись в /dev/ttyS0 есть.
спецификацию к UPS прилагаю.
буду очень рад если кто-нибудь поможет =)
Спасибо сказали:
_edgbla_
Сообщения: 13
ОС: OpenSUSE

Re: непонятки с COM портом

Сообщение _edgbla_ »

Откомпилил, ну мне как бы тоже самое пишет, но если со стороны ком порта нету устройства, если есть всё гуд, гляди распайку.
Правда читать не пробовал, так как вопрос был только про ups_send_msg: Resource temporarily unavailable.
:-D
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: непонятки с COM портом

Сообщение RasenHerz »

с кабель новый, порт рабочий =(
я совсем не понимаю что происходит, пробовал отключать проверку паритета и т.д. не помогает...
Спасибо сказали:
Аватара пользователя
Denjs
Сообщения: 1685
ОС: SuSe 10.2

Re: непонятки с COM портом

Сообщение Denjs »

гм.... я не могу вам помось непосредственно, с компортами разбирался давно.
совершенно не помню как работать с ними "на относительно низком уровне", т.к. делал это "год назад и ночью" >_<

НО! Если вам подойдет демо-код на QT? - могу попробовать посоветовать вам адаптировать под свои нужды мою утилиту поиска esc-pos принтера.

Скачивайте исходники проекта OTPD: http://developer.berlios.de/projects/otpd/
там в разделе исходники качайте файл "otpd.src.2008.05.22_0200.tar.gz" (полтора мегабайта)
раскрыв его, идите в каталог ./OTPD_project/otpd_utils/find_serial_escpos_printers"

Это утилита по списку перебирает компорты, скорости, посылает тестовый запрос и ждет ответ секунду. Соответственно выводит результат.
посмотрите код этой утилиты, замените данные запрос-ответа и думаю у вас должно все получиться.

Этот код полностью рабочий. По крайней мере у меня работал и принтеры типа "Epson TM-88" исправно находил.
Причем и под вендой и под линуксом. Все кроссплатформенное.
QDroid - Среда исполнения и фреймворк для QtScript.
OTPD - Открытые драйвера промышленных принтеров чеков и этикеток (кроссплатформенная подсистема печати).
Спасибо сказали: