STM32 USB VCP बग


8

मैं पिछले दो सप्ताह से एक परियोजना पर काम कर रहा हूं और इस पूरे सप्ताह में इस एक मुद्दे पर बहस हुई है। आश्चर्य है कि अगर कोई मदद कर सकता है, तो मैं यथासंभव स्पष्ट और स्पष्ट होने की कोशिश करूंगा।

मैं STM32F302K8 (कोर्टेक्स एम 4) के आधार पर एक माइक्रोकंट्रोलर पर एक यूएसबी वर्चुअल कॉम पोर्ट को लागू करने की कोशिश कर रहा हूं। मैंने CDC क्लास को लागू करने वाले USB Full Speed ​​Device स्थापित करने के लिए आवश्यक कोड उत्पन्न करने के लिए STM32CubMX का उपयोग किया है। मेरी डिवाइस विंडोज (डिवाइस मैनेजर) और लिनक्स दोनों में दिखाई देती है। मैं उदाहरण कोड के आधार पर एक साधारण इको फ़ंक्शन को लागू करने में सक्षम हूं, लेकिन जब मैं अब पीसी में डेटा भेजने के लिए फ़ंक्शन USBD_CDC_SetTxBuffer का उपयोग करने का प्रयास करता हूं , तो यह एक हार्ड फॉल्ट हैंडलर सेट करता है। मैंने इसे इस तथ्य से कम कर दिया है कि UsbDeviceFS.pClass (जो USBD_CDC_SetTxBuffer द्वारा आवश्यक है) फ़ील्ड को कभी भी आरंभीकृत नहीं किया जाता है क्योंकि USBD_CDC_Init () USB डिवाइस के प्रारंभ में कभी नहीं कहा जाता है।

मैंने कई फ़िक्स को लागू किया है (जिसमें ढेर का आकार बदलना , USBD_CDC_TransmitPacket में ट्रांसमिशन फ़्लैग को ठीक करना , और CDC_DATA_HS_MAX_PACKET_SIZE का आकार 512 से 256 तक बदलना) एसटी मंच पर प्रलेखित के रूप में लेकिन अभी भी एक ही त्रुटि प्राप्त कर रहा है।

मेरा डिवाइस सेटअप कोड है

* 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);

}

जब से मैंने पिछली बार STM में USB के साथ काम किया था, तब से ही कुछ समय हो गया है, लेकिन मुझे लगता है कि USBD_CDC_Init () एक मॉलोक करने की कोशिश करता है। समस्या यह थी कि डिफ़ॉल्ट सेटअप में ढेर पर पर्याप्त जगह नहीं है और आपको इसे बढ़ाने की आवश्यकता है।
ब्राह्मण

नमस्ते, मैं 0x600 को ढेर आकार में वृद्धि हुई है और कुछ भी नहीं हो रहा है। कौन सा फ़ंक्शन मॉलोक कहता है क्योंकि जब मैं इस पर एक ब्रेकपॉइंट डालता हूं, तो ऐसा लगता है कि इसे कभी नहीं कहा जाता है।
गैलेक्सी

जवाबों:


6

मेरे अपने प्रश्न का उत्तर देने के लिए, समस्या यह है कि मेरा कोड USB के आरंभिक होने का इंतजार नहीं करता था और तुरंत डेटा भेजना शुरू कर देता था। एक बूलियन पर एक सक्रिय प्रतीक्षा करना या देरी जोड़ना (जैसा @ramez द्वारा बताया गया है) समस्या को हल करता है।

अद्यतन यह बग ST के बाद के USB CDC ड्राइवर संस्करणों में तय किया गया है। सेटअप में अब HAL_Delay है। कैविएट यह है कि यदि किसी कारण से Sys_Tick काम नहीं करता है / निष्क्रिय नहीं है / अभी तक आरंभिक नहीं है, तो आपका कोड लटका रहेगा।


1
हां, आपको इसे एक अलग प्रश्न के रूप में पोस्ट करना चाहिए। इस उत्तर में केवल मूल प्रश्न के लिए प्रासंगिक जानकारी रखें।
m.Alin

2

मैंने STM32F4 खोज के लिए कोड जनरेट करने के लिए CubeMX का उपयोग किया। मैंने इसे आप के रूप में वर्चुअल COM पोर्ट के रूप में इस्तेमाल किया। मैंने सीधे USBD_CDC_SetTxBuffer () फ़ंक्शन का उपयोग नहीं किया । में usbd_cdc_if.c फ़ाइल नाम के एक समारोह है CDC_Transmit_FS () । उत्पन्न कोड में एक बग था, फ़ंक्शन ने पैरामीटर के रूप में एक बफर लिया और इसके साथ कुछ भी नहीं किया। सही फ़ंक्शन कोड निम्नलिखित है:

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
  uint8_t result = USBD_OK;
  memcpy(UserTxBufferFS, Buf, sizeof(char) * Len);
  USBD_CDC_SetTxBuffer(hUsbDevice_0, UserTxBufferFS, Len);   
  result = USBD_CDC_TransmitPacket(hUsbDevice_0);
  return result;
}

दरअसल मुझे मेमकी को कोड में जोड़ना था। इस सुधार के बाद मैं इस संचारण फ़ंक्शन के साथ पीसी के लिए माइक्रोकॉट्रोलर से डेटा भेज सकता था। उदाहरण के लिए:

int main(void)
{
  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();
  MX_USB_DEVICE_Init();
  configureGPIOs();

  uint8_t Buf[] = "Test";

  HAL_Delay(1000);

  while (1)
  {
      CDC_Transmit_FS(Buf, 4);
      HAL_Delay(1000);
  }
}

MX_USB_DEVICE_Init () में इनबिल्टाइज़ेशन आपके जैसे ही है।


1
शुक्रिया ramez मुझे समस्या मिल गई है, मुझे यह परीक्षण करना था कि क्या वर्चुअल कॉम पोर्ट ने आरंभीकरण समाप्त कर लिया है, मैंने CDC_Init_FS में एक बूलियन का उपयोग किया था जो कि मुख्य लूप CDC_Transmit_FS को कॉल करने से पहले सही होने का इंतजार करता था। मुझे लगता है कि आपके कोड में HAL_DELAY समान प्रभाव प्राप्त करता है। सहायता के लिए धनयवाद।
गैलेक्सी

1

पहले, जांचें कि hUsbDevice_0 अशक्त है (आपके समाधान में अनुपलब्ध तत्व):

    if (hUsbDevice_0 == NULL)
            return USBD_FAIL;

यह आपके uC को लटकने से रोकेगा और देरी में व्यस्त होने की आवश्यकता नहीं है।

आप इसे CDC_Transmit_FS में कहीं रख सकते हैं:

USBD_StatusTypeDef CDC_Transmit_FS(uint8_t* Buf, uint16_t Len) {

    if (hUsbDevice_0 == NULL)
        return USBD_FAIL;

    USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) hUsbDevice_0->pClassData;

    if (hcdc->TxState != 0)
        return USBD_BUSY;

    uint8_t result = USBD_OK;

    USBD_CDC_SetTxBuffer(hUsbDevice_0, Buf, Len);
    result = USBD_CDC_TransmitPacket(hUsbDevice_0);

    return result;
}

0

मुझे भी यही समस्या थी, लेकिन यह केवल एक चीज थी जिसे मुझे करने की ज़रूरत है, कंप्यूटर से यूएसबी कनेक्शन को फिर से प्लग करें। ज्यादातर बार आप कोड को फ्लैश करते हैं और माइक्रोकंट्रोलर को रीसेट करते हैं लेकिन पीसी की तरफ एन्यूमरेशन अपडेट नहीं होता है। USBD_CDC_Init कहा जाता है जब होस्ट आपके डिवाइस की जांच करना शुरू करता है और इसीलिए pClassData NULL है।


1
आप सॉफ्टवेयर में भी पुन: गणना के लिए बाध्य कर सकते हैं। री-प्‍लगिंग के बाद दूसरा सबसे सुगम रास्‍ता डिवाइस प्रबंधक में आपके पोर्ट को अक्षम / सक्षम करने का है, यदि आपके पास एक कस्टम ड्राइवर नहीं है जो इसे अधिक फैंसी तरीके से संभाल रहा है
हैंडल कर रहा है
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.