Перейти к содержанию
    

flammmable

Свой
  • Постов

    298
  • Зарегистрирован

  • Посещение

Весь контент flammmable


  1. А давайте, учитывая количество сказанных вами слов "стандартный", вы выложите (или хотя бы назовёте) стандарт, регламентирующий, на ваш взгляд, количество бит в символе у порта (что бы это ни значило)? Про совет - это, очевидно, был сарказм. Ваши советы на уровне Ответов Майл-ру. Бесполезные и бессмысленные. Ощущение, словно вы копипастите их из ChatGPT.
  2. Ура! Однако, тут уместно повторить вопросу к вам Потому что как раз 9N1 вполне описан в стандарте Multi-Drop Bus. Теперь вернёмся к первому посту и перечитаем: А затем перечитаем вас: Вот совет, так совет. Именно таких, неочевидных, но предельно точных, ёмких, лаконичных и практических советов и ожидаешь, когда пишешь вопрос в глубоко профильное и авторитетное сообщество ))))
  3. Запись 8E1 означает 8 бит данных, один бит чётности (E - even, чётный) и один стоп-бит. Запись 8O2 означает 8 бит данных, один бит нечётности (O - odd, нечётный) и два стоп-бита. Запись 7N1 означает 7 бит данных, отсутствие бита чётности (N - none, нет/отсутствие) и один стоп-бит. Так что выражение... ...просто лишено смысла. Запись 9N1 не предусматривает каких-либо множественных трактовок и всяких "если". Если только это не "Ответы Майл-ру". Тогда да. Но от автора-завсегдатая "Ответов Майл-ру" и совет будет соответствующей ценности. Вроде такого:
  4. Что же FTDI не пишет об этом на его страничке... ...а также в документации (специально отсмотрел все 115 вхождений символа "9" в даташит)? Глобально, если передача 7N1 (а также всяких там 5N1 и 6N1) подразумевает банальное маскирование лишних битов в байте, пришедшем от хоста, то передача 9N1 предусматривает наличие пары байт на каждый символ формата 9N1. Такой специфический режим работы достаточно трудно спрятать где-то между строк. А потому возникает ряд дополнительных вопросов: 1) Вы лично, своими руками реализовывали на FT232RL режим 9N1? 2) Если нет, то что именно вселяет в вас уверенность, что данный режим существует в FT232RL? 3) Что по вашему означает "стандартные режимы" в контексте COM-порта? На ваш взгляд, есть какой-то стандарт, где перечислены возможные длины символов (сразу говорю, в TIA/EIA-232x этого нет и быть не может)?
  5. Мост XR21V1410 способен вести приём/передачу данных в редком режиме 9N1. Однако для этого ему нужно включить режим wide mode. То есть данному мосту можно установить длину символа, равную 9 битам, но с выключенным режимом wide mode последний бит символа всегда будет нулём. В режиме же wide mode на каждый символ, уходящий с Tx приходится 2 байта, приходящих в мост от USB (и во втором будет содержаться в том числе 9-й бит). Я нашёл любительский код (по-видимому, на Baisic), предназначенный для включения данного режима. Данный код изобилует "магическими" числами: Private Const ExarPortIndex = &H805 <...> Dim ExarWriteCode As Long = CTL_CODE(FILE_DEVICE_UNKNOWN, _ ExarPortIndex + 17, _ METHOD_BUFFERED, _ FILE_ANY_ACCESS) <...> Private Sub WriteReg(ByVal Reg As UInt16, ByVal Data As UInt16) <...> Dim Status As Boolean = DeviceIoControl(PortHandle, ExarWriteCode, inPtr, 4, -1, 0, ReturnedBytes, 0) <...> End Sub <...> WriteReg(&HD02, 1) ' Set Wide mode for XR21B1411 Я попробовал переписать данный код на C++, но мой код не заработал. Тогда я решил уменьшить его до минимума и (в рамках эксперимента) поменять уже установленный мосту битрейт при помощи функции DeviceIoControl: #include <windows.h> #include <winioctl.h> int main(int argc, char* argv[]) { HANDLE hUart; CHAR uartName[] = "\\\\.\\COM8"; hUart = CreateFileA(uartName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); DCB uartDCB; uartDCB.BaudRate = CBR_9600; uartDCB.ByteSize = 9; uartDCB.Parity = NOPARITY; uartDCB.StopBits = ONESTOPBIT; SetCommState(hUart, &uartDCB); DWORD bytesRet = 0; DWORD baudRate = CBR_14400; const UINT64 IOCTL_SERIAL_SET_BAUD_RATE = CTL_CODE(FILE_DEVICE_SERIAL_PORT, 1, METHOD_BUFFERED, FILE_ANY_ACCESS); DeviceIoControl(hUart, IOCTL_SERIAL_SET_BAUD_RATE, &baudRate, sizeof(baudRate), NULL, 0, &bytesRet, (LPOVERLAPPED)NULL); const UINT16 arrayLen = 2; UINT8 array[arrayLen]; array[0] = 0x33; array[1] = 0xFF; WriteFile(hUart, array, arrayLen, &bytesReturned, NULL); CloseHandle(hUart); return 0; } Данный код отработал как надо - я зафиксировал это по осциллограмме с линии Tx и по логу Serial Port Monitor (там видно, что IOCTL_SERIAL_SET_BAUD_RATE вызывается дважды, один раз для 9600 бит/с, второй раз для 14400 бит/с). Однако во-первых, в любительском примере макрос CTL_CODE принимает в качестве аргумента DeviceType значение FILE_DEVICE_UNKNOWN, а в моём коде это FILE_DEVICE_SERIAL_PORT, а во-вторых я не понимаю, что ставить в качестве аргумента Function - для смены битрейта я взял "1" из второй таблицы по этой ссылке. У любительского же примера там какое-то магическое число. В даташите на XR21V1410 на стр.12 есть таблица USB Сontrol Сommands , а на стр.15 есть таблица UART Register Map. Но что означают колонки Request Type, Request, Address - не вполне понятно. Не ясно также, как использовать значения в данных колонках для функции DeviceIoControl, чтобы включить wide mode. Что я должен поменять в своём коде, чтобы добиться от XR21V1410 полноценного режима 9N1?
  6. Добрый день. Есть необходимость открывать схему в MicroCap консольной командой, запускать анализ и складывать результаты в файл. И так - много раз. В MicroCap предусмотрен консольный запуск. Так, набрав <путь к экзешнику>\mc12_64.exe <путь к схеме>\Circuit.CIR ...MicroCap запустится и откроет данную схему. А если набрать <путь к экзешнику>\mc12_64.exe <путь к схеме>\Circuit.CIR /T ...то ещё и запустит транзиентный анализ, отрисовав графики. Хелп говорит, что есть также ключи /S, /IC, /IA, /IP, /IF, /I3 и /IH, которые позволяют сохранять как минимум картинки. В хелповском примере написано, в частности, так: .../IA Page="Main" Output="DelB.jpg" Но как я ни пытался заставить MicroCap сохранить хоть что-то, команда вида <путь к экзешнику>\mc12_64.exe <путь к схеме>\Circuit.CIR /T /IA Page="MAIN" Output="test_output.jpg" ...вызывает ошибку Error in command line '/IA Page="MAIN" Output="test_output.jpg"'. Кто знает, как работает сохранение результатов анализа в MicroCap по команде?
  7. Я к тому, что у данного устройства два варианта работы: с драйвером usbser.sys и с драйвером производителя. И если используется драйвер производителя, то там возможен обычный режим и wide mode - расширенный режим. И в расширенном режиме возможна конфигурация символа 9N1.
  8. Я так понимаю, что под "standard CDC-ACM driver" подразумевается usbser.sys. Там есть вариант подключить к XR21V1410 внешнюю конфигурационную память и, как я это понимаю, можно залить в неё такую конфигурацию, что тип устройства XR21V1410 определиться не как MISC(так он определяется без внешней памяти и подхватывается драйвером MaxLinear), а как CDC-ACM. Соответственно, виндовыц usbser.sys может его подхватить.
  9. Как говорит даташит на XR21V1410 Так что нет, не работает. Драйвер от производителя лишь предоставляет возможность включить данный режим путём расширения набора команд управления.
  10. Как отправить управляющую передачу (control transfer) устройству USB на чистом WinAPI?
  11. Добрый день! У меня есть микросхема XR21V1410, которая является мостом USB-UART. Согласно даташиту, она способна работать в обычном режиме (с 7, либо 8 информационными битами в символе UART), а также в расширенном режиме (wide mode), который поддерживает 9 информационных бит - 9N1. Согласно даташиту, для включения этого режима необходимо через USB сконфигурировать регистр UART CUSTOM REGISTER. А для этого нужно отправить команду XR_SET_REG. Согласно спецификации устройств CDC-ACM, к которым причисляются мосты USB-UART, минимально необходимым набором поддерживаемых команд является SET_LINE_CODING, GET_LINE_CODING и SET_CONTROL_LINE_STATE. Первые две для отправки и приёма символов, последняя - для отправки в мост конфигурации (битрейт, количество стоп-битов наличие/отсутствие бита паритета). Функции WinAPI для работы с мостами USB-UART прячут всё "под капот" - есть готовая функция SetCommState(), пользуйтесь ею, а про control transfer SET_CONTROL_LINE_STATE не думайте. Оно - хорошо, но как настроить на 9N1 мост XR21V1410? Я погуглил и нашёл такой пример, где используется XR_SET_REG. В этом примере XR_SET_REG подсовывается в функцию usb_control_msg. Проблема в том, что пример написан для Линукса. Я начал гуглить, есть ли в WinAPI функция, аналогичная usb_control_msg. Все примеры вели к библиотеке libusb. И действительно, в файле libusb_dyn.c данной библиотеки я нашёл следующую реализацию функции usb_control_msg: int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout) { if (_usb_control_msg) return _usb_control_msg(dev, requesttype, request, value, index, bytes, size, timeout); else return -ENOFILE; } Поискав по файлу, что же такое "_usb_control_msg" я нашёл это: static usb_control_msg_t _usb_control_msg = NULL; И, честно говоря, встал в тупик - как же именно на чистом WinAPI отправить control transfer мосту XR21V1410. Может быть кто-нибудь подскажет?
  12. Ваш комментарий помог отсечь весьма обширную область поиска ошибки. Большое спасибо! Всё заработало.
  13. Нет, вы ничего не придумали, USB-CDC именно так и построен. Ваш совет мне помог. Ешё раз, большое вам спасибо! :)
  14. В регистре RCC_CFGR есть поле PPRE[2:0]. Согласно даташиту оно отвечает за делитель тактового сигнала шины APB1. Я пытаюсь программно поменять данный делитель в STM32F070, применив следующий код: RCC->CFGR &= ~(RCC_CFGR_PPRE_Msk); RCC->CFGR |= RCC_CFGR_PPRE_DIV4; Однако, никаких изменений не происходит. Я прочитал, что для смены множителя PLL системы тактирования STM32 необходимо: 1) переключиться на HSI 2) выключить PLL 3) поменять множитель 4) включить PLL 5) переключиться на PLL Но касается ли это делителя PPRE? Он же находится "выше по течению", есть ли ему дело, включен ли PLL или нет? Если ему есть дело, то почему? Если нет и танцы с включением/выключением PLL здесь не причём, то как тогда поменять данный делитель на лету? P.S. Иллюстрация здесь не от STM32F070. В STM32F070 нет шины APB2, но принцип тот же.
  15. Играюсь с CDC на STM32F070. В функции CDC_Control_FS(...) файла usbd_cdc_if.c есть длинная структура switch-case. Её условие CDC_SET_LINE_CODING срабатывает, если происходит попытка передать в STM32-CDC конфигурацию UART (битрейт, количество стоп-битов и всё такое). Для кое-каких нужд я объявил в main.c глобальную переменную reconf_flag. В функции main() перед бесконечным циклом я присвоил ей ноль. А в самом бесконечном цикле я при помощи if(reconf_flag) проверяю, не поднялся ли флаг. Затем в usbd_cdc_if.c я объявил reconf_flag как extern. И в условии CDC_SET_LINE_CODING я присваиваю этой переменной единицу. Код, однако, не работает. Сначала я раскидал GPIOx->ODR по тексту, то есть отлаживал при помощи загорающихся LED: в условие CDC_SET_LINE_CODING программа заходит, в if(reconf_flag) внутри main() - нет. Затем прошёл отладчиком, поставив на if(reconf_flag) и на присвоение внутри CDC_SET_LINE_CODING точки останова. Видно, как сначала reconf_flag равен нулю, затем, как в CDC_Control_FS(...) ей присваивается единица, а затем уже в main() эта единица осознаётся отладчиком. Но! В тело if(reconf_flag) вход не происходит! Я посмотрел ассемблер на точке останова if(reconf_flag), он показывает 0x800037c: b.n 0x800037c У меня включена оптимизация -Os (optimization for size), без которой код просто не залезет в STM32F070 (у него маловато памяти). И я полагаю, что оптимизатор слишком вольно интерпретирует if(reconf_flag), перед которым происходит reconf_flag=0; Я думаю, оптимизатор видит, что в main.c переменная reconf_flag больше нигде не изменяется и вфигачивает этот ноль жёстко в условие if(0), которое никогда не отрабатывается. 1) Если оно так, то как сказать компилятору не делать этого? 2) Если оно не так, то почему не происходит вход в условие?
  16. Встречал ли кто-нибудь контрафактные микросхемы Prolific, которые бы определялись драйвером, как "THIS IS NOT PROLIFIC PL2303. PLEASE CONTACT YOUR SUPPLIER"? Если да, сохранились ли у кого-нибудь подобные микросхемы?
  17. fakemodem гораздо более лаконичен (хотя ioctl.c у него будь здоров) в сравнении с VirtualSerial2. По моему мнению начинать нужно с малого и двигаться к большому. Так-то исходный код com0com тоже выложен, но с начальными знаниями определить, что является в нём основным, а что вспомогательным, не представляется возможным.
  18. Вполне запустился и выдал отладку ) Разумеется, есть проблемы с запуском неподписанных драйверов. Но у Павла Йосифовича написаны рекомендации, как притупить бдительность системы проверки цифровой подписи, которым я следовал )
  19. Я считаю данные объяснения сугубо флеймом. Есть конкретная задача. Она чётко изложена в вопросе. Всё несущественное - отсечено ради лаконичности. Если у прочитавших есть ответ - хорошо. Если нет - вступать в дискуссию почему нужно именно это не вижу смысла. Ну, положим, докажу я вам, что утилитой com0com не обойтись. Вы что, скажете тогда "А, ну да. Тогда - да. Тогда - хорошо. Тогда <ответ по существу>"? Ведь нет же )) Это - во-вторых. А во-первых - ответ на интересующий меня вопрос уже был дан в самом первом посте )) Есть собеседники, компетенции которых позволяют дать прямой ответ на прямой вопрос. Моя задача (в целом, регулярно достигаемая) - контакт с ними. А не с теми, кто хочет править исходный вопрос до тех пор, пока он не войдёт в сферу их компетенции. Да, на Исходниках нашлась масса обормотов, которые начали рассказывать не то, что нужно, а то, что они знают. В духе: Но также там был и Majestio, который ответил по сути вопроса. На первых я просто не обращаю внимание )))
  20. Добрый день! Разбираюсь в процессе написания драйверов. Почитал Павла Йосифовича. Выкачал WDK, настроил Visual Studio, создал виртуалку с Windows. Вывел через KdPrint("Hello, world!"). И по скопипащенному из книги примеру при помощи драйвера и консольного приложения поменял приоритет треда. В последнем примере в функции DriverEntry создаётся (при помощи IoCreateSymbolycLink) текстовая ссылка (условно "MyDriver"), при помощи которой в main() приложения получается хэндлер: HANDLE hDevice = CreateFile(L"\\\\.\\MyDriver", ... Хочу создать виртуальный COM-порт. Для этого взял пример fakemode из майкрософтовских примеров. Я его успешно собрал, установил на виртуалку и запустил. COM-порт в диспетчере устройств не появился (что, наверное, логично). Значит, надо как-то сообщить драйверу о необходимости создания этого COM-порта. Но как? В DriverEntry у примера fakemodem нет создания текстовой ссылки: NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS status = STATUS_SUCCESS; WDF_DRIVER_CONFIG config; KdPrint(("Fakemode Function Driver Sample - Driver Framework Edition.\n")); KdPrint(("Built %s %s\n", __DATE__, __TIME__)); WDF_DRIVER_CONFIG_INIT( &config, FmEvtDeviceAdd ); status = WdfDriverCreate( DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, // Driver Config Info WDF_NO_HANDLE ); if (!NT_SUCCESS(status)) { KdPrint( ("WdfDriverCreate failed with status 0x%x\n", status)); } return status; } Но даже если как-нибудь (может, дописав в код fakemodem создание текстовой ссылки, а может , при помощи OpenDriver(...), но это не точно) удастся получить в приложении хэндлер, то что делать дальше? В примере от Microsoft нет кода приложения usermode для использования самого драйвера fakemodem.sys. Как ему внушить, что мне требуется создать COM-порт?
  21. Вместо Марка Руссиновича я читаю Павла Йосифовича ) Я уже выкачал WDK, настроил Visual Studio, создал виртуалку с Windows, вывел через KdPrint("Hello, world!"). И по скопипащенному из книги примеру при помощи драйвера и консольного приложения поменял приоритет треда. Да, консультации не заменят чтения, но заметно ускорят процесс, так как чтиву не задашь уточняющий вопрос. Вообще, мой опыт запросов платных консультаций говорит о несколько парадоксальной ситуации. Задаёшь вопрос на форуме: - <Вопрос> - <Странный, не раскрывающий суть ответ> [я не про текущий случая, а в целом; здесь вы сразу, лаконично, ёмко и по сути ответили] - Вы рассказываете здесь что-то не то. - А что вы хотели? Здесь всё бесплатно и добровольно, нам за это не приплачивают, между прочим. - Хорошо, давайте за деньги. - Ой, вы знаете, я, на самом деле, не специалист, а если и специалист, то давно этим не занимался, а если и занимался недавно то... Ой птичка, смотрите-смотрите! <убегает в противоположную сторону> Непонятный феномен ))) Ну да ладно. Попробую позадавать вопросы в данном разделе по мере возникновения )
  22. Большое спасибо за ответ по существу! Мне нужно, чтобы функционал моего приложения создавал в диспетчере устройств COM-порт в отсутствие внешних подключений. Я начал погружаться в тематику написания драйверов, но решил уточнить: зря или не зря. Если создание виртуального COM-порта невозможно без написания драйвера, то не зря. Большое спасибо, что вы есть! На форумах хватает "советчиков", которые на самом деле не знают ответа на конкретный вопрос, но отписаться желают. Потому они читают исходный вопрос через слово, перемешивают отдельные фразы в голове, формулируют какой-то свой вопрос и на него же отвечают. Это просто бич электронного комьюнити! Ещё один важный вопрос: кто разбирается в написании драйверов для Windows и может за деньги проконсультировать меня по Скайпу?
  23. Возможно ли без написания драйвера UMDF/KMDF и без применения готового ПО, вроде com0com, создать при помощи WinAPI приложение, которое бы имитировало бы работу COM порта в операционной системе?
  24. Я сгенерировал CubeMX-ом код для USB_DEVICE класса CDC. В числе прочего сренерировался файл usbd_cdc_if.c, в котором имеется функция-колбэк, предоставляющая принятые через USB данные: static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); USBD_CDC_ReceivePacket(&hUsbDeviceFS); return (USBD_OK); /* USER CODE END 6 */ } Как вытащить из неё данные (Buf/Len), скажем, в main(), для последующей обработки/анализа?
×
×
  • Создать...