LINUX.ORG.RU

Сообщения prostoR

 

C++ как проверить поток.

Добрый всем. Есть задачка, опрашивать датчик через определенный интервал времени (время опроса датчика не должно прерываться). После заполнения файла temp.txt он копируется по сети (далее создается новый файл temp.txt) и так по кругу.

Для реализации задачи я в программе запустил 2 потока, первый делает опрос, второй копирует данные.

Функция копирования файла для 2-го потока.

void CopyNetFile(std::string path) {
        DIR *dir;
        char dirbuffer[150];
        const char * test_path = path.c_str();
        strcpy(dirbuffer, test_path);
        dir = opendir(dirbuffer);

        if ( dir == NULL ) {
                printf("Каталог не доступен (копируй локально\n");
        }else{
                printf("DIR YES\n");
                std::string nametime = ""+path+"file.txt";
                std::string nametemp = "temp.txt";
                const char* p_c_nametemp = nametemp.c_str();
                const char* p_c_nametime = nametime.c_str();

                std::ifstream in(p_c_nametemp); // open original file
                std::ofstream out(p_c_nametime); // open target file
                out << in.rdbuf(); // read original file into target
                out.close(); // explicit close, unnecessary in this case
                in.close();// explicit close, unnecessary in this case
                unlink (p_c_nametemp);//удаляем файл
        }
}
Основной поток main
#include <thread>
int main(int argc,char *argv[]) {
   while (1){
      опрос датчика...
      if (пришло время копировать) {
         //Запускаем в отдельном потоке функцию 
         std::thread copy_thread(CopyNetFile,path);
         //Не дожидаемся выполнения функции продолжаем работу основного потока. 
         copy_thread.detach();
      }
   }
}
Все компилируется и копируется.
С потоками работаю первый раз, не знаю как проверить есть остановка основного потока или нет.

 ,

prostoR
()

Чтение запись COM порта

Отправляю пакет в com порт функция write проходит без ошибок и если буфер com порта не пустой отвечает нормально. Но если я отправляю пакет в com порт в бесконечном цикле, с паузой в 1 секунду, то первый пакет отрабатывает нормально, далее идут ошибки ввода\вывода Ниже код программы.

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <bitset>
#include <sys/ioctl.h>
#include "rsrw.h"

int main()
{
    char *portname = "/dev/ttyAMA0";
    int fd;
    int wlen;
    int rbuf = 0;

    fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
    if (fd < 0) {
        printf("Error opening %s: %s\n", portname, strerror(errno));
        return -1;
    }
    set_interface_attribs(fd, B57600);

//while (1){
    //sleep(1);
    const uint8_t wr[] = { 0x01, 0x01, 0x00, 0x01, 0x02, 0x03 };
    wlen = write(fd, &wr[0], sizeof(wr));
    if (wlen != sizeof(wr)) {
        printf("Error from write: %d, %d\n", wlen, errno);
    }
    tcdrain(fd);

    ioctl(fd,FIONREAD,&rbuf);
    if (rbuf > 0) {
        unsigned char buf[rbuf];
        int rdlen;
        rdlen = read(fd, buf, sizeof(buf) - 1);
        if (rdlen > 0) {
        #ifdef DISPLAY_STRING
            buf[rdlen] = 0;
            printf("Read %d: \"%s\"\n", rdlen, buf);
        #else
            unsigned char *p;
            printf("Read %d:", rdlen);
            for (p = buf; rdlen-- > 0; p++)
                printf(" 0x%x", *p);
            printf("\n");
        #endif
        } else if (rdlen < 0) {
            printf("Error from read: %d: %s\n", rdlen, strerror(errno));
        }
    }
//}
}
В файле rsrw.h описана функция set_interface_attribs();
int set_interface_attribs(int fd, int speed)
{
    struct termios tty;

    if (tcgetattr(fd, &tty) < 0) {
        printf("Error from tcgetattr: %s\n", strerror(errno));
        return -1;
    }

    cfsetospeed(&tty, (speed_t)speed);
    cfsetispeed(&tty, (speed_t)speed);

    tty.c_cflag |= (CLOCAL | CREAD);    
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;         /* 8-bit characters */
    tty.c_cflag &= ~PARENB;     /* no parity bit */
    tty.c_cflag &= ~CSTOPB;     /* only need 1 stop bit */
    tty.c_cflag &= ~CRTSCTS;    /* no hardware flowcontrol */
    tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
    tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    tty.c_oflag &= ~OPOST;
    tty.c_cc[VMIN] = 1;
    tty.c_cc[VTIME] = 1;

    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        printf("Error from tcsetattr: %s\n", strerror(errno));
        return -1;
    }
    return 0;
}

Может кто знает в чем моя ошибка.

 , ,

prostoR
()

C++ неблокирующие сокет

Всем привет начал изучать сокет и у меня вопросы.
Если кто имел опыт помогите плиз
Если описать в 2-х словах я использую библиотеку «set» чтобы облегчить работу с набором дескрипторов.

Я взял готовый пример и у меня получилось. Но дескриптор формируется автоматически, я думаю нужно научится значение дескриптора назначать самому. Клиент должен передать параметры а сервер должен назначит ему дескриптор не в произвольном порядке, что бы по данному дескриптору вести обмен информацией.
При подключении клиента на стороне сервера срабатывает функция «accept»

socklen_t addr_size;
set<int> clients;
...
while(1)
    {
     ....
     addr_size = sizeof(addr);
     sock = accept(listener, (struct sockaddr *)&addr, &addr_size);
     fcntl(sock, F_SETFL, O_NONBLOCK);
     clients.insert(sock);
}
sock = дескриптор
На стороне клиента функция connect
connect(sock, (struct sockaddr *)&addr, sizeof(addr));

Может нужно передать правильно struct?

 , , ,

prostoR
()

C++ Работа с бинарными файлами

Добрый ... всем! Пытаюсь обработать бинарные файлы в каталоге bin в цикле. Первое что я сделал это в buf загнал название файла, потом соединил их с путем. Далее преобразовал в const char* и передал функции ifstream. Ниже код и описание проблемы.

#include <stdio.h>
#include <iostream>
#include <fstream>
#include <ctime>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
using namespace std;
int main(int argc, const char ** argv)
{
        char buf[1024];
        FILE * ls;
        int result;
        int i;
        const char* fname;
        strcpy(buf,"ls ./Bin/");
        for (i=1; i < argc; i ++) {
                strcat (buf, argv[i]);
                strcat (buf, " ");
        }
        ls = popen(buf,"r");
        if(!ls){
                perror("popen");
                return 1;
        }
        while(fgets(buf, sizeof(buf), ls)) {
                std::string namefile = std::string("./Bin/") + buf;
                fname = namefile.c_str();
                ifstream instrm (fname, std::ios::binary);
                //printf ("%s\n", fname);
                signed short t[240000] = {0};
                instrm.read((char *)t, sizeof(t));      // чтение файла в массив
                instrm.close();                         // закрываем
                for(int i = 0; i < sizeof(t)/sizeof(*t); i++){   // цикл вывода массива
                        cout << t[i] << ' ';
                }
                cout << '\n';
        }
        result = pclose(ls);
        if(!WIFEXITED(result)) return 1;
        return 0;
}

Проблема в том что если я ставлю переменную

ifstream instrm (fname, std::ios::binary);
не работает нули идут, а если указываю файл работает.
ifstream instrm ("./Bin/file.bin", std::ios::binary);
Ошибок при компиляции нет!

 ,

prostoR
()

C++ стравнения значений

С++ нет опыта только учусь. Может кто знает
У меня есть такой код

std::bitset<8> b(9b); //(9b меняется)
Потом я преобразую в строку
std::string str = b.to_string();
Получаю массив двоичного кода 10011011
Мне надо поставить условие
if (str[0] == 1) { printf ("OK"/n);}
Но сравнение не работает. Я пробовал 1 загнать в переменную и преобразовать в тип char int.

 , ,

prostoR
()

C++ изменить HEX на BIN

Добрый день. Есть векторный массив

std::vector<uint8_t> read;
На выходе я получаю
printf("%02x", read[0]);
Результат printf «9b»
Задача c 9b получить 10011011
И я тут завис
Как разделить 9 и b что бы определить бинарный код.
Функций стандартных я не нашел.

 , , ,

prostoR
()

Протокол обмена Linux -> датчик

Добрый день. Первая программа на С++, ругайте только не сильно. Задача вроде простая, есть датчик температуры с выходом RS485 порта я его через конвертер подключил к RS232. При загрузки датчика в консоль дает ответ «Ready». По документации датчик отвечает на запросы, не сыпет данные в консоль постоянно. Запрос состоит из шестнадцатеричного кода [старт бит] ..... [стоп бит] (набор битов есть). Я написал программу

int fd;
int k;
std::vector<uint8_t> wr;
uint8_t buf[512] = { 0 }; 
struct termios oldtio, newtio;
int open_port();

int main(int argc,char **argv){
        fd = open_port();

        wr.clear();
        wr.insert(wr.begin(), 0x56);
        wr.push_back(0x65);
        wr.push_back(0x01);
        wr.push_back(0x02);
        wr.push_back(0x98);
        wr.push_back(0x56);

        /*WRITE*/
        int m;
        for (m=0; m<=wr.size()-1; m++){
                write(fd, &wr[m], wr.size());
                printf(" for= %x \n", wr[m]);
        }
     
        /*READ*/
        while(k!=-1) {
                k=read(fd,buf,512);
                printf(" k= %d  \n",k);
                printf(" buf= %x  \n",buf[0]);
                sleep(1);
        }
        close(fd);
        return(0);
}
int open_port(){
   struct sigaction saio; 
   fd = open(/dev/ttyS0, O_RDWR | O_NOCTTY |O_NONBLOCK);
   fcntl(fd, F_SETOWN, getpid()); 
   fcntl(fd, F_SETFL, O_ASYNC|O_NONBLOCK|fcntl(fd, F_GETFL));
   tcgetattr(fd,&oldtio); /* save current port settings */
   cfsetispeed(&newtio, B9600); 
   cfsetospeed(&newtio, B9600); 
   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;
   if((tcsetattr(fd,TCSANOW,&newtio)) != 0){ 
        printf("Error setattr\n");
        exit(1);
   }
   return (fd);
}
Ответа нет!
Возможно я не правильно даже посылаю пакет, а может считываю не правильно. Если есть у кого опыт поделитесь!

Функцию open_port() нашел в интернете.
include не стал перечислять, компиляция проходит.

 , ,

prostoR
()

RSS подписка на новые темы