我现在使用c6748中使用emac的开发,软件配置128M的ddr,l1p l1d l2p都用做cache,现在emac中的 接收中断和发送中断怎么使用cachewb ();cacheinv();
来保证数据正常传输!
当不使用cache时,以太网是可以正常收发的!但是一使用cache收发数据就不正常!
在emac中断中怎样使用cache,这些有没有例程可以参考,谢谢!
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.
Zhang 先生:
根据你的要求我把资料熟悉了下,现在更改如下:
在main() 函数里加入以下使能cache
{
//关闭 emaci 的cppi 8k ram cache
CacheDisableMAR((unsigned int)0x01E20000, (unsigned int)0x00002000); //EMACram //8k
// 使能缓存 L1 及 L2
CacheEnableMAR((unsigned int)0xC0000000, (unsigned int)0x08000000); //ddr2 //128M
CacheEnableMAR((unsigned int)0x80000000, (unsigned int)0x00020000); //sharm //128k
CacheEnable(L1DCFG_L1DMODE_32K | L1PCFG_L1PMODE_32K | L2CFG_L2MODE_256K);
}
在sitaraif.c中
在
static void
sitaraif_transmit(struct sitaraif *sitaraif, struct pbuf *pbuf) {
struct pbuf *q;
struct txch *txch;
volatile struct cpdma_tx_bd *curr_bd, *active_head, *bd_end;
txch = &(sitaraif->txch);
/* Get the buffer descriptor which is free to transmit */
curr_bd = txch->free_head;
active_head = curr_bd;
/* Update the total packet length */
curr_bd->flags_pktlen &= ~0xFFFF;
curr_bd->flags_pktlen |= pbuf->tot_len;
/* Indicate the start of the packet */
curr_bd->flags_pktlen |= (CPDMA_BUF_DESC_SOP | CPDMA_BUF_DESC_OWNER);
/* Copy pbuf information into TX buffer descriptors */
for(q = pbuf; q != NULL; q = q->next) {
/* Intialize the buffer pointer and length */
curr_bd->bufptr = (u32_t)(q->payload);
curr_bd->bufoff_len = (q->len) & 0xFFFF;
bd_end = curr_bd;
curr_bd->pbuf = pbuf;
//新增加 cacheWB 回写
CacheWB ((unsigned int) curr_bd->bufptr, curr_bd->bufoff_len);
//
curr_bd = curr_bd->next;
}
/* Indicate the end of the packet */
bd_end->next = NULL;
bd_end->flags_pktlen |= CPDMA_BUF_DESC_EOP;
txch->free_head = curr_bd;
/* For the first time, write the HDP with the filled bd */
if(txch->active_tail == NULL) {
CPSWCPDMATxHdrDescPtrWrite(sitaraif->cpsw_cpdma_base,
(unsigned int)(active_head), 0);
}
/*
* Chain the bd's. If the DMA engine, already reached the end of the chain,
* the EOQ will be set. In that case, the HDP shall be written again.
*/
else {
curr_bd = txch->active_tail;
curr_bd->next = active_head;
if(curr_bd->flags_pktlen & CPDMA_BUF_DESC_EOQ) {
/* Write the Header Descriptor Pointer and start DMA */
CPSWCPDMATxHdrDescPtrWrite(sitaraif->cpsw_cpdma_base,
(unsigned int)(active_head), 0);
}
}
txch->active_tail = bd_end;
}
在
void
sitaraif_rx_inthandler(struct netif *netif) {
struct sitaraif *sitaraif;
struct rxch *rxch;
volatile struct cpdma_rx_bd *curr_bd, *processed_bd, *curr_tail, *last_bd;
volatile struct pbuf *pbuf, *q, *new_pbuf;
u32_t ex_len = 0, len_to_alloc = 0;
u16_t tot_len;
sitaraif = netif->state;
rxch = &(sitaraif->rxch);
/* Get the bd which contains the earliest filled data */
curr_bd = rxch->active_head;
last_bd = rxch->active_tail;
/**
* Process the descriptors as long as data is available
* when the DMA is receiving data, SOP flag will be set
*/
while(curr_bd->flags_pktlen & CPDMA_BUF_DESC_SOP) {
ex_len = 0;
len_to_alloc = 0;
/* Start processing once the packet is loaded */
if((curr_bd->flags_pktlen & CPDMA_BUF_DESC_OWNER)
!= CPDMA_BUF_DESC_OWNER) {
if(rxch->free_head == NULL) {
/* this bd chain will be freed after processing */
rxch->free_head = curr_bd;
}
/* Get the total length of the packet. curr_bd points to the start
* of the packet.
*/
tot_len = (curr_bd->flags_pktlen) & 0xFFFF;
/* Get the start of the pbuf queue */
q = curr_bd->pbuf;
do {
/* Get the pbuf pointer which is associated with the current bd */
pbuf = curr_bd->pbuf;
/* If the earlier pbuf ended, update the chain */
if(pbuf->next == NULL) {
pbuf->next = (struct pbuf*)(curr_bd->next)->pbuf;
}
len_to_alloc += pbuf->len;
/* Update the len and tot_len fields for the pbuf in the chain*/
pbuf->len = (curr_bd->bufoff_len) & 0xFFFF;
pbuf->tot_len = tot_len - ex_len ;
//新增
CacheInv ((unsigned int) pbuf->payload, pbuf->len);
//
processed_bd = curr_bd;
ex_len += pbuf->len;
curr_bd = curr_bd->next;
} while((processed_bd->flags_pktlen & CPDMA_BUF_DESC_EOP)
!= CPDMA_BUF_DESC_EOP);
/**
* Close the chain for this pbuf. A full packet is received in
* this pbuf chain. Now this pbuf can be given to upper layers for
* processing. The start of the pbuf chain is now 'q'.
*/
pbuf->next = NULL;
/* Adjust the link statistics */
LINK_STATS_INC(link.recv);
/* Process the packet */
if(ethernet_input((struct pbuf *)q, netif) != ERR_OK) {
/* Adjust the link statistics */
LINK_STATS_INC(link.memerr);
LINK_STATS_INC(link.drop);
}
/* Acknowledge that this packet is processed */
CPSWCPDMARxCPWrite(sitaraif->cpsw_cpdma_base, 0, (unsigned int)processed_bd);
rxch->active_head = curr_bd;
/**
* The earlier pbuf chain is freed from the upper layer. So, we need to
* allocate a new pbuf chain and update the descriptors with the pbuf info.
* To support chaining, the total length freed by the upper layer is tracked.
* Care should be taken even if the allocation fails.
*/
/**
* now len_to_alloc will contain the length of the pbuf which was freed
* from the upper layer
*/
rxch->freed_pbuf_len += len_to_alloc;
new_pbuf = pbuf_alloc(PBUF_RAW, (rxch->freed_pbuf_len), PBUF_POOL);
/* Write the descriptors with the pbuf info till either of them expires */
if(new_pbuf != NULL) {
curr_bd = rxch->free_head;
for(q = new_pbuf; (q != NULL) && (curr_bd != rxch->active_head); q = q->next) {
curr_bd->bufptr = (u32_t)(q->payload);
/* no support for buf_offset. RXBUFFEROFFEST register is 0 */
curr_bd->bufoff_len = (q->len) & 0xFFFF;
curr_bd->flags_pktlen = CPDMA_BUF_DESC_OWNER;
rxch->freed_pbuf_len -= q->len;
/* Save the pbuf */
curr_bd->pbuf = q;
last_bd = curr_bd;
curr_bd = curr_bd->next;
}
/**
* At this point either pbuf expired or no rxbd to allocate. If
* there are no, enough rx bds to allocate all pbufs in the chain,
* free the rest of the pbuf
*/
if(q != NULL) {
pbuf_free((struct pbuf *)q);
}
curr_tail = rxch->active_tail;
last_bd->next = NULL;
curr_tail->next = rxch->free_head;
/**
* Check if the reception has ended. If the EOQ flag is set, the NULL
* Pointer is taken by the DMA engine. So we need to write the RX HDP
* with the next descriptor.
*/
if(curr_tail->flags_pktlen & CPDMA_BUF_DESC_EOQ) {
CPSWCPDMARxHdrDescPtrWrite(sitaraif->cpsw_cpdma_base,
(u32_t)(rxch->free_head), 0);
}
rxch->free_head = curr_bd;
rxch->active_tail = last_bd;
}
}
curr_bd = rxch->active_head;
CPSWCPDMANumFreeBufSet(sitaraif->cpsw_cpdma_base, 0, 1);
}
CPSWCPDMAEndOfIntVectorWrite(sitaraif->cpsw_cpdma_base, CPSW_EOI_TX_PULSE);
CPSWCPDMAEndOfIntVectorWrite(sitaraif->cpsw_cpdma_base, CPSW_EOI_RX_PULSE);
}