This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM3359脱离LWIP直接使用CPDMA发送单个包的问题

Other Parts Discussed in Thread: SYSBIOS

大家好,

因为想实现EtherCAT MASTER,因此在beaglebone上需要脱离LWIP发送以太网包,项目中有用到SYSBIOS的,在使用中碰到了点问题,做程序时,CPSW和CPDMA初始化部分是参照LWIP那个例子程序写的。要实现的功能时,通过一个独立的函数,每次被调用的时候,仅发送一个以太网包,即完成。下一次调用时,在发送一个。以此类推。因此我设计时考虑在buffer discripter里面就放一个对象,同时设定SOP和EOP,每次变得只是buffer指针指向对象里面的数据,其他都不用变,只要重新触发一下发送就可以了,但实际使用中碰到了一下的问题:

1.发送的时候,仅能在debug的时候才能发送成功,即只有我通过F6单步走过CPSWCPDMATxHdrDescPtrWrite这个函数,才能成功。而直接进入auto执行,却发不出包,这个原因一直没找到,很奇怪。但我如果在执行这个函数前,加一个延时函数,延时时间几百微妙的话,auto执行也能成功。所以是不是我某些参数设定还是不正确造成。

2.即使通过debug的方式,成功发送一个包以后,第二次调用函数,用同样的方法却无法再次发送数据了。我监控了下,在第一次发送的时候,CPDMA只会把相应bd的ownership清零,而不会设置EOQ。照理来说我看manual里面,我bd里面只有一个对象,且同时设定了SOP和EOP,发送完毕后应该会被设定EOQ的。不知道是不是第一次发送的时候,CPDMA认为还没发完呢?

因此请教大家,

1.我想每次只发送一个packet的话,到底应该怎么设定我的buffer discripter?

2.发送单个fragment packet的话,这个过程到底应该是怎么样的呢?

先行谢谢大家!!

我的发送函数的代码大致如下:

//Send Single package to Network

int AM335x_EMAC_send (void *packet, int length)

 {

 volatile struct cpdma_tx_bd *bd_to_send;

  struct txch *txch;

  volatile uint32 cnt = 0xFFFF;

 

 cpswinst *pCpswinst = &cpsw_inst_data[0];

 txch = &(pCpswinst->txch);

 bd_to_send = txch->free_head;

 bd_to_send->flags_pktlen = length;

 /* Indicate the start of the packet */

 

  bd_to_send->flags_pktlen |= (CPDMA_BUF_DESC_SOP | CPDMA_BUF_DESC_OWNER | CPDMA_BUF_DESC_EOP);

 

 /* Intialize the buffer pointer and length */

  bd_to_send->bufptr = (unsigned int)packet;

  bd_to_send->bufoff_len = (length) & CPDMA_BD_LEN_MASK;

 

 CPSWCPDMATxHdrDescPtrWrite(pCpswinst->cpdma_base,   (unsigned int)(bd_to_send), 0);

 

/*Make sure that the transmission is over */

  while(((bd_to_send->flags_pktlen & CPDMA_BUF_DESC_OWNER)            == CPDMA_BUF_DESC_OWNER) && ((--cnt) != 0));

     /* If CPDMA failed to transmit, give it a chance once more *、

      if(0 == cnt) {

        CPSWCPDMATxHdrDescPtrWrite(pCpswinst->cpdma_base, (uint32)(bd_to_send), 0);

        return;

     }

     bd_to_send->flags_pktlen &= ~(CPDMA_BUF_DESC_SOP);

      bd_to_send->flags_pktlen &= ~(CPDMA_BUF_DESC_EOP);

 

     /* Acknowledge CPSW and free the corresponding pbuf */

      CPSWCPDMATxCPWrite(pCpswinst->cpdma_base, 0, (uint32)bd_to_send);

 

     CPSWCPDMAEndOfIntVectorWrite(pCpswinst->cpdma_base, CPSW_EOI_TX_PULSE);

 

   return ERR_OK;

}