Recently the JDP team investigated a group of KITL timeout failures. Each timeout occurred under similar conditions and seemed to be associated with a single bug.
At first we were puzzled as to why we were seeing these failures on different devices with different OS versions. As the investigation progressed it became clear that the bug was located in a section of BSP code that handles KITL packets sent over the USB Serial transport.
To indicate a transmission is complete the USB client sends a partial packet (i.e. a packet smaller then the max packet size) to USB host. This means that if the data being sent is equal to the exact size of the USB max packet size, the USB client must send a zero length packet at the end of the transmission. On the BSPs we were using, this zero length packet was never sent, so in some cases KITL would think it was hung waiting for a transmission to complete; in other cases, the debug message flow would simply stop for a split second and then continue.
To test for this bug you can write a very simple application that will send 64 byte packets to the debug output. Keep in mind the standard KITL header is 34 bytes (do not worry about these details if they do not make sense right now, I will explain KITL header and transmissions in more detail in a follow-up blog). Also, do not forget that debug messages are sent in ASCII therefore each character will take 1 byte.
The following code will detect the KITL packet bug if the bug is present, a hang or a pause will be shown in the debug messages when this code is executed:
for(int a = 0; a < 100; a++)
memset(strng, 'k', a);
strng[a] = '\0';
//!!If the bug exists, the second printf should cause a hickup or hang!!
printf("%s\n", strng); //Remember '\n' is compiled into two characters (CR and LF).
This bug has a simple fix. Find the KITLSend function in your KITL implementation, (it's called USBKitlTxIntHandler in some BSPs), then find the spot right before a packet is sent to USB and insert these 3 lines:
// here we split the last trunk of data into 2 short packets(EP1Len - 4) and 4 bytes
if (len == EP1Len)
// if the requested send size happens to be multiple of EP1Len,
// we should send a zero length packet to indicate end of data,
//, so we never need to send a zero length packet
lastPacketLen -= 4;