STM32 USB - Verzögerte Übertragung bei Nutzlastlänge = 256 (oder 512 oder 768 ...) Bytes?

Ich implementiere USB-Kommunikation auf einem STM32F105 mit der USB-Bibliothek v2.1.0 von ST . Er kommuniziert als virtueller COM-Port ("VCP") der CDC-Klasse. Ich verwende die eingebettete Full-Speed-PHY.

Ich habe mit dem VCP-Beispielprojekt von ST begonnen, bei dem es sich um einen Seriell-zu-USB-Konverter handelt. Ich habe es gut funktioniert, bis auf ein Problem, von dem ich vermute, dass es sich um einen Fehler in ihrem Bibliothekscode handelt.

Ihr USB-Treiber legt einen Ringpuffer und einen Pufferzeiger offen. Die Anwendung soll Daten in diesen Puffer legen, die vom Treiber bemerkt und bearbeitet werden. Hier ist die Funktion zum Füllen des Puffers:

uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len)
{
    uint32_t i;
    for (i=0; i<Len; i++)
    {
        APP_Rx_Buffer[APP_Rx_ptr_in] = Buf[i];
        APP_Rx_ptr_in++;

        /* To avoid buffer overflow */
        if(APP_Rx_ptr_in == APP_RX_DATA_SIZE)
        {
            APP_Rx_ptr_in = 0;
        }
    }
    return USBD_OK;
 }

Dies funktioniert, um bis zu (mindestens) 1024 Bytes an Daten zu senden, außer wenn die Datenlänge ein gerades Vielfaches von 256 Bytes ist. Mit anderen Worten, ich kann diese Funktion verwenden, um problemlos 255 oder 257 Bytes (oder sogar 1023) zu senden, aber wenn ich versuche, 256 Bytes zu senden, schlägt dies fehl. Oder 512 oder 768 usw.

Der Fehlermodus besteht darin, dass keine Daten über USB gesendet werden, bis insgesamt 4096 Bytes in ihren Puffer geleitet wurden, und dann alles auf einmal übertragen wird. Wenn es richtig funktioniert, werden die Daten natürlich sofort übertragen.

Eine Liste bekannter Fehler finden Sie hier . Ich habe sie eingebaut, aber es hat dieses Problem nicht behoben.

Weiß jemand eine Lösung? Ich würde es vorziehen, den Treibercode von ST nicht zu debuggen ...

Ich sehe, dass der ursprüngliche Link zu der Liste bekannter Fehler starb, als ST ihre Forensoftware änderte. (Es ist erstaunlich, sich vorzustellen, wie viele Links im ganzen Internet unterbrochen worden sein müssen, als sie das taten! :-( ). Wenn Sie sich jedoch erinnern können, wie diese Liste aussah, glaube ich, dass ich den entsprechenden Link auf ihrem neuen gefunden habe Forum: community.st.com/message/59785 Wenn das die gleichen Informationen sind, dann überlasse ich es Ihnen, sie Ihrer Frage hinzuzufügen, wie auch immer Sie das tun möchten :-)
Ausgezeichnet, @SamGibson! Das ist in der Tat das, wovon ich gesprochen habe. Ich konnte es nicht wieder finden, nachdem ST die Dinge geändert hatte. Ich habe die Frage aktualisiert. Vielen Dank :)

Antworten (1)

außer wenn die Datenlänge ein gerades Vielfaches von 256 Byte ist

Es sind tatsächlich 64 Bytes (MaxPacketSize). USB-Massenübertragungen "enden" mit Übertragungen, die nicht MaxPacketSize sind - normalerweise 64 Byte lang. Wenn Ihre Übertragung ein ganzzahliges Vielfaches davon ist, senden Sie nach den Daten ein Nullpaket . Dies signalisiert das Ende der Übertragung an die oberen USB-Software-Stacks, die Ihre Daten sofort zurücksenden.

Der meiste VCP-Beispielcode lässt dies der Einfachheit halber weg.

Ah, ausgezeichnet, danke! Das ist genau das, wonach ich gesucht habe.
Eine kurze Folgefrage, wenn es Ihnen nichts ausmacht: Ist die Erstellung von Nullpaketen im Allgemeinen in der Anwendungsschicht oder in der CDC-Klassenschicht implementiert?
@bitsmack Ich würde die CDC-Schicht vorschlagen, Ihre Anwendung sollte transportunabhängig sein, daher ist es ein schlechter Geruch, Details der unteren Schichten zu kennen.
@Colin__s Danke für deinen Vorschlag! So habe ich es schließlich gemacht, aus ähnlichen Gründen. Natürlich muss ich, wenn ich auf eine neuere USB-Bibliothek aktualisiere, den Fix neu bewerten (und möglicherweise erneut anwenden) ...