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

Strange _alloc_box behavior in RTL CAN code -- help!

We've been working on a project that uses RTX and the RTL CAN drivers for a while. Recently we made some changes to the code, and since then we've been seeing a Data Abort occur in the CAN_ISR interrupt handler. What is odd is that none of the CAN-related code was touched during these changes.

The CAN drivers allocate a memory pool, CAN_mpool, which is initialized as part of CAN_init(). This appears to work with no problems. We begin to receive CAN packets, and I can watch the ISR return a pointer from _alloc_box() each time.

Now here's the strange part: if CAN_mpool fills up, instead of returning NULL as it should, _alloc_box() is returning 0x000003FF. The next call CAN_ISR() makes is CAN_hw_rd(1, ptrmsg), and the first attempt to write to the pointer location understandably causes a Data Abort. (I should note that a NULL would normally cause a Data Abort anyway, since CAN_ISR() never checks to make sure the _alloc_box() call succeeds.)

I don't understand how this could be happening, and am wondering if anybody out there has any suggestions. Below is the portion of CAN_ISR we have modified to catch the unexplained 0x3FF (as well as fix a few other problems that caused the system to lock up in the case of a buffer overflow). Note that this code was working just fine until recently, but a code diff between a working version and a crashing version does not show any changes that should affect CAN communications in any way.

  /* If message is received and if mailbox isn't full read message from
     hardware and send it to message queue                                   */
#if USE_CAN_CTRL1 == 1
  if (CAN1GSR & 0x01) {
    if (isr_mbx_check (MBX_rx_ctrl[0]) > 0) {
      ptrmsg = _alloc_box (CAN_mpool);
      if (ptrmsg != NULL)
      {
        /* GSL DEBUG: Check to see if msg is truly within the memory pool limits. */
        if (((U32*)ptrmsg < CAN_mpool) || ((U32*)ptrmsg > (CAN_mpool + CAN_CTRL_MAX_NUM*(CAN_No_SendObjects+CAN_No_ReceiveObjects)*(sizeof(CAN_msg)/4) + 3)))
        {
          /* Breakpoint to catch odd 0x3FF return value goes here! */
          __asm("nop");
        }

        CAN_hw_rd (1, ptrmsg);
        CAN1CMR = 0x04;                   /* Release receive buffer            */
        isr_mbx_send (MBX_rx_ctrl[0], ptrmsg);
      }
      else
      {
        /* The CAN message pool is full.  Release the receive buffer. */
        CAN1CMR = 0x04;
      }
    }
    else {
      /* The required mailbox is full.  Release the receive buffer, because if
         we do not this interrupt will just fire indefinitely and no tasks will
         ever execute! */
      CAN1CMR = 0x04;
    }
  }
#endif

0