我现在使用c6748中使用emac的开发,软件配置128M的ddr,l1p l1d l2p都用做cache,现在emac中的 接收中断和发送中断怎么使用cachewb ();cacheinv();
来保证数据正常传输!
当不使用cache时,以太网是可以正常收发的!但是一使用cache收发数据就不正常!
在emac中断中怎样使用cache,这些有没有例程可以参考,谢谢!
Shine:
可以参考starterware里的cache例程C:\ti\C6748_StarterWare_1_20_04_01\examples\lcdkC6748\cache_mmu。http://processors.wiki.ti.com/index.php/StarterWare_01.20.01.01_User_Guide#Cache_Management
likui han:
回复 Shine:
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 voidsitaraif_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;}
在
voidsitaraif_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); }
likui han:
回复 likui han:
以上更改,网络通信压根就不通
likui han:
回复 likui han:
关于怎么lwip怎么使用cache,有例程吗