STM32 USB VCP bug

8

Saya telah mengerjakan sebuah proyek selama dua minggu terakhir sekarang dan men-debug masalah yang satu ini telah menghabiskan seluruh minggu ini. Ingin tahu apakah ada yang bisa membantu, saya akan mencoba untuk menjadi sejelas dan sejelas mungkin.

Saya mencoba untuk mengimplementasikan Port USB Virtual Comm pada MicroController berdasarkan STM32F302K8 (Cortex M4). Saya telah menggunakan STM32CubMX untuk menghasilkan kode yang diperlukan untuk mengatur Perangkat Kecepatan Penuh USB yang mengimplementasikan kelas CDC. Perangkat saya muncul di Windows (Device Manager) dan Linux. Saya dapat menerapkan fungsi gema sederhana berdasarkan kode contoh tetapi ketika sekarang saya mencoba menggunakan fungsi USBD_CDC_SetTxBuffer untuk mengirim data ke PC, ini memicu Hard Fault Handler. Saya mempersempit ini menjadi kenyataan bahwa bidang UsbDeviceFS.pClass (yang diperlukan oleh USBD_CDC_SetTxBuffer) tidak pernah diinisialisasi karena USBD_CDC_Init () tidak pernah dipanggil dalam inisialisasi Perangkat USB.

Saya telah menerapkan perbaikan ke beberapa bug (termasuk mengubah ukuran tumpukan, memperbaiki bendera transmisi di USBD_CDC_TransmitPacket , dan mengubah ukuran CDC_DATA_HS_MAX_PACKET_SIZE menjadi 256 dari 512) dalam kode contoh seperti yang didokumentasikan pada forum ST tetapi masih mendapatkan kesalahan yang sama.

Kode pengaturan perangkat saya adalah

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

}
Galaksi
sumber
Sudah lama sejak saya terakhir bekerja dengan USB pada STM, tapi saya pikir USBD_CDC_Init () mencoba melakukan malloc. Masalahnya adalah bahwa tidak ada ruang yang cukup di tumpukan di pengaturan default dan Anda perlu meningkatkannya.
brhans
Hai, saya telah meningkatkan ukuran tumpukan menjadi 0x600 dan tidak ada yang terjadi. Fungsi yang memanggil malloc karena ketika saya meletakkan breakpoint di atasnya, sepertinya tidak pernah dipanggil.
Galaxy

Jawaban:

6

Untuk menjawab pertanyaan saya sendiri, masalahnya adalah bahwa kode saya tidak menunggu USB untuk menyelesaikan inisialisasi dan segera mulai mengirim data. Memasukkan tunggu aktif di boolean atau menambahkan penundaan (seperti yang ditunjukkan oleh @ramez) memecahkan masalah.

PEMBARUAN Bug ini telah diperbaiki pada versi driver CDC USB berikutnya dari ST. Sekarang ada HAL_Delay dalam penyiapan. Peringatan adalah bahwa jika karena alasan apa pun Sys_Tick tidak berfungsi / dinonaktifkan / belum diinisialisasi, kode Anda akan hang.

Galaksi
sumber
1
Ya, Anda harus memposting ini sebagai pertanyaan terpisah. Simpan dalam jawaban ini hanya informasi yang relevan untuk pertanyaan awal.
m.Alin
2

Saya menggunakan CubeMX untuk menghasilkan kode untuk penemuan STM32F4. Saya menggunakannya sebagai port COM virtual seperti Anda. Saya tidak menggunakan fungsi USBD_CDC_SetTxBuffer () secara langsung. Dalam file usbd_cdc_if.c ada fungsi bernama CDC_Transmit_FS () . Ada bug dalam kode yang dihasilkan, fungsi mengambil buffer sebagai parameter dan tidak melakukan apa-apa dengannya. Kode fungsi yang dikoreksi adalah sebagai berikut:

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;
}

Sebenarnya saya harus menambahkan memcpy ke kode. Setelah koreksi ini saya bisa mengirim data dari mikrokotroller ke PC dengan fungsi pengiriman ini. Sebagai contoh:

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

Inisialisasi dalam MX_USB_DEVICE_Init () sama dengan saya.

tenkmilan
sumber
1
Terima kasih ramez. Saya telah menemukan masalah, saya harus menguji apakah port comm virtual telah selesai inisialisasi, saya menggunakan boolean di CDC_Init_FS yang loop utama menunggu benar sebelum memanggil CDC_Transmit_FS. Saya pikir HAL_DELAY dalam kode Anda mencapai efek yang sama. Terima kasih atas bantuannya.
Galaxy
1

Pertama, periksa apakah hUsbDevice_0 adalah null (elemen yang hilang dalam solusi Anda):

    if (hUsbDevice_0 == NULL)
            return USBD_FAIL;

Ini akan mencegah menggantung UC Anda dan tidak perlu sibuk menunggu dalam penundaan.

Anda dapat menempatkannya di suatu tempat di 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;
}
jemdream
sumber
0

Saya memiliki masalah yang sama tetapi ternyata satu-satunya hal yang perlu saya lakukan adalah menancapkan kembali koneksi USB ke komputer. Sebagian besar waktu Anda mem-flash kode dan mengatur ulang mikrokontroler tetapi pada sisi PC enumerasi tidak diperbarui. USBD_CDC_Init dipanggil ketika tuan rumah mulai menyelidiki perangkat Anda dan itulah sebabnya pClassData adalah NULL.

Yuanyi Wu
sumber
1
Anda dapat memaksa pencacahan ulang dalam perangkat lunak juga. Cara paling bodoh kedua setelah memasukkan kembali adalah menonaktifkan / mengaktifkan port Anda di manajer perangkat, jika Anda tidak memiliki driver khusus yang menangani ini dengan cara yang lebih mewah
stiebrs