• Как исправить ошибку буфера с UART?

    @communistic_sistema Автор вопроса
    jcmvbkbc, проблема, увы не исчезла, 67кб передаются с теми же 33к ошибок
    DWORD ComIface::write(byte* data, int count) {
        DWORD NumOfWritten, status;
        OVERLAPPED overlap = { 0 };
        overlap.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
        if (!overlap.hEvent) {
            printf("CreateEvent failed with error %d.\n", GetLastError());
            return 0;
        }
        if (!WriteFile(port_handle, data, count, &NumOfWritten, &overlap)) {
            status = GetLastError();
            if (status != ERROR_IO_PENDING) {
                printf("WriteFile failed with error %d.\n", status);
                CloseHandle(overlap.hEvent);
                return 0;
            }
    		status = WaitForSingleObject(overlap.hEvent, read_delay);
    		if (status == WAIT_ABANDONED || status == WAIT_FAILED) {
    			printf("WaitForSingleObject failed with error %d.\n", GetLastError());
    		}
            if (!GetOverlappedResult(port_handle, &overlap, &NumOfWritten, TRUE)) {
                printf("GetOverlappedResult failed with error %d.\n", GetLastError());
            }
        }
        CloseHandle(overlap.hEvent);
        return NumOfWritten;
    }
    DWORD ComIface::read(byte* buffer, int size) {
        DWORD NumberOfBytesReaded = 0, status = 0;
        OVERLAPPED overlap = { 0 };
        overlap.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
        if (!overlap.hEvent) {
            printf("CreateEvent failed with error %d.\n", GetLastError());
            return 0;
        }
        if (!ReadFile(port_handle, buffer, size, NULL, &overlap)) {
            status = GetLastError();
            if (status != ERROR_IO_PENDING) {
                printf("ReadFile failed with error %d.\n", status);
                CloseHandle(overlap.hEvent);
                return 0;
            }
    		status = WaitForSingleObject(overlap.hEvent, read_delay);
    		if (status == WAIT_ABANDONED || status == WAIT_FAILED) {
    			printf("WaitForSingleObject failed with error %d.\n", GetLastError());
    		}
            if (!GetOverlappedResult(port_handle, &overlap, &NumberOfBytesReaded, TRUE)) {
                printf("GetOverlappedResult failed with error %d.\n", GetLastError());
            }
        }
        CloseHandle(overlap.hEvent);
        return NumberOfBytesReaded;
    }
    Написано
  • Как исправить ошибку буфера с UART?

    @communistic_sistema Автор вопроса
    res2001, для обработки ERROR_IO_PENDING как раз и применяется WaitForSingleObject. И как таймауты могут навредить передаче при одном чтении? Зачем использовать EV_ERR когда мы передаем и получаем одинаковое кол-во байт? Куда переполнится буфер если мы всего для теста запускаем 1 отправку и 1 чтение, а запас в 1,5х объема?
    Написано
  • Как исправить ошибку буфера с UART?

    @communistic_sistema Автор вопроса
    jcmvbkbc, м... хорошая идея, спасибо
    После тестов сообщу результаты
    Написано
  • Как исправить ошибку буфера с UART?

    @communistic_sistema Автор вопроса
    jcmvbkbc, могу прислать и верилог, тег в вопросе потому что ПЛИС используется
    Написано
  • Как исправить ошибку буфера с UART?

    @communistic_sistema Автор вопроса
    res2001, я могу полностью прислать код и спросить "верно?", "работать будет?". Но это не гарантирует снижение вероятности ошибок ни на одной из сторон. Я не понимаю почему ONESTOPBIT ломает передачу на 533 байте со смещением на 1 и почему при ONE5STOPBITS происходит смещение на 25 байт. Это не типичное поведение. Но недозаписал или еще что, но у тебя будет нормальное начало и незначащий конец, а это все здесь, в этой ситуации, значащие данные с определенным порядком, который задали мы со сдвигом в 25 позиций.
    Откуда эти 25 позиций?!
    Написано
  • Как исправить ошибку буфера с UART?

    @communistic_sistema Автор вопроса
    res2001,
    bool ComIface::open(int _port_num, bool log) {
        //create port name
        wchar_t strbuffer[11];
        swprintf_s(strbuffer, 11, L"\\\\.\\COM%d", _port_num);
        //create port handle
        port_handle = CreateFileW(
            strbuffer,
            GENERIC_READ | GENERIC_WRITE,
            0,                              //must be opened with exclusive-access
            NULL,                           //default security attributes
            OPEN_EXISTING,                  //must use OPEN_EXISTING
            FILE_FLAG_OVERLAPPED,           //async I/O
            NULL                            //hTemplate must be NULL for comm devices
        );
        //check if handle is valid
        if (port_handle == INVALID_HANDLE_VALUE) {
            if (log) {
                printf("CreateFileW failed with error %d.\n", GetLastError());
            }
            return false;
        }
        //set port settings
        if (!SetCommState(port_handle, &dcb)) {
            if (log) {
                printf("SetCommState failed with error %d.\n", GetLastError());
            }
            close();
            return false;
        }
        //set port timings
        COMMTIMEOUTS timings{
            10,      /* Maximum time between read chars. */
            10,     /* Multiplier of characters.        */
            10,     /* Constant in milliseconds.        */
            10,      /* Multiplier of characters.        */
            10       /* Constant in milliseconds.        */
        };
        SetCommTimeouts(port_handle, &timings);
        PurgeComm(port_handle, PURGE_RXCLEAR | PURGE_TXCLEAR);
        //set port state
        port_num = _port_num;
        return true;
    }

    Таймауты есть. ReadFile читает содержимое порта 1 раз, так что мы должны получить не смещение, а недозапись из порта в наш буфер, раз мы не гарантировано читаем все при передаче управления. Однако, ReadFile возвращает столько байт, сколько было и для WriteFile
    Сейчас цикл есть, но это цикл не "ожидание байта с прочтением в течении времени" а "ожидание блока байтов с прочтением их всех"
    Написано
  • Как исправить ошибку буфера с UART?

    @communistic_sistema Автор вопроса
    Ну так это и была попытка асинхронного IO, флаг файла - overlapped
    это не значит, что ReadFile гарантированно завершиться синхронно

    синхронно относительно кого?
    Цикл проблему не решает, ReadFile по 1 байту приводит к такому же результату (обе проблемы). Тем более смысл делать много чтений, когда я могу подождать пока туда положится нужный мне блок
    В попытках найти ответ на мои проблемы я находил посты что ReadFile и WriteFile медленные, однако прочитав не совсем понимал причину, однако скорость сейчас не в приоритете, в приоритете это рабочая передача блока любого размера, что физически порт может хранить в буфере
    Написано
  • Как исправить ошибку буфера с UART?

    @communistic_sistema Автор вопроса
    jcmvbkbc, это обеспечивает асинхронные EV_RXCHAR и EV_TXCHAR, нам нужно тестировать плис. Я не просто так указал verilog здесь, потому что я не уверен 100% что здесь нет ее вины.
    Написано
  • Как исправить ошибку буфера с UART?

    @communistic_sistema Автор вопроса
    jcmvbkbc, разве ReadFile/WriteFile при созданном файле с флагом overlapped можно использовать без overlapped и сохранить асинхронность?
    Написано
  • Как исправить ошибку буфера с UART?

    @communistic_sistema Автор вопроса
    jcmvbkbc, возвращаемый DWORD инициализирован как 0 в начале, не будет мусора.
    по поводу ReadFile и WriteFile:
    как я понял мне нужно убрать указатель на число обозначающее сколько было записано/прочтено, но оставить GetOverlappedResult для асинхронного порта
    Верно? Это и есть причина таких смещений и ошибок?
    Написано
  • Как исправить ошибку буфера с UART?

    @communistic_sistema Автор вопроса
    jcmvbkbc, то есть ReadFileEx должно упростить и исправить ситуацию?
    Проверка чтения идет по возвращаемому DWORD.
    Я уберу GetOverlappedResult, спасибо.
    Написано
  • Как исправить ошибку буфера с UART?

    @communistic_sistema Автор вопроса
    Передача ПК-ПЛИС-ПК в тот же самый порт
    DWORD ComIface::write(byte* data, int count) должна byte[N] записать в буфер порта на отправку
    Сложно потому что IO_PENDING, OVERLAPPED в асинхронном режиме должна быть не NULL в WriteFile
    Может GetOverlappedResult лишнее, но оно точно не влияет на число записанных байтов
    DWORD ComIface::read_block(byte* buffer, int size) должна за 1 ReadFile заполнить byte[N]
    Происходят 2 проблемы, я их указал, 1 мы починили костылем (потерпим), а вторую не починили
    Написано
  • Почему возникает ошибка error C4430 в шаблоне, если выходной тип определен?

    @communistic_sistema Автор вопроса
    тогда почему в решении, где лежит проект lib такого нет?
    Написано
  • Почему возникает ошибка error C4430 в шаблоне, если выходной тип определен?

    @communistic_sistema Автор вопроса
    Ошибка возникает на
    utils\include\hash.h(6,1): error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
    . Почему - я не понимаю, потому что все типы на всех этапах определены.
    Написано
  • Почему возникает ошибка error C4430 в шаблоне, если выходной тип определен?

    @communistic_sistema Автор вопроса
    Евгений Шатунов, проект в решении (lib)
    utils\include\hash.h
    #pragma once
    #include "type_info.h"
    namespace utils {
    	//template for iterable hashes, where iteration is independannt result
    	template<typename IN, typename OUT> constexpr inline
    	OUT	iterable_hash(const IN* in, size_t in_size, auto iterable_hash_lamda) {
    		static_assert(
    			!(sizeof(OUT) < sizeof(IN)), 
    			"iterable_hash can`t generate output type smaller than input type"
    		);
    		static_assert(
    			!type_in_type_wholes<IN, OUT>(),
    			"iterable_hash can`t input type must fil entirely output type"
    		);
    		//to do "static warning", when sizeof(in)*in_size=OUT
    		OUT result;
    		IN* out_pointer = (IN*)&result;
    		//make result = 0, supports arrays with constant legth (like int[2])
    		size_t i = type_in_type_capasity<IN, OUT>(), ii = 0;
    		while (i) {
    			out_pointer[--i] = 0;
    		}
    		//calculate hash, IN size is already a STEP size
    		i = type_in_type_capasity<IN, OUT>();
    		while (in_size) {
    			out_pointer[ii] = iterable_hash_lamda(out_pointer[ii], in[--in_size]);
    			if (++ii == i) {
    				ii = 0;
    			}
    		}
    		return result;
    	}
    	template<typename IN, typename OUT> constexpr inline
    	OUT	pearson_hash(const IN* in, size_t in_size) {
    		return iterable_hash<IN, OUT>(
    			in, in_size,
    			[](IN& out_step, const IN& in_step) {
    				return out_step ^ in_step;
    			}
    		);
    	};
    }

    token\object.h
    #pragma once
    #include "utils/include/hash.h"
    #include <stdint.h>
    #include <xstring>
    namespace tokenoperator::dte_token {
    #define TOKEN_NAME(lpwstr) token_name(lpwstr, std::char_traits<wchar_t>::length(lpwstr))
    	struct object {
    		public:
    			object(uint64_t ID) : ID(ID){}
    			virtual ~object() {}
    			uint64_t getID() const {
    				return ID; 
    			}
    		protected:
    			uint64_t ID;
    	};
    	constexpr inline uint64_t token_name(const wchar_t* wstr, size_t wstr_len) {
    		return utils::pearson_hash<wchar_t, uint64_t>(wstr, wstr_len);
    	}
    }

    в lib, другом проекте решения (exe) и в dll есть структуры наследники объекта, например
    token\data\include\value.h
    #pragma once
    #include "type.h"
    namespace tokenoperator::dte_token::data {
    	template<typename T>
    	struct value : object {
    		template <typename U> friend struct value;
    		public:
    			value(uint64_t ID = 0) : object(ID), t(ID) {}
    			template<typename U>
    			value(const U& v, uint64_t ID = 0) : object(ID), t(ID), v(v) {}
    			value(const T& v, uint64_t ID = 0) : object(ID), t(ID), v(v) {}
    			T& get_value() {
    				return v;
    			}
    			type<T> get_type() const { 
    				return t;
    			}
    		protected:
    			T v;
    			type<T> t;
    	};
    }

    в exe (другом проекте решения с lib именно) и dll экземпляры, причем в dll эти экземпляры еще не созданы (ну не написал, хочу сначала проверить что структура будет нормальной)
    Написано
  • Почему возникает ошибка error C4430 в шаблоне, если выходной тип определен?

    @communistic_sistema Автор вопроса
    Dmitrii, используется в функции
    constexpr inline uint64_t token_name(const wchar_t* wstr, size_t wstr_len) {
    	return utils::pearson_hash<wchar_t, uint64_t>(wstr, wstr_len);
    }

    а pearson_hash это
    template<typename IN, typename OUT> constexpr inline
    OUT pearson_hash(const IN* in, size_t in_size) {
    	return iterable_hash<IN, OUT>(
    		in, in_size,
    		[](IN& out_step, const IN& in_step) {
    			return out_step ^ in_step;
    		}
    	);
    };

    То есть wchar_t* переводится в uint64_t и функция которая это использует - явно объявляет типы, что должны быть и лежит в lib (token_name). В dll надо обеспечить возможность использовать данный шаблон, а также использовать стандартный вариант, который в lib. Я не понимаю что я делаю не так
    Написано
  • VS видит тело функции, почему возникает ошибка LNK2001?

    @communistic_sistema Автор вопроса
    Dmitrii, cpp добавлен верно, VS дает тела функции по их декларации. Не жалуется на их верность (я скопы/типы проверял, ошибок не нашел).
    VS при выносе тела создает в cpp такую же запись, только со словом inline, что как бы не меняет ситуацию.
    Когда определение в хэдере, функция стнаовится inline, может это может дать ответ?
    Ответ типа "пиши в хэдере" не подходит, я заранее сообщил о необходимости разделения деклараций от тел.
    Написано
  • VS видит тело функции, почему возникает ошибка LNK2001?

    @communistic_sistema Автор вопроса
    Dmitrii, если я пишу в прототипе ее тело, то она становится inline и все нормально, стоит сделать ее не inline, сразу возникают проблемы
    мне желательно отделять декларации от типов, поэтому я стремлюсь понят в чем проблема
    Написано
  • VS видит тело функции, почему возникает ошибка LNK2001?

    @communistic_sistema Автор вопроса
    Dmitrii,
    1>------ Сборка начата: проект: DynamicTokenEngine, Конфигурация: Debug x64 ------
    1>root_scope.cpp
    1>root_scope.obj : error LNK2001: неразрешенный внешний символ "public: virtual void __cdecl dte_core::add_module_struct::execute(struct tokenoperator::dte_token::function::bf_args *,unsigned __int64 *,bool,class std::vector > *,struct tokenoperator::dte_token::stream::stream *)" (?execute@add_module_struct@dte_core@@UEAAXPEAUbf_args@function@dte_token@tokenoperator@@PEA_K_NPEAV?$vector@_KV?$allocator@_K@std@@@std@@PEAUstream@956@@Z).
    1>root_scope.obj : error LNK2001: неразрешенный внешний символ "public: virtual void __cdecl dte_core::remove_module_struct::execute(struct tokenoperator::dte_token::function::bf_args *,unsigned __int64 *,bool,class std::vector > *,struct tokenoperator::dte_token::stream::stream *)" (?execute@remove_module_struct@dte_core@@UEAAXPEAUbf_args@function@dte_token@tokenoperator@@PEA_K_NPEAV?$vector@_KV?$allocator@_K@std@@@std@@PEAUstream@956@@Z).
    1>D:\DTE\DynamicTokenEngine\x64\Debug\DTE.exe : fatal error LNK1120: неразрешенных внешних элементов: 2
    1>Сборка проекта "DynamicTokenEngine.vcxproj" завершена с ошибкой.
    Написано