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

USB CDC +HAL. Как правильно обрабатывать переподключение?

Сгенерировал в CUBE проект USB CDC (библиотека HAL, контроллер STM32F103C8)

Завелось с полпинка, работает абсолютно без нареканий.

Одно но есть - с компом устройство общается через примитивный пока софт. Когда я перепрошиваю контроллер софт теряет связь с устройством. Это естественно и не вызывало удивления, пока я думал, что дело только в софте, который не обрабатывает ошибки. 

Однако, если перепрошить контроллер, а потом снова запустить софт - все равно нет подключения. Спасает только передергивание USB кабеля. 

Я так понял, что перепрошитое устройство должно давать какую-то команду не просто софту, а именно контроллеру USB в компьютере, чтобы "знакомство" прошло повторно?

Как это реализовать?

Инициализация USB у меня такая

 

void MX_USB_DEVICE_Init(void)
{
  /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
  
  /* USER CODE END USB_DEVICE_Init_PreTreatment */
  
  /* Init Device Library, add supported class and start the library. */
  if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)
  {
    Error_Handler();
  }
  if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK)
  {
    Error_Handler();
  }
  if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK)
  {
    Error_Handler();
  }
  if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */
  
  /* USER CODE END USB_DEVICE_Init_PostTreatment */
}

 

Обмен в главном цикле такой

 

 while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    referenceValue=GetTargetTemperature(TIME_POSITION);
		measurementValue=INFO_VAR.CurrentUpperThermoCouple;
		PID_out = pid_Controller(referenceValue, measurementValue);
		
		if (INFO_VAR.WORK_STATE==1)
		{
 		INFO_VAR.UpperFrontHeaterPOWER=PID_out;
	 	INFO_VAR.UpperRearHeaterPOWER=PID_out;
		}		
		InfoVarPrepare();
    CalculatePowerParametres();
		uint16_t len = strlen((const char*)UserRxBufferFS);  
    if(len > 0)
    {
      OptionsBufferDecode();
			InfoBufferCode();
   		CDC_Transmit_FS((uint8_t*)DataOut, sizeof(DataOut));      
      memset(UserRxBufferFS, 0, sizeof(UserRxBufferFS));

		
    }

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

54 минуты назад, -=Женек=- сказал:

Я так понял, что перепрошитое устройство должно давать какую-то команду не просто софту, а именно контроллеру USB в компьютере, чтобы "знакомство" прошло повторно?

Как это реализовать?

Читать спецификацию USB на тему "Сигнализация подключения отключения USB-device".

Там узнаете, что для перезапуска энумерации со стороны USB-хоста, USB-device должен (если это FS/HS-устройство) понизить уровень на линии D+ (отключить подтяжку резистором например - зависит от схемы) на некоторое время, а затем - обратно повысить уровень на D+ (включить резистор подтяжки).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 minutes ago, jcxz said:

Читать спецификацию

Читать исходный вопрос. Если Вы думаете, что при перезапуске контроллера подтяжка не отключается - ну... Вы очень странно думаете.

 

Проблема, возможно, в том, что виндовс как-то неадекватно себя ведёт при исчезновении COM-порта. Когда-то давно (в эпоху WinXP/Win7) разбирались. Если устройство пропало, потом появилось, в этот порт ничего записать уже нельзя (что логично, в принципе). Но и после того, как его закроешь, он как-то странно открывалось. Самое лучшее, что придумали - писишный программист сразу же после исчезновения устройства закрывал порт, при подключении пытался открыть обратно. Ну либо костыль: "дрыгать" коннект со стороны железки, если этот порт никто не открывает в течении N секунд.

На win10 я с этой проблемой не сталкивался, вероятно, в майкрософте это поправили.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, esaulenka сказал:

Если устройство пропало, потом появилось, в этот порт ничего записать уже нельзя (что логично, в принципе). Но и после того, как его закроешь, он как-то странно открывалось.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 минут назад, VladislavS сказал:

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

Дескриптор-то остался, и его (и связанные с ним ресурсы) надо вернуть в систему. Так что вполне логично и правильно вызвать CloseHandle() для порта, который отвалился.

 

1 час назад, esaulenka сказал:

Если Вы думаете, что при перезапуске контроллера подтяжка не отключается - ну... Вы очень странно думаете.

Надо схему смотреть. Насколько я помню, у F103 нет встроенной подтяжки USB, и приходится делать внешнюю. Схемы бывают разные, с транзисторами и без. И в некоторых случаях приходится предпринимать специальные действия в программе, чтобы вызвать ре-енумерацию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, esaulenka сказал:

Читать исходный вопрос. Если Вы думаете, что при перезапуске контроллера подтяжка не отключается - ну... Вы очень странно думаете.

Если Вы умеете видеть принципиальную схему автора на расстоянии, то Вы - Великий Ясновидец видимо. Я такими способностями не обладаю. :wink2:

А подтяжка может не отключаться при перезапуске МК по множеству причин. Достаточно хоть немного подумать (например: просто тупо стоит подтяжка всегда без управления от МК).

Это уже не говоря о том, что перезапуск МК может происходить очень быстро и если ТС даже не задумывался о состоянии подтяжки (что скорее всего так и есть), то у него при перезапуске эта подтяжка вообще может моргать на миллисекунды и USB-хост будет просто проигнорировать такое "отключение".

Цитата

Проблема, возможно, в том, что виндовс как-то неадекватно себя ведёт при исчезновении COM-порта. Когда-то давно (в эпоху WinXP/Win7) разбирались. Если устройство пропало, потом появилось, в этот порт ничего записать уже нельзя (что логично, в принципе). Но и после того, как его закроешь, он как-то странно открывалось.

Если COM-порт был открыт во время отключения USB-COM, то пока его не закроешь - он не будет работать. Но достаточно его закрыть и после этого можно открывать заново - и он должен открываться корректно.

Цитата

На win10 я с этой проблемой не сталкивался, вероятно, в майкрософте это поправили.

У меня на XP всё работает нормально - закрываю COM, потом открываю - и всё ок. Так что проблема думаю не в винде.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хм.. 

У меня внешнего управления подтяжкой нет. Плата -примитивная китайская отладочная.

Вижу три варианта

1. Не реализовано управление подтяжкой в самом контроллере

2. Наверное действительно во время ресета слишком мало времени проходит и кратковременное дерганье подтяжки ни на что не влияет.

3. На китайской плате между контроллером и usb стоит какая-то защита в 6ногом корпусе. Они ж разные бывают, может быть она и мешает управлению.

В общем, спасибо за наводку, приеду с дачи завтра - попробую.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, -=Женек=- сказал:

3. На китайской плате между контроллером и usb стоит какая-то защита в 6ногом корпусе. Они ж разные бывают, может быть она и мешает управлению.

Почитайте, может и мешает, хотя по симптомам случай не ваш:

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 часов назад, -=Женек=- сказал:

У меня внешнего управления подтяжкой нет. Плата -примитивная китайская отладочная.

Тогда надо ручками:

* при старте инициализируете ногу A12 как выход, переводите в 0 и ждёте немножко

* потом переключаете A12 в ANALOGINPUT, и вызываете инициализацию USB.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Долго же ТС будет искать ногу с таким заковыристым обозначением - F103C8 в "нечеловеческих" корпусах не бывают ;-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 минут назад, Obam сказал:

Долго же ТС будет искать ногу с таким заковыристым обозначением - F103C8 в "нечеловеческих" корпусах не бывают ;-)

Вы про A12? И в LQFP64, и даже в LQFP48 есть эта нога.

А, понял. Вы думали, что это номер ноги. Нет, это нога 12 порта A. Которая USB D+.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

59 minutes ago, AHTOXA said:

Тогда надо ручками:

* при старте инициализируете ногу A12 как выход, переводите в 0 и ждёте немножко

* потом переключаете A12 в ANALOGINPUT, и вызываете инициализацию USB.

Уже догадался. Но... неужели нельзя было сделать эту мелочь на аппаратном уровне? Нет, я не жалуюсь, мне просто не верится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мало ли, может у вас в работе F103V8I - попробуй отличи ногу (шар) А12 от, на самом деле, PA12.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Obam сказал:

Мало ли, может у вас в работе F103V8I - попробуй отличи ногу (шар) А12 от, на самом деле, PA12.

Может быть много чего, но в стартовом посте явно указан STM32F103C8. Так что ваша придирка мимо кассы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

.А подскажите мне такую вещь.

У меня usb cdc, устройство, настроенное соответствующим образом, определяется  в компе как виртуальный ком порт. Но при этом обладает атрибутами usb - именем устройства например.

Скажите, как прочитать имя устройста, определяющегося как компорт?

У меня на компе проект в Embarcadero, в нем компонент TAdpComport (из пакета AsyncPro). Кто -то работал с таким? Как узнать имя устройства? Ну или может если кто не работал именно с таким компонентом, но подскажет куда копать? А то неохота просто по номеру компорта подключатся. Хочется поименовать устройство и чтоб имено его искал софт на компе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...