This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Mailbox send & receive sync

Hi,

I have a code for USB mass storage device on atmel AT91SAM7SE512 target. The code is based on Keil\ARM\Boards\Atmel\AT91SAM7X-EK\RL\USB\RTX_Memory .

When connecting my device to a PC and saving a file - I see that at some point, messages are sent to endpoint task from ISR (isr_mbx_send...) but not received by the endpoint task (os_mbx_wait...).
Some save sessions are passed successfully, but most sessions behave as described above...

Any idea what may be the problem...?

Thanks

  • Since isr_mbx_send does not return any value, you might not know, if the message has been send.

    http://www.keil.com/support/man/docs/rlarm/rlarm_isr_mbx_send.htm

    If the mailbox is full, the kernel ignores the message since it cannot be put into the mailbox. Thus before sending a message using isr_mbx_send, you must use the os_mbx_check function to check if the mailbox is full.
    [There is failure in the manual, it should be isr_mbx_check.]

    Do you check the mailbox with isr_mbx_check?

  • Currently I check the mailbox with os_mbx_check (as done in the mentioned reference code) and according to the return value - mailbox is available...
    When should I use os_mbx_check and when isr_mbx_check..?

    Thanks

  • In an ISR, you should use isr_mbx_send() and obviously then also isr_mbx_check().

  • I'm using now isr_mbx_check but there is no change in the behavior.

  • Can you post the code of the ISR and the receiving function?

  • The ISR code:

    /* Endpoint Interrupts */
    for (n = 0; n < USB_EP_NUM; n++) {
      if (isr & (1 << n)) {
    
        csr = pUDP->UDP_CSR[n];
    
        /* Setup Packet Received Interrupt */
        if (csr & AT91C_UDP_RXSETUP) {
          pEpEvent = _alloc_box (USB_MsgPool);                  /* allocate memory */
          if (pEpEvent){
                    pEpEvent->bCnt = USB_ReadEP(n, pEpEvent->bData);  /* read the setup packet */
            pEpEvent->wEvent = USB_EVT_SETUP;                        /* set event */
                    if (isr_mbx_check (USB_EPMbx[n]) == 0)
                            _free_box (USB_MsgPool, pEpEvent);
                    else
            isr_mbx_send (USB_EPMbx[n], pEpEvent);
              }
    
              Udp_ep_clr_flag(pUDP,n,AT91C_UDP_RXSETUP);
        }
    
        /* Data Packet Received Interrupt */
        bkm = RX_DATA_BK[RxDataBank[n]];
        if (csr & bkm) {
          pEpEvent = _alloc_box (USB_MsgPool);                   /* allocate memory */
              if (pEpEvent){
            pEpEvent->bCnt = USB_ReadEP(n, pEpEvent->bData);   /* read the data packet */
            pEpEvent->wEvent = USB_EVT_OUT;                           /* set event */
                    // Save isr_mbx_check result for debug
                    mbxCheck = isr_mbx_check (USB_EPMbx[n]);
                    if (mbxCheck == 0){
                            _free_box (USB_MsgPool, pEpEvent);
                            mbxErr++; // Debug
                    }
                    else {
                    isr_mbx_send (USB_EPMbx[n], pEpEvent);
                            // Debug- count the bulk out (EP 2) data messages
                            if ((pEpEvent->bCnt == 64) && (n==2))
                                            EP_2_Count_Sent++;
                    }
              }
    
          Udp_ep_clr_flag(pUDP,n ,bkm);
          if (DualBankEP & (1 << n)) {
            RxDataBank[n] ^= 1;
          }
        }
    
        /* Data Packet Sent Interrupt */
        if (csr & AT91C_UDP_TXCOMP) {
          Udp_ep_clr_flag(pUDP,n ,AT91C_UDP_TXCOMP);
          if (TxDataBank[n]) {
            //pUDP->UDP_CSR[n] |= AT91C_UDP_TXPKTRDY;
                    Udp_ep_set_flag(pUDP,n,AT91C_UDP_TXPKTRDY);
            TxDataBank[n] = 0;
          }
    
          pEpEvent = _alloc_box (USB_MsgPool);
              if (pEpEvent){
            pEpEvent->wEvent = USB_EVT_IN;
                    if (isr_mbx_check (USB_EPMbx[n]) == 0)
                            _free_box (USB_MsgPool, pEpEvent);
                    else
            isr_mbx_send (USB_EPMbx[n], pEpEvent);
              }
    
        }
    
        /* STALL Packet Sent Interrupt */
        if (csr & AT91C_UDP_STALLSENT) {
          if ((csr & AT91C_UDP_EPTYPE) == AT91C_UDP_EPTYPE_CTRL) {
            pEpEvent = _alloc_box (USB_MsgPool);
                    if (pEpEvent){
                    pEpEvent->wEvent = USB_EVT_IN_STALL;
                    if (isr_mbx_check (USB_EPMbx[n]) == 0)
                            _free_box (USB_MsgPool, pEpEvent);
                    else
                    isr_mbx_send (USB_EPMbx[n], pEpEvent);
    
                    }
          }
          Udp_ep_clr_flag(pUDP,n ,AT91C_UDP_STALLSENT);
        }
    
      }
    }
    

    The receiver task code:

    void USB_EndPoint2 (void) __task {
      T_USB_EP_EVENT *pEpEvent;
    
    
    USB_EPMbx[2] = USB_EP2Mbx; /* store Mbx in array */ os_mbx_init (USB_EP2Mbx, sizeof(USB_EP2Mbx)); /* initialize the mailbox */
    for (;;) { os_mbx_wait (USB_EP2Mbx, (void **)&pEpEvent, 0xFFFF); /* Wait for an Event */ memcpy (BulkBuf, pEpEvent->bData, pEpEvent->bCnt); /* store received data from mailbox */ BulkLen = pEpEvent->bCnt;
    // Debug - update counters if ((BulkBuf[15] == 0x2A) && (BulkLen == 31)) { printf("\n --> BulkOut zero counter %d (writeCount = %d) ", bufOutCount, writeCount); bufOutCount = 0; writeCount = 0; } else if (BulkLen == 64) bufOutCount++;
    MSC_BulkOut();
    _free_box (USB_MsgPool, pEpEvent); /* free memory allocated for message */
    } }

    In the error case - I eventually receive Bus reset from host and then I print the session counters:
    CBW.dDataLength = 29184, - Length of data that was sent (/64 = 456)
    EP_2_Count_Sent = 420, - Number of bulks sent by ISR
    bufOutCount = 388, - Number of bulks received by receiver task
    writeCount = 388, - Number of bulks handled by SW
    mbxErr = 0 , - No mailbox request errors
    mbxCheck = 28 - Number of available mailbox entries

    (Each Bulk is 64 bytes)

  • May it be possible, that

    pEpEvent = _alloc_box (USB_MsgPool);
    


    fails and therefore the message is not even created.
    There is no error checking for this case, as far as I see.

  • The next line checks that aloccation was successfull (
    if (pEpEvent){...).
    If allocation failes - the mailbox send code is not activated...
    See that my counter is promoted only after successfull allocations and when mailbox is available