Je travaille sur un projet depuis deux semaines maintenant et le débogage de ce problème a pris toute la semaine. Vous vous demandez si quelqu'un peut m'aider, je vais essayer d'être aussi explicite et clair que possible.
J'essaie d'implémenter un port de communication virtuel USB sur un MicroController basé sur le STM32F302K8 (Cortex M4). J'ai utilisé STM32CubMX pour générer le code nécessaire à la configuration d'un périphérique USB pleine vitesse implémentant une classe CDC. Mon appareil apparaît à la fois sous Windows (Gestionnaire de périphériques) et Linux. Je suis en mesure d'implémenter une fonction d'écho simple basée sur l'exemple de code mais lorsque j'essaie maintenant d'utiliser la fonction USBD_CDC_SetTxBuffer pour envoyer des données au PC, cela déclenche un gestionnaire de pannes matérielles. J'ai réduit cela au fait que le champ UsbDeviceFS.pClass (qui est requis par USBD_CDC_SetTxBuffer) n'est jamais initialisé car USBD_CDC_Init () n'est jamais appelé dans l'initialisation du périphérique USB.
J'ai implémenté des correctifs pour plusieurs bogues (y compris la modification de la taille du segment de mémoire , la correction de l'indicateur de transmission dans USBD_CDC_TransmitPacket et la modification de la taille de CDC_DATA_HS_MAX_PACKET_SIZE à 256 contre 512) dans l'exemple de code tel que documenté sur le forum ST mais toujours avec la même erreur.
Le code de configuration de mon appareil est
* USB Device Core handle declaration */
USBD_HandleTypeDef hUsbDeviceFS;
/* init function */
void MX_USB_DEVICE_Init(void)
{
/* Init Device Library,Add Supported Class and Start the library*/
USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);
USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC);
USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS);
USBD_Start(&hUsbDeviceFS);
}
Réponses:
Pour répondre à ma propre question, le problème est que mon code n'a pas attendu l'USB pour terminer l'initialisation et a immédiatement commencé à envoyer des données. L'insertion d'une attente active sur un booléen ou l'ajout d'un délai (comme souligné par @ramez) résout le problème.
MISE À JOUR Ce bogue a été corrigé dans les versions ultérieures du pilote CDC USB de ST. Il y a maintenant un HAL_Delay dans la configuration. Attention, si pour une raison quelconque Sys_Tick ne fonctionne pas / est désactivé / pas encore initialisé, votre code se bloque.
la source
J'ai utilisé CubeMX pour générer du code pour la découverte STM32F4. Je l'ai utilisé comme port COM virtuel comme vous. Je n'ai pas utilisé directement la fonction USBD_CDC_SetTxBuffer () . Dans le fichier usbd_cdc_if.c , il y a une fonction nommée CDC_Transmit_FS () . Il y avait un bug dans le code généré, la fonction a pris un tampon en paramètre et n'a rien fait avec. Le code de fonction corrigé est le suivant:
En fait, j'ai dû ajouter le memcpy au code. Après cette correction, j'ai pu envoyer des données du microcontrôleur au PC avec cette fonction de transmission. Par exemple:
L'initialisation dans MX_USB_DEVICE_Init () est la même chez moi que la vôtre.
la source
Vérifiez d'abord si hUsbDevice_0 est nul (élément manquant dans votre solution):
Cela empêchera de suspendre votre uC et n'a pas besoin d'attendre trop longtemps.
Vous pouvez le placer quelque part dans CDC_Transmit_FS:
la source
J'ai eu le même problème mais il s'est avéré que la seule chose que je devais faire était de rebrancher la connexion USB à l'ordinateur. La plupart du temps, vous flashez le code et réinitialisez le microcontrôleur, mais du côté PC, l'énumération n'est pas mise à jour. USBD_CDC_Init est appelé lorsque l'hôte commence à sonder votre appareil et c'est pourquoi pClassData est NULL.
la source